3 from collections
import defaultdict
8 def merge_continuation_lines(lines
: "list[str]"):
13 nest_level
+= len(re
.findall(r
"(?<!\\)\{", line
))
14 nest_level
-= len(re
.findall(r
"(?<!\\)\}", line
))
15 assert nest_level
>= 0, "too many closing }"
19 assert nest_level
== 0, "missing closing }"
22 def merge_footnotes(lines
: "list[str]"):
24 footnote_inp_ctr_to_text_map
: "dict[int, str]" = {}
26 def replace_footnotemark(match
):
28 print(f
"input footnote ref #{inp_ctr}")
29 retval
= "\\footnotemark{" + str(inp_ctr
) + "}"
33 tmpl_lines
= [] # template lines
34 for line
in merge_continuation_lines(lines
):
35 parts
= line
.split(r
'\footnotetext')
37 assert len(parts
) == 2 and parts
[0] == '', \
38 "\\footnotetext must only be at the beginning of a line"
42 after_footnote
= False
43 for part
in re
.split(r
'(?<!\\)(\{|\})', parts
[1]):
46 if nest_level
== 1 and not after_footnote
:
47 continue # remove leading {
50 if nest_level
== 0 and not after_footnote
:
52 continue # remove trailing }
54 trailing_parts
.append(part
)
56 footnote_parts
.append(part
)
57 footnote_text
= ''.join(footnote_parts
)
58 trailing_text
= ''.join(trailing_parts
)
59 print(f
"input footnote #{inp_ctr - 1}: {footnote_text[:30]}")
60 footnote_inp_ctr_to_text_map
[inp_ctr
- 1] = footnote_text
61 line
= "\\footnotetext{}" + trailing_text
64 r
"\\addtocounter\{footnote\}\{(-?[1-9][0-9]*)\}\n", line
)
66 adj
= int(match
.group(1))
68 print(f
"adjust input footnote counter by {adj} to {inp_ctr}")
70 line
= re
.sub(r
"\\footnotemark\{\}", replace_footnotemark
, line
)
71 tmpl_lines
.append(line
)
72 footnote_text_to_id_map
: "dict[str, int]" = {}
74 footnote_queue
: "list[str]" = []
76 def replace_footnotemark_tmpl(match
: "re.Match[str]"):
77 nonlocal next_footnote_id
78 inp_ctr
= int(match
.group(1))
79 text
= footnote_inp_ctr_to_text_map
[inp_ctr
]
80 footnote_id
= footnote_text_to_id_map
.get(text
)
81 if footnote_id
is None:
82 footnote_id
= next_footnote_id
84 footnote_text_to_id_map
[text
] = footnote_id
85 footnote_queue
.append(
87 + str(footnote_id
) + "]{" + text
+ "}")
88 return "\\footnotemark[" + str(footnote_id
) + "]"
91 for line
in tmpl_lines
:
92 parts
= line
.split(r
'\footnotetext{}')
94 if len(footnote_queue
) == 0:
97 line
= footnote_queue
.pop() + parts
[1]
98 for footnote
in footnote_queue
:
99 retval
.append(footnote
+ "\n")
100 footnote_queue
.clear()
101 line
= re
.sub(r
"\\footnotemark\{([0-9]+)\}",
102 replace_footnotemark_tmpl
, line
)
107 with
open(sys
.argv
[1], "r") as f
:
108 lines
= list(f
.readlines())
110 with
open(sys
.argv
[2], "w") as o
:
111 if sys
.argv
[1].endswith("comparison_table_pre.tex"):
112 o
.write("\\renewcommand{\\footnotesize}"
113 "{\\fontsize{6pt}{4pt}\\selectfont}\n")
114 lines
= merge_footnotes(lines
)
117 if sys
.argv
[1].endswith("comparison_table_pre.tex") and \
118 line
.startswith(r
"\begin{itemize}"):
120 o
.write("\\itemsep -0.6em\n")