Browse Source

Initiate repository from existing material

master
Jean-Sébastien Caux 11 months ago
commit
90b2388b0b

+ 23
- 0
.gitignore View File

@@ -0,0 +1,23 @@
1
+*~
2
+*.swp
3
+
4
+deprec
5
+export
6
+
7
+venv_*
8
+
9
+todo.org
10
+src/ltximg
11
+
12
+*.pdf
13
+*.aux
14
+*.bbl
15
+*.blg
16
+*.idx
17
+*.log
18
+*.out
19
+*.toc
20
+
21
+src/index.html
22
+src/index.pdf
23
+src/index.tex

+ 5
- 0
changelog.org View File

@@ -0,0 +1,5 @@
1
+
2
+* 2023
3
+** 06
4
+*** 05  Initiated repository
5
+Set up the repo starting from existing material.

+ 296
- 0
css/style.css View File

@@ -0,0 +1,296 @@
1
+
2
+/* body { */
3
+/*     margin: 1rem; */
4
+/*     padding: 1rem; */
5
+/* } */
6
+
7
+html {
8
+    padding: 4rem;
9
+}
10
+body{
11
+    margin: 1rem auto;
12
+    max-width: 60rem;
13
+    line-height: 1.4;
14
+    font-size: 1.1rem;
15
+    color: #222;
16
+    padding: 0 1rem;
17
+    overflow: auto;
18
+}
19
+
20
+.title {
21
+    margin-bottom: 2rem;
22
+}
23
+
24
+/* Table of contents */
25
+nav#collapsed-table-of-contents {
26
+    margin-bottom: 1rem;
27
+}
28
+nav#collapsed-table-of-contents details {
29
+    background-color: #e8e8e8;
30
+    border: none;
31
+    margin: 0.5rem;
32
+}
33
+nav#collapsed-table-of-contents details summary {
34
+    padding: 0.5rem;
35
+}
36
+nav#collapsed-table-of-contents > details > summary { /* bigger padding for main toc */
37
+    padding: 1rem;
38
+}
39
+nav#collapsed-table-of-contents details ul {
40
+    list-style: none;
41
+    margin: 0.5rem;
42
+    padding: 0;
43
+}
44
+nav#collapsed-table-of-contents details > ul > li {
45
+    margin: 0.5rem;
46
+}
47
+nav#collapsed-table-of-contents details > ul > li > a {
48
+    margin: 0.5rem 1rem;
49
+}
50
+nav#collapsed-table-of-contents details > ul > li.toc-open {
51
+    background-color: #c0e8d0;
52
+}
53
+nav#collapsed-table-of-contents details > ul > li.toc-currentpage {
54
+    background-color: #a0e0b0;
55
+}
56
+nav#collapsed-table-of-contents details[open] {
57
+    border: 1px solid gray;
58
+}
59
+nav#collapsed-table-of-contents details[open] > summary {
60
+    background-color: #d0d0d0;
61
+}
62
+nav#collapsed-table-of-contents details > summary:hover {
63
+    background-color: #d8d8d8;
64
+}
65
+nav#collapsed-table-of-contents details > summary.toc-open {
66
+    background-color: #d0e8d0;
67
+}
68
+nav#collapsed-table-of-contents details > summary.toc-currentpage {
69
+    background-color: #a0e0b0;
70
+}
71
+
72
+div#text-table-of-contents ul {
73
+    margin: 0;
74
+    list-style: none;
75
+}
76
+
77
+
78
+/* DEPREC Navbar */
79
+div.navbar {
80
+    list-style: none;
81
+}
82
+div.navbar li {
83
+    display: inline;
84
+}
85
+
86
+
87
+/* Breadcrumbs */
88
+ul.breadcrumbs {
89
+    font-size: 70%;
90
+    list-style: none;
91
+    margin: 0;
92
+}
93
+ul.breadcrumbs > li {
94
+    display: inline;
95
+    margin-right: 0.3rem;
96
+}
97
+ul.breadcrumbs > li+li:before {
98
+    content: "/\00a0";
99
+}
100
+
101
+ul.navigation-links {
102
+    list-style: none;
103
+    margin: 0;
104
+}
105
+ul.navigation-links > li {
106
+    font-size: 70%;
107
+    display: inline-block;
108
+    margin-right: 1rem;
109
+}
110
+ul.navigation-links > li {
111
+    text-decoration: none;
112
+}
113
+
114
+table th, table td {
115
+    padding: 0.5rem;
116
+}
117
+
118
+/* HTML5-specific tags */
119
+
120
+aside {
121
+    width: 40%;
122
+    padding-left: .5rem;
123
+    margin-left: .5rem;
124
+    float: right;
125
+    box-shadow: inset 5px 0 5px -5px #29627e;
126
+    font-style: italic;
127
+    color: #29627e;
128
+}
129
+
130
+aside > p {
131
+    margin: .5rem;
132
+}
133
+
134
+details {
135
+    border: 1px solid gray;
136
+    margin: 1rem;
137
+    padding: 0rem;
138
+    clear: both;
139
+}
140
+summary {
141
+    padding: 1rem;
142
+}
143
+details[open] > p, ul {
144
+    margin-left: 1rem;
145
+    margin-right: 1rem;
146
+    margin: 1rem;
147
+}
148
+
149
+
150
+/* Preformatted code blocks */
151
+pre {
152
+    border-radius: .3rem;
153
+    background-color: #f2efe4;
154
+    padding: .5rem;
155
+}
156
+
157
+
158
+/* rank-based container classes */
159
+.rant {
160
+    opacity: 0.5;
161
+}
162
+
163
+
164
+/* Environment-specific styles */
165
+
166
+.prereq {
167
+    background-color: rgba(191, 0, 0, 0.2);
168
+}
169
+.objectives {
170
+    background-color: rgba(191, 191, 255, 0.6);
171
+}
172
+.core {
173
+    background-color: rgba(191, 255, 191, 0.4);
174
+}
175
+.derivation {
176
+    background-color: rgba(191, 255, 191, 0.2);
177
+}
178
+.example {
179
+    background-color: rgba(255, 255, 191, 0.6);
180
+}
181
+.info {
182
+    background-color: rgba(159, 255, 255, 0.4);
183
+}
184
+.context {
185
+    background-color: rgba(191, 223, 255, 0.6);
186
+}
187
+
188
+/* when details are open, darken summary */
189
+details[open].prereq > summary {
190
+    background-color: rgba(191, 0, 0, 0.1);
191
+}
192
+details[open].objectives > summary {
193
+    background-color: rgba(191, 191, 255, 0.6);
194
+}
195
+details[open].core > summary {
196
+    background-color: rgba(191, 255, 191, 0.4);
197
+}
198
+details[open].derivation > summary {
199
+    background-color: rgba(191, 255, 191, 0.2);
200
+}
201
+details[open].example > summary {
202
+    background-color: rgba(255, 255, 191, 0.6);
203
+}
204
+details[open].info > summary {
205
+    background-color: rgba(159, 255, 255, 0.4);
206
+}
207
+details[open].context > summary {
208
+    background-color: rgba(191, 223, 255, 0.6);
209
+}
210
+
211
+
212
+/* Permalinks to sections */
213
+a.headline-permalink, span.headline-id {
214
+    float: right;
215
+    margin-right: 1rem;
216
+    font-size: 70%;
217
+    text-decoration: none;
218
+}
219
+
220
+/* when contextual colors are used for a div */
221
+div.prereq, div.objectives, div.core, div.derivation, div.example, div.info, div.context {
222
+    margin: 1rem;
223
+    padding: 1rem;
224
+    padding-bottom: 1.5rem;  /* to fit the alteqlabels inside colored box */
225
+    overflow: auto;
226
+}
227
+
228
+/* Giving equation nrs from other sources: use aside element */
229
+/* aside.alteqlabels { */
230
+/*     box-shadow: none; /\* remove standard aside property *\/ */
231
+/*     color: gray; */
232
+/*     font-size: 50%; */
233
+/*     width: 10%; */
234
+/* } */
235
+/* aside.alteqlabels > ul { */
236
+/*     list-style: none; */
237
+/* } */
238
+
239
+ul.altsecnrs {
240
+    color: gray;
241
+    font-size: 60%;
242
+    float: right;
243
+    /* clear: both; */
244
+    list-style: none;
245
+    margin-top: -1rem;
246
+    padding-top: 0;
247
+}
248
+ul.altsecnrs > li {
249
+    display: inline-block;
250
+}
251
+ul.altsecnrs > li:not(:first-child)::before {
252
+    content: '/';
253
+    margin-right: 0.2rem;
254
+}
255
+
256
+div.eqlabel {
257
+    float: right;
258
+    clear: both;
259
+    position: relative;
260
+    z-index: 10;
261
+}
262
+div.eqlabel p {
263
+    margin: 0;
264
+    margin-left: 1rem;
265
+}
266
+
267
+div.alteqlabels {
268
+    color: gray;
269
+    font-size: 60%;
270
+    float: right;
271
+    clear: both;
272
+}
273
+div.alteqlabels > ul {
274
+    list-style: none;
275
+    margin-left: 1rem;
276
+    padding: 0;
277
+}
278
+/* div.alteqlabels p { */
279
+/*     float: right; */
280
+/*     clear: both; */
281
+/* } */
282
+
283
+
284
+/* Equations */
285
+/* .eq-permalink { */
286
+/*     float: right; */
287
+/* } */
288
+
289
+
290
+div.license {
291
+    font-size: 60%;
292
+}
293
+
294
+.figs2 img {
295
+    width: 100%;
296
+}

