1
1
import itertools
2
2
import pathlib
3
+ import re
3
4
4
5
from truncatehtml import truncate
5
6
@@ -9,13 +10,22 @@ def _generate_sorted_tag_keys(all_items):
9
10
return sorted (key_set )
10
11
11
12
13
+ def _title_case_preserve (s ):
14
+ return re .sub (r'\b(\w)' , lambda m : m .group (1 ).upper (), s )
15
+
16
+
17
+ def _make_class (s ):
18
+ return re .sub (r'^\d+' , '' , s .replace (' ' , '-' ).lower ())
19
+
20
+
12
21
def _generate_tag_set (all_items , tag_key = None ):
13
22
tag_set = set ()
14
23
for item in all_items :
15
24
for k , e in item ['tags' ].items ():
25
+ tags = [_title_case_preserve (t ) for t in e ]
16
26
if tag_key and k != tag_key :
17
27
continue
18
- for t in e :
28
+ for t in tags :
19
29
tag_set .add (t )
20
30
21
31
return tag_set
@@ -26,20 +36,18 @@ def _generate_tag_menu(all_items, tag_key):
26
36
tag_list = sorted (tag_set )
27
37
28
38
options = '' .join (
29
- f'<li><label class="dropdown-item checkbox { tag_key } "><input type="checkbox" rel={ tag . replace ( " " , "-" )} onchange="change();"> { tag . capitalize () } </label></li>'
39
+ f'<li><label class="dropdown-item checkbox { tag_key } "><input type="checkbox" rel={ _make_class ( tag )} onchange="change();"> { tag } </label></li>'
30
40
for tag in tag_list
31
41
)
32
42
33
43
return f"""
34
- <div class="dropdown">
35
-
36
- <button class="btn btn-sm btn-outline-primary mx-1 dropdown-toggle" type="button" id="{ tag_key } Dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
37
- { tag_key .title ()}
38
- </button>
39
- <ul class="dropdown-menu" aria-labelledby="{ tag_key } Dropdown">
40
- { options }
41
- </ul>
42
- </div>
44
+ :::{{dropdown}} { tag_key }
45
+ <div class="dropdown">
46
+ <ul>
47
+ { options }
48
+ </ul>
49
+ </div>
50
+ :::
43
51
"""
44
52
45
53
@@ -71,10 +79,9 @@ def build_from_items(items, filename, title='Gallery', subtitle=None, subtext=No
71
79
tag_list = sorted ((itertools .chain (* item ['tags' ].values ())))
72
80
tag_list_f = [tag .replace (' ' , '-' ) for tag in tag_list ]
73
81
74
- tags = [f'<span class="badge bg-primary">{ tag } </span>' for tag in tag_list_f ]
82
+ tags = [f'<span class="badge bg-primary mybadges ">{ _title_case_preserve ( tag ) } </span>' for tag in tag_list_f ]
75
83
tags = '\n ' .join (tags )
76
-
77
- # tag_class_str = ' '.join(tag_list_f)
84
+ tag_classes = ' ' .join (tag_list_f )
78
85
79
86
author_strs = set ()
80
87
affiliation_strs = set ()
@@ -108,51 +115,52 @@ def build_from_items(items, filename, title='Gallery', subtitle=None, subtext=No
108
115
if ellipsis_str in short_description :
109
116
modal_str = f"""
110
117
<div class="modal">
111
- <div class="content">
112
- <img src="{ thumbnail } " class="modal-img" />
113
- <h3 class="display-3">{ item ["title" ]} </h3>
114
- { authors_str }
115
- <br/>
116
- { affiliations_str }
117
- <p class="my-2">{ item ['description' ]} </p>
118
- <p class="my-2">{ tags } </p>
119
- <p class="mt-3 mb-0"><a href="{ item ["url" ]} " class="btn btn-outline-primary btn-block">Visit Website</a></p>
120
- </div>
118
+ <div class="content">
119
+ <img src="{ thumbnail } " class="modal-img" />
120
+ <h3 class="display-3">{ item ["title" ]} </h3>
121
+ { authors_str }
122
+ <br/>
123
+ { affiliations_str }
124
+ <p class="my-2">{ item ['description' ]} </p>
125
+ <p class="my-2">{ tags } </p>
126
+ <p class="mt-3 mb-0"><a href="{ item ["url" ]} " class="btn btn-outline-primary btn-block">Visit Website</a></p>
127
+ </div>
121
128
</div>
122
129
"""
123
130
modal_str = '\n ' .join ([m .lstrip () for m in modal_str .split ('\n ' )])
124
131
else :
125
132
modal_str = ''
126
133
127
- new_card = f"""\
128
- :::{{grid-item-card}}
129
- :shadow: md
130
- :class-footer: card-footer
131
- <div class="d-flex gallery-card">
132
- <img src="{ thumbnail } " class="gallery-thumbnail" />
133
- <div class="container">
134
- <a href="{ item ["url" ]} " class="text-decoration-none"><h4 class="display-4 p-0">{ item ["title" ]} </h4></a>
135
- <p class="card-subtitle">{ authors_str } <br/>{ affiliations_str } </p>
136
- <p class="my-2">{ short_description } </p>
137
- </div>
138
- </div>
139
- { modal_str }
134
+ new_card = f"""
135
+ :::{{grid-item-card}}
136
+ :shadow: md
137
+ :class-footer: card-footer
138
+ :class-card: tagged-card { tag_classes }
140
139
141
- +++
140
+ <div class="d-flex gallery-card">
141
+ <img src="{ thumbnail } " class="gallery-thumbnail" />
142
+ <div class="container">
143
+ <a href="{ item ["url" ]} " class="text-decoration-none"><h4 class="display-4 p-0">{ item ["title" ]} </h4></a>
144
+ <p class="card-subtitle">{ authors_str } <br/>{ affiliations_str } </p>
145
+ <p class="my-2">{ short_description } </p>
146
+ </div>
147
+ </div>
148
+ { modal_str }
142
149
143
- { tags }
150
+ +++
144
151
145
- :::
152
+ { tags }
146
153
147
- """
154
+ :::
148
155
149
- grid_body . append ( ' \n ' . join ([ m . lstrip () for m in new_card . split ( ' \n ' )]))
156
+ """
150
157
151
- grid_body = '\n ' .join (grid_body )
158
+ grid_body . append ( '\n ' .join ([ m . lstrip () for m in new_card . split ( ' \n ' )]) )
152
159
153
160
stitle = f'#### { subtitle } ' if subtitle else ''
154
161
stext = subtext if subtext else ''
155
162
163
+ grid_body = '\n ' .join (grid_body )
156
164
grid = f"""\
157
165
{ title }
158
166
{ '=' * len (title )}
@@ -163,12 +171,12 @@ def build_from_items(items, filename, title='Gallery', subtitle=None, subtext=No
163
171
{ menu_html }
164
172
165
173
::::{{grid}} 1
166
- :gutter: 4
174
+ :gutter: 0
167
175
168
176
{ grid_body }
169
177
170
178
<div class="modal-backdrop"></div>
171
- <script src="/_static/custom.js"></script>
179
+ <script src="../html /_static/custom.js"></script>
172
180
"""
173
181
174
182
grid = '\n ' .join ([m .lstrip () for m in grid .split ('\n ' )])
0 commit comments