+ 3
- 0
readme.org View File

@@ -0,0 +1,3 @@
1
+* The Bethe Ansatz
2
+
3
+Source files for the  [[https://integrability.org][integrability.org]] presenting a collection of online resources on the Bethe Ansatz and related concepts used in the study of integrable models of quantum mechanics.

+ 112
- 0
scripts/cleanup_links.py View File

@@ -0,0 +1,112 @@
1
+#! /usr/bin/env python
2
+
3
+import os
4
+from lxml.html import parse, etree, tostring
5
+
6
+link_svg = """<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-link" viewBox="0 0 16 16">
7
+  <path d="M6.354 5.5H4a3 3 0 0 0 0 6h3a3 3 0 0 0 2.83-4H9c-.086 0-.17.01-.25.031A2 2 0 0 1 7 10.5H4a2 2 0 1 1 0-4h1.535c.218-.376.495-.714.82-1z"/>
8
+  <path d="M9 5.5a3 3 0 0 0-2.83 4h1.098A2 2 0 0 1 9 6.5h3a2 2 0 1 1 0 4h-1.535a4.02 4.02 0 0 1-.82 1H12a3 3 0 1 0 0-6H9z"/>
9
+</svg>"""
10
+
11
+
12
+os.chdir('export/html')
13
+filenames = [f.rpartition('.html')[0] for f in os.listdir() if f.endswith('html')]
14
+
15
+# Build dictionary of which dedicated links and headline links  (by filename)
16
+dl = {}
17
+hl = {}
18
+cl = {}
19
+for filename in filenames:
20
+    dl[filename] = []
21
+    hl[filename] = []
22
+    tree = parse(f'{filename}.html')
23
+    for el in tree.iter():
24
+        # find all dedicated links, which are of form 'a id="..."'
25
+        # (they are the only links with and id)
26
+        if (el.tag == 'a' and 'id' in el.attrib):
27
+            # #and el.attrib['id'].partition(':')[0] in filenames):
28
+            #and el.attrib['id'].partition(':')[0] == 'eq'):
29
+            # raise flag if id coincides with a filename:
30
+            if el.attrib['id'] in filenames:
31
+                print("** Error: dedicated link name clashes with "
32
+                      f"headline CUSTOM_ID {el.attrib['id']} **")
33
+            # raise flag if this key already exists:
34
+            if el.attrib['id'] in dl[filename]:
35
+                print(f"** Error: multiply-defined label {el.attrib['id']} **")
36
+            else: # add this dedicated link to our dictionary
37
+                dl[filename].append(el.attrib['id'])
38
+        # find the headline links, which are of form '<h[2-6] id="...">'
39
+        if (el.tag in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] and 'id' in el.attrib):
40
+            if el.attrib['id'] in hl[filename]:
41
+                print("** Error: multiply-defined headline {el.attrib['id']} **")
42
+            else:
43
+                hl[filename].append({
44
+                    'tag': el.tag,
45
+                    'id': el.attrib['id'],
46
+                    'text': el[0].text # el[0] is the a tag (only child)
47
+                })
48
+        # find all the child section links inside `<ul class="child-link-list">`
49
+        # and are of the form `<li><a href="....html">`
50
+        # if (el.tag == 'ul' and 'class' in el.attrib and
51
+        #     el.attrib['class'] == 'child-link-list'):
52
+        #     for c in el:
53
+        #         cl[c[0].attrib['href'].partition('.')[0] ] =
54
+
55
+
56
+# Perform all substitutions
57
+for filename in filenames:
58
+    with open(f'{filename}.html', 'r') as file:
59
+        content = file.read()
60
+        # cleanup any stray type in script tags coming from old-fashioned org export
61
+        content = content.replace('style type="text/css"', 'style ')
62
+        content = content.replace('script type="text/javascript"', 'script ')
63
+        # remove validation link if present
64
+        content = content.replace('<a href="https://validator.w3.org/check?uri=referer">Validate</a>', '')
65
+        # section link substitutions
66
+        for val in filenames:
67
+            content = content.replace(
68
+                # link directly to the headline at `#{val}` even if it's top-level
69
+                # f'a href="#{val}"', f'a href="./{val}.html#{val}"')
70
+                f'href="#{val}"', f'href="./{val}.html#{val}"')
71
+        # equation link substitutions
72
+        for key, vals in dl.items():
73
+            for val in vals:
74
+                #print('Replacing ', f'href="#{val}"', ' by ', f'href="./{key}.html#{val}')
75
+                content = content.replace(f'href="#{val}"', f'href="./{key}.html#{val}"')
76
+                # add permalinks
77
+                content = content.replace(
78
+                    f'<a id="{val}"></a>',
79
+                    f'<a id="{val}"></a><a href="./{key}.html#{val}">{link_svg}</a>'
80
+                )
81
+        # add permalinks to headlines
82
+        for key, vals in hl.items():
83
+            for val in vals:
84
+                el_tag = val['tag']
85
+                el_id = val['id']
86
+                el_text = val['text']
87
+                content = content.replace(
88
+                    (f'<{el_tag} id="{el_id}">'
89
+                     f'<a href="./{key}.html#{el_id}">{el_text}</a></{el_tag}>'),
90
+                    (f'<{el_tag} id="{el_id}">{el_text}'
91
+                     f'<a class="headline-permalink" href="./{key}.html#{el_id}">'
92
+                     f'{link_svg}</a>'
93
+                     f'<span class="headline-id">{el_id.replace("_",".")}</span>'
94
+                     f'</{el_tag}>')
95
+                )
96
+                # add section ids to all `child-link-list`s
97
+                content = content.replace(
98
+                    f'<li><a href="{el_id}.html">{el_text}</a></li>',
99
+                    (f'<li><a href="{el_id}.html">{el_text}</a>'
100
+                    f'<span class="headline-id">'
101
+                    f'{el_id.replace("_",".")}</span></li>')
102
+                )
103
+                # add section ids to items in the toc
104
+                content = content.replace(
105
+                    f'<a class="toc-a" href="./{key}.html#{el_id}">{el_text}</a>',
106
+                    (f'<a class="toc-a" href="./{key}.html#{el_id}">{el_text}</a>'
107
+                    f'<span class="headline-id">'
108
+                    f'{el_id.replace("_",".")}</span>')
109
+                )
110
+    # rewrite file
111
+    with open(f'{filename}.html', 'w') as outfile:
112
+        outfile.write(content)

+ 23
- 0
scripts/export.sh View File

@@ -0,0 +1,23 @@
1
+#! /bin/sh
2
+
3
+BASEDIR="."
4
+
5
+mkdir -p $BASEDIR/export/html
6
+rm -rf $BASEDIR/export/html/*
7
+
8
+# Single-page version
9
+echo 'Creating single-page version...'
10
+mkdir -p $BASEDIR/export/html/singlepage
11
+cp $BASEDIR/src/org/index.html $BASEDIR/export/html/singlepage/index.html
12
+cp $BASEDIR/css/style.css $BASEDIR/export/html/singlepage/style.css
13
+cp -r $BASEDIR/src/fig $BASEDIR/export/html/singlepage/
14
+
15
+# Split version
16
+echo 'Creating split pages...'
17
+cp $BASEDIR/css/style.css $BASEDIR/export/html/style.css
18
+cp -r $BASEDIR/src/fig $BASEDIR/export/html/
19
+echo 'Exporting split html...'
20
+$BASEDIR/scripts/export_split.py
21
+echo 'Repairing links...'
22
+$BASEDIR/scripts/cleanup_links.py
23
+echo 'All done.'

+ 319
- 0
scripts/export_split.py View File

@@ -0,0 +1,319 @@
1
+#! /usr/bin/env python
2
+
3
+import os
4
+from lxml.html import parse, etree, tostring
5
+
6
+copyright_string = """
7
+<div class="license">
8
+<a rel="license noopener" href="https://creativecommons.org/licenses/by/4.0/"
9
+target="_blank" class="m-2">
10
+<img alt="Creative Commons License" style="border-width:0"
11
+src="https://licensebuttons.net/l/by/4.0/80x15.png"/>
12
+</a>
13
+Except where otherwise noted, all content is licensed under a
14
+<a rel="license noopener" href="https://creativecommons.org/licenses/by/4.0/"
15
+target="_blank">Creative Commons Attribution 4.0 International License</a>.
16
+</div>
17
+"""
18
+
19
+BASEDIR = "./"
20
+SRCDIR = f"{BASEDIR}src/org/"
21
+
22
+tree = parse(f"{SRCDIR}index.html")
23
+
24
+el_head = None
25
+el_header = None
26
+el_title = None
27
+el_nav = None
28
+el_ttoc = None
29
+el_content = None
30
+el_postamble = None
31
+
32
+sections_2 = []
33
+
34
+for el in tree.iter():
35
+    if el.tag == 'head':
36
+        el_head = el
37
+    if el.tag == 'header':
38
+        el_header = el
39
+    if 'class' in el.attrib and el.attrib['class'] == 'title':
40
+        el_title = el
41
+    if el.tag == 'nav':
42
+        el_nav = el
43
+    if 'id' in el.attrib and el.attrib['id'] == 'text-table-of-contents':
44
+        el_ttoc = el
45
+    if 'id' in el.attrib and el.attrib['id'] == 'content':
46
+        el_content = el
47
+    if 'id' in el.attrib and el.attrib['id'] == 'postamble':
48
+        el_postamble = el
49
+    if 'class' in el.attrib and el.attrib['class'].startswith('outline-2'):
50
+        sections_2.append(el)
51
+
52
+export_dir = f"{BASEDIR}export/html"
53
+if not os.path.isdir(export_dir):
54
+    os.makedirs(export_dir)
55
+
56
+
57
+def ordered_pages(el):
58
+    """
59
+    Creates a list of all pages, able to return previous, next and up links.
60
+
61
+    `el` should be the text-table-of-contents element.
62
+    """
63
+    page_ids = []
64
+    page_texts = []
65
+    for child in el.iter():
66
+        if child.tag == 'a':
67
+            page_ids.append(child.attrib['href'].lstrip('#'))
68
+            page_texts.append(child.text)
69
+    return page_ids, page_texts
70
+
71
+page_ids, page_texts = ordered_pages(el_ttoc)
72
+
73
+def head_at_location(el_head, page_id):
74
+    output = tostring(el_head, pretty_print=True, encoding='unicode')
75
+    try:
76
+        index = page_ids.index(page_id)
77
+    except ValueError:
78
+        return output
79
+    if index == 0:
80
+        return output
81
+    return output.replace(
82
+        '</title>',
83
+        f': {page_texts[index]}</title>'
84
+    )
85
+
86
+def breadcrumbs(page_id):
87
+    try:
88
+        index = page_ids.index(page_id)
89
+    except ValueError:
90
+        return ''
91
+    if index == 0: # mains page, no need for breadcrumbs
92
+        return ''
93
+    breadcrumb_lis = f'<li>{page_texts[index]}</li>'
94
+    # If book or article, take shortcut
95
+    if page_id.startswith("b-"): # this is a book
96
+        page_id_stripped = "l_b"
97
+    elif page_id[:4].isdigit(): # this is an article
98
+        page_id_stripped = f"l_a_{page_id[:4]}"
99
+    else:
100
+        page_id_stripped = page_ids[index].rpartition('_')[0]
101
+    while page_id_stripped:
102
+        index_stripped = page_ids.index(page_id_stripped)
103
+        breadcrumb_lis = (
104
+            # give class to link to prevent auto addition of ids from cleanup_links script
105
+            '<li><a class="breadcrumb-link"' +
106
+            f'href="{page_ids[index_stripped]}.html">' +
107
+            f'{page_texts[index_stripped]}</a></li>'
108
+            + breadcrumb_lis)
109
+        page_id_stripped = page_id_stripped.rpartition('_')[0]
110
+    return f'<ul class="breadcrumbs">{breadcrumb_lis}</ul>'
111
+
112
+def link_previous(page_id):
113
+    try:
114
+        index = page_ids.index(page_id)
115
+    except ValueError:
116
+        return None
117
+    if index == 0: # first, no previous
118
+        return None
119
+    # If depth is 1, there is no previous
120
+    if page_id.count('_') == 0:
121
+        return None
122
+    else:
123
+        return f'<a href="{page_ids[index-1]}.html">{page_texts[index-1]}&emsp;<small>[{page_ids[index-1].replace("_",".")}]</small></a>'
124
+
125
+def link_next(page_id):
126
+    try:
127
+        index = page_ids.index(page_id)
128
+    except ValueError:
129
+        return None
130
+    if index == len(page_ids) - 1: # last, no next
131
+        return None
132
+    return f'<a href="{page_ids[index+1]}.html">{page_texts[index+1]}&emsp;<small>[{page_ids[index+1].replace("_",".")}]</small></a>'
133
+
134
+def link_up(page_id):
135
+    try:
136
+        index = page_ids.index(page_id)
137
+    except ValueError:
138
+        return None
139
+    # Strip one '_' from id and point there
140
+    if page_id.count('_') > 0:
141
+        index_up = page_ids.index(page_id.rpartition('_')[0])
142
+        return f'<a href="{page_ids[index_up]}.html">{page_texts[index_up]}&emsp;<small>[{page_ids[index_up].replace("_",".")}]</small></a>'
143
+    return None
144
+
145
+def navigation_links(location):
146
+    links = '<ul class="navigation-links">'
147
+    previous = link_previous(location)
148
+    if previous:
149
+        links += f'<li>Prev:&nbsp;{previous}</li>'
150
+    nxt = link_next(location)
151
+    if nxt:
152
+        links += f'<li>Next:&nbsp;{nxt}</li>'
153
+    up = link_up(location)
154
+    if up:
155
+        links += f'<li>Up:&nbsp;{up}</li>'
156
+    links += '</ul>'
157
+    if previous or nxt or up:
158
+        return links
159
+    return ''
160
+
161
+def search_box():
162
+    return """
163
+    <form style="float: right; padding-right: 0;" method="get" id="search" action="https://duckduckgo.com/" target="_blank">
164
+    <input type="hidden" name="sites" value="integrability.org"/>
165
+    <input class="search" type="text" name="q" maxlength="300" placeholder="Search"/>
166
+    <input type="submit" value="Search" style="visibility: hidden; width: 0;" /></form>
167
+    """
168
+
169
+def list_to_details_recursive(el):
170
+    """
171
+    `el` contains either a single `a` child, or an `a` followed by `ul`.
172
+    In the first case, output as is.
173
+    In the second case, replace by details/summary.
174
+    """
175
+    # checks
176
+    if not (len(el) == 1 or len(el) == 2):
177
+        raise ValueError(f'el must have either 1 or 2 children, found {len(el)}')
178
+    if not el[0].tag in ['a', 'ul']:
179
+        raise ValueError(f'el[0] must be an a or ul tag, but found a {el[0].tag}')
180
+    if len(el) == 2 and not (el[0].tag == 'a' and el[1].tag == 'ul'):
181
+        raise ValueError(f'for len(el) == 2, el[1] must be ul, but found {el[1].tag}')
182
+    # single child, output as is
183
+    if len(el) == 1 and el[0].tag == 'a':
184
+        output = tostring(el[0], pretty_print=True, encoding='unicode')
185
+    else: # build a details/summary
186
+        summary_text = (
187
+            'Table of contents' + search_box() if len(el) == 1 else
188
+            tostring(el[0], pretty_print=True, encoding='unicode')
189
+        )
190
+        ul = el[0] if len(el) == 1 else el[1]
191
+        # print(f'summary_text: {summary_text}')
192
+        # print(f'len(ul): {len(ul)}')
193
+        # print([li.tag for li in ul])
194
+        # print([tostring(li, pretty_print=True, encoding='unicode') for li in ul])
195
+        output = ('\n<details>'
196
+                  f'\n<summary>\n{summary_text}'
197
+                  '\n</summary>\n<ul>\n')
198
+        for li in ul:
199
+            if not li.tag == 'li':
200
+                raise ValueError('child of ul should be li')
201
+            output += '<li>\n'
202
+            output += list_to_details_recursive(li)
203
+            output += '\n</li>\n'
204
+        output += '\n</ul>\n</details>'
205
+    return output
206
+
207
+
208
+
209
+collapsed_toc = '\n<nav id="collapsed-table-of-contents">'
210
+collapsed_toc += list_to_details_recursive(el_ttoc)
211
+collapsed_toc += '\n</nav>\n'
212
+
213
+
214
+def toc_at_location(collapsed_toc, location):
215
+    """
216
+    Given a collapsed toc and location (filename),
217
+    mark the details hierarchy as open.
218
+    """
219
+    output = collapsed_toc
220
+    if location != 'index':
221
+        # open all ancestors
222
+        prefix = location.rpartition('_')[0]
223
+        while prefix:
224
+            output = output.replace(
225
+                f'<details>\n<summary>\n<a href="#{prefix}"',
226
+                f'<details open="">\n<summary class="toc-open">\n<a href="#{prefix}"')
227
+            prefix = prefix.rpartition('_')[0]
228
+        # highlight the current location, whether it's a summary or a
229
+        output = output.replace(
230
+            f'<details>\n<summary>\n<a href="#{location}"',
231
+            f'<details open="">\n<summary class="toc-currentpage">\n<a href="#{location}"'
232
+        )
233
+        output = output.replace(
234
+            f'<li>\n<a href="#{location}"',
235
+            f'<li class="toc-currentpage">\n<a href="#{location}"'
236
+        )
237
+        # but close all details which contain deeper levels than location
238
+        output = output.replace(
239
+            f'<details open="">\n<summary>\n<a href="#{location}_',
240
+            f'<details>\n<summary>\n<a href="#{location}_')
241
+    return output.replace('<a href', '<a class="toc-a" href')
242
+
243
+def write_file_start(_file, location):
244
+    _file.write('<!DOCTYPE html>\n<html lang="en">\n')
245
+    _file.write(head_at_location(el_head, location))
246
+    _file.write('<div id="content">\n')
247
+    #_file.write(tostring(el_header, pretty_print=True, encoding='unicode'))
248
+    _file.write('<header>\n<h1 class="title">\n'
249
+                '<a href="./index.html" class="homepage-link">')
250
+    _file.write(f'{el_title.text}</a>\n</h1>\n</header>')
251
+    _file.write(toc_at_location(collapsed_toc, location))
252
+    _file.write(breadcrumbs(location))
253
+    _file.write(navigation_links(location))
254
+
255
+def write_file_end(_file, location):
256
+    _file.write('\n<br>')
257
+    _file.write(navigation_links(location)) # repeat, for convenience
258
+    _file.write('\n<br>')
259
+    _file.write('\n<hr>')
260
+    _file.write(copyright_string)
261
+    _file.write(tostring(el_postamble, pretty_print=True, encoding='unicode'))
262
+    _file.write('\n</div>\n</html>')
263
+
264
+
265
+def write_files_recursive(name, el, levelmax=5):
266
+    """
267
+    Recursively extract outlines.
268
+    """
269
+    if 'id' in el.attrib and el.attrib['id'] == 'content':
270
+        level = 1
271
+    elif not (el is not None and
272
+              'class' in el.attrib and
273
+              el.attrib['class'].startswith('outline-')):
274
+        print(f'Element name {name} has no outline class, no files written.')
275
+        return
276
+    else:
277
+        level = int(el.attrib['class'].partition('outline-')[2][0])
278
+
279
+    _file = open(f'{BASEDIR}export/html/{name}.html', 'w')
280
+    write_file_start(_file, name)
281
+
282
+    # Count outline children for establishing output format
283
+    children = []
284
+    for child in el.iter():
285
+        if ('class' in child.attrib and
286
+            child.attrib['class'].startswith('outline-%s' % str(level + 1))):
287
+            children.append(child)
288
+
289
+    # if no children or if we're on levelmax, write everything
290
+    if (len(children) == 0 or level == levelmax):
291
+        _file.write(tostring(el, pretty_print=True, encoding='unicode'))
292
+    # otherwise write anything above first next-level headling,
293
+    # and then replace the next-level headlines by links to their files
294
+    else:
295
+        if (el.text):
296
+            _file.write(el.text)
297
+        for child in el:
298
+            if ('class' in child.attrib and
299
+                child.attrib['class'].startswith('outline-%s' % str(level + 1))):
300
+                break # break out once we hit the first next-level headline
301
+            if child.tag != "nav": # don't write the table-of-contents
302
+                _file.write(tostring(child, pretty_print=True, encoding='unicode'))
303
+        # now print the list of children
304
+        _file.write(f'<h{level+1}>In this section:</h{level+1}>')
305
+        _file.write('\n<ul class="child-links-list">')
306
+        for child in children:
307
+            child_h = next(child.iter('h%s' % int(level + 1)))
308
+            child_label = child_h.attrib['id']
309
+            child_text = next(child_h.iter('a')).text
310
+            _file.write(f'\n<li><a href="{child_label}.html">{child_text}</a></li>')
311
+            write_files_recursive(name=child_label, el=child)
312
+        _file.write('\n</ul>\n')
313
+
314
+    write_file_end(_file, name)
315
+    _file.close()
316
+
317
+
318
+# Rewrite the index.html file:
319
+write_files_recursive('index', el_content) # the only call needed

+ 90
- 0
scripts/parse_bibtex.py View File

@@ -0,0 +1,90 @@
1
+#!/usr/bin/env python
2
+
3
+entries = {}
4
+
5
+outfile = open("../lit/papers.org", "w")
6
+
7
+
8
+def org_entry(bibtex_entry_text, bibtex_entry_dict):
9
+    if {
10
+            "key", "author", "title", "journal", "volume", "pages", "year", "doi",
11
+    } <= bibtex_entry_dict.keys():
12
+        b = {}
13
+        b["key"] = bibtex_entry_dict["key"].replace("_", ".")
14
+        b["author"] = bibtex_entry_dict["author"]
15
+        b["title"] = bibtex_entry_dict["title"]
16
+        b["journal"] = bibtex_entry_dict["journal"]
17
+        b["volume"] = bibtex_entry_dict["volume"]
18
+        b["pages"] = bibtex_entry_dict["pages"]
19
+        b["year"] = bibtex_entry_dict["year"]
20
+        b["doi"] = bibtex_entry_dict["doi"]
21
+        b_text = bibtex_entry_text.replace(bibtex_entry_dict["key"], b["key"])
22
+        return (
23
+            f"""
24
+
25
+**** {b["key"]}
26
+:PROPERTIES:
27
+:CUSTOM_ID: {b["key"]}
28
+:END:
29
+
30
+{b["author"]},
31
+/{b["title"]}/,
32
+{b["journal"]} **{b["volume"]}**, {b["pages"]} ({b["year"]}), doi:[[https://doi.org/{b["doi"]}][{b["doi"]}]].
33
+
34
+| <20>             | <60> |
35
+| Extended data    |      |
36
+|------------------+------|
37
+| Author           | {b["author"]} |
38
+| Title            | {b["title"]}  |
39
+| Journal          | {b["journal"]} |
40
+| Volume           | {b["volume"]} |
41
+| Pages            | {b["pages"]} |
42
+| Year             | {b["year"]} |
43
+| doi              | [[https://doi.org/{b["doi"]}][{b["doi"]}]] |
44
+| Publication date |      |
45
+|------------------+------|
46
+| Submission date  |      |
47
+""" + """
48
+#+begin_details
49
+#+begin_summary
50
+#+html: BibTeX
51
+#+end_summary
52
+#+begin_src bibtex
53
+""" + f"{b_text}" + """
54
+#+end_src
55
+#+end_details
56
+
57
+#+attr_html: :open true
58
+#+begin_details
59
+#+begin_summary
60
+#+html: Annotations
61
+#+end_summary
62
+#+end_details
63
+
64
+
65
+"""
66
+        )
67
+    else:
68
+        return ""
69
+
70
+
71
+with open("../lit/papers.bib", errors="ignore") as infile:
72
+    while line := infile.readline():
73
+        if "@article" in line.lower():
74
+            bibtex_entry = line
75
+            key = line.partition("{")[2].rstrip(",\n")
76
+            entries[key] = {}
77
+            entries[key]["key"] = key
78
+            while line := infile.readline():
79
+                bibtex_entry += line
80
+                if line.startswith("}"):
81
+                    break
82
+                field, _, value = line.partition("=")
83
+                field = field.strip()
84
+                value = value.strip().removesuffix(",")
85
+                if value.startswith("{{") and value.endswith("}}"):
86
+                    value = value.removeprefix("{{").removesuffix("}}")
87
+                value = value.removeprefix("{").removesuffix("}")
88
+                value = value.removeprefix('"').removesuffix('"')
89
+                entries[key][field] = value
90
+            outfile.write(org_entry(bibtex_entry, entries[key]))

+ 21
- 0
scripts/update_html_repo.sh View File

@@ -0,0 +1,21 @@
1
+#!/bin/sh
2
+
3
+ba_export_html_dir='/home/jscaux/work/writing/lecture_notes/Bethe_Ansatz/export/html/'
4
+ba_html_build_dir='/home/jscaux/work/writing/lecture_notes/Bethe_Ansatz_html/build/'
5
+
6
+cd $ba_html_build_dir
7
+
8
+cp -r $ba_export_html_dir* $ba_html_build_dir
9
+
10
+# remove files which don't exist anymore
11
+for file in $(ls -R)
12
+do
13
+    if ! [ -f $BA_export_html_dir$file ]
14
+    then
15
+	rm $file
16
+    fi
17
+done
18
+
19
+echo 'Committing'
20
+msg='Update '$(date +"%F %R")
21
+git commit -a -m "$msg"

+ 3
- 0
scripts/upload.sh View File

@@ -0,0 +1,3 @@
1
+#! /bin/bash
2
+
3
+rsync -avhPz --delete export/html/ jscaux@opal6.opalstack.com:apps/integrability

BIN
src/fig/Lieb-Liniger/e_t_v_GS_versus_gamma.jpg View File


BIN
src/fig/Lieb-Liniger/eps_type_I.jpg View File


BIN
src/fig/Lieb-Liniger/eps_type_II.jpg View File


BIN
src/fig/Lieb-Liniger/eps_type_I_gamma_0p01.jpg View File


BIN
src/fig/Lieb-Liniger/eps_type_I_gamma_1.jpg View File


BIN
src/fig/Lieb-Liniger/eps_type_I_gamma_100.jpg View File


BIN
src/fig/Lieb-Liniger/lambdaF_versus_gamma.jpg View File


BIN
src/fig/Lieb-Liniger/muGS_versus_gamma.jpg View File


BIN
src/fig/Lieb-Liniger/rhoGS_versus_lambda.jpg View File


BIN
src/fig/Lieb-Liniger/rhoT_versus_lambda.jpg View File


BIN
src/fig/Lieb-Liniger/rhohT_versus_lambda.jpg View File


+ 9727
- 0
src/index.org
File diff suppressed because it is too large
View File


+ 4
- 0
src/index_head.org View File

@@ -0,0 +1,4 @@
1
+# #+OPTIONS: num:nil  // uncomment to remove section numbering
2
+#+OPTIONS: toc:4
3
+
4
+#+AUTHOR: Jean-Sébastien Caux

Loading…
Cancel
Save