pyeasyphd 0.4.42__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. pyeasyphd/.python-version +1 -0
  2. pyeasyphd/Main.sublime-menu +43 -0
  3. pyeasyphd/__init__.py +5 -0
  4. pyeasyphd/data/templates/csl/apa-no-ampersand.csl +2183 -0
  5. pyeasyphd/data/templates/csl/apa.csl +2133 -0
  6. pyeasyphd/data/templates/csl/ieee.csl +512 -0
  7. pyeasyphd/data/templates/tex/Article.tex +38 -0
  8. pyeasyphd/data/templates/tex/Article_Header.tex +29 -0
  9. pyeasyphd/data/templates/tex/Article_Tail.tex +3 -0
  10. pyeasyphd/data/templates/tex/Beamer_Header.tex +79 -0
  11. pyeasyphd/data/templates/tex/Beamer_Tail.tex +14 -0
  12. pyeasyphd/data/templates/tex/Style.tex +240 -0
  13. pyeasyphd/data/templates/tex/TEVC_Header.tex +52 -0
  14. pyeasyphd/data/templates/tex/TEVC_Tail.tex +4 -0
  15. pyeasyphd/data/templates/tex/eisvogel.tex +1064 -0
  16. pyeasyphd/data/templates/tex/math.tex +201 -0
  17. pyeasyphd/data/templates/tex/math_commands.tex +677 -0
  18. pyeasyphd/data/templates/tex/nextaimathmacros.sty +681 -0
  19. pyeasyphd/main/__init__.py +6 -0
  20. pyeasyphd/main/basic_input.py +101 -0
  21. pyeasyphd/main/pandoc_md_to.py +380 -0
  22. pyeasyphd/main/python_run_md.py +320 -0
  23. pyeasyphd/main/python_run_tex.py +200 -0
  24. pyeasyphd/pyeasyphd.py +86 -0
  25. pyeasyphd/pyeasyphd.sublime-settings +100 -0
  26. pyeasyphd/pyeasyphd.sublime-syntax +5 -0
  27. pyeasyphd/scripts/__init__.py +34 -0
  28. pyeasyphd/scripts/_base.py +65 -0
  29. pyeasyphd/scripts/run_article_md.py +101 -0
  30. pyeasyphd/scripts/run_article_tex.py +94 -0
  31. pyeasyphd/scripts/run_beamer_tex.py +84 -0
  32. pyeasyphd/scripts/run_compare.py +71 -0
  33. pyeasyphd/scripts/run_format.py +62 -0
  34. pyeasyphd/scripts/run_generate.py +211 -0
  35. pyeasyphd/scripts/run_replace.py +34 -0
  36. pyeasyphd/scripts/run_search.py +251 -0
  37. pyeasyphd/tools/__init__.py +12 -0
  38. pyeasyphd/tools/generate/generate_from_bibs.py +181 -0
  39. pyeasyphd/tools/generate/generate_html.py +166 -0
  40. pyeasyphd/tools/generate/generate_library.py +203 -0
  41. pyeasyphd/tools/generate/generate_links.py +400 -0
  42. pyeasyphd/tools/py_run_bib_md_tex.py +398 -0
  43. pyeasyphd/tools/search/data.py +282 -0
  44. pyeasyphd/tools/search/search_base.py +146 -0
  45. pyeasyphd/tools/search/search_core.py +400 -0
  46. pyeasyphd/tools/search/search_keywords.py +229 -0
  47. pyeasyphd/tools/search/search_writers.py +350 -0
  48. pyeasyphd/tools/search/utils.py +190 -0
  49. pyeasyphd/utils/utils.py +99 -0
  50. pyeasyphd-0.4.42.dist-info/METADATA +33 -0
  51. pyeasyphd-0.4.42.dist-info/RECORD +53 -0
  52. pyeasyphd-0.4.42.dist-info/WHEEL +4 -0
  53. pyeasyphd-0.4.42.dist-info/licenses/LICENSE +674 -0
@@ -0,0 +1,6 @@
1
+ __all__ = ["BasicInput", "PandocMdTo", "PythonRunMd", "PythonRunTex"]
2
+
3
+ from .basic_input import BasicInput
4
+ from .pandoc_md_to import PandocMdTo
5
+ from .python_run_md import PythonRunMd
6
+ from .python_run_tex import PythonRunTex
@@ -0,0 +1,101 @@
1
+ import os
2
+ from typing import Any
3
+
4
+ from pyadvtools import read_list
5
+ from pybibtexer.main import BasicInput as BasicInputInPyBibtexer
6
+
7
+
8
+ class BasicInput(BasicInputInPyBibtexer):
9
+ """Basic input class for handling bibliography and template configurations.
10
+
11
+ Args:
12
+ options (dict[str, Any]): Configuration options.
13
+
14
+ Attributes:
15
+ full_csl_style_pandoc (str): Full path to CSL style for pandoc.
16
+ full_tex_article_template_pandoc (str): Full path to tex article template for pandoc.
17
+ full_tex_beamer_template_pandoc (str): Full path to tex beamer template for pandoc.
18
+ article_template_tex (list[str]): Article template for LaTeX.
19
+ article_template_header_tex (list[str]): Article template header for LaTeX.
20
+ article_template_tail_tex (list[str]): Article template tail for LaTeX.
21
+ beamer_template_header_tex (list[str]): Beamer template header for LaTeX.
22
+ beamer_template_tail_tex (list[str]): Beamer template tail for LaTeX.
23
+ math_commands_tex (list[str]): LaTeX math commands.
24
+ usepackages_tex (list[str]): LaTeX usepackages.
25
+ handly_preamble (bool): Whether to handle preamble manually.
26
+ options (dict[str, Any]): Configuration options.
27
+ """
28
+
29
+ def __init__(self, options: dict[str, Any]) -> None:
30
+ """Initialize BasicInput with configuration options.
31
+
32
+ Args:
33
+ options (dict[str, Any]): Configuration options dictionary.
34
+ """
35
+ super().__init__(options)
36
+
37
+ current_dir = os.path.dirname(os.path.abspath(__file__))
38
+ self._path_templates = os.path.join(os.path.dirname(current_dir), "data", "templates")
39
+
40
+ # main
41
+ self._initialize_pandoc_md_to(options)
42
+ self._initialize_python_run_tex(options)
43
+
44
+ self.options = options
45
+
46
+ def _initialize_pandoc_md_to(self, options: dict[str, Any]) -> None:
47
+ """Initialize pandoc markdown to other formats configuration.
48
+
49
+ Args:
50
+ options (dict[str, Any]): Configuration options.
51
+ """
52
+ csl_name = options.get("csl_name", "apa-no-ampersand")
53
+ if not isinstance(csl_name, str):
54
+ csl_name = "apa-no-ampersand"
55
+ self.full_csl_style_pandoc = os.path.join(self._path_templates, "csl", f"{csl_name}.csl")
56
+ if not os.path.exists(self.full_csl_style_pandoc):
57
+ self.full_csl_style_pandoc = os.path.join(self._path_templates, "csl", "apa-no-ampersand.csl")
58
+
59
+ self.full_tex_article_template_pandoc = os.path.join(self._path_templates, "tex", "eisvogel.latex")
60
+ self.full_tex_beamer_template_pandoc = os.path.join(self._path_templates, "tex", "eisvogel.beamer")
61
+
62
+ self.article_template_tex = self._try_read_list("tex", "Article.tex")
63
+
64
+ def _initialize_python_run_tex(self, options: dict[str, Any]) -> None:
65
+ """Initialize Python LaTeX processing configuration.
66
+
67
+ Args:
68
+ options (dict[str, Any]): Configuration options.
69
+ """
70
+ self.article_template_header_tex = self._try_read_list("tex", "Article_Header.tex")
71
+ self.article_template_tail_tex = self._try_read_list("tex", "Article_Tail.tex")
72
+ self.beamer_template_header_tex = self._try_read_list("tex", "Beamer_Header.tex")
73
+ self.beamer_template_tail_tex = self._try_read_list("tex", "Beamer_Tail.tex")
74
+ self.math_commands_tex = self._try_read_list("tex", "math_commands.tex")
75
+ self.usepackages_tex = self._try_read_list("tex", "Style.tex")
76
+
77
+ # handly preamble
78
+ self.handly_preamble = options.get("handly_preamble", False)
79
+ if self.handly_preamble:
80
+ self.article_template_header_tex, self.article_template_tail_tex = [], []
81
+ self.beamer_template_header_tex, self.beamer_template_tail_tex = [], []
82
+ self.math_commands_tex, self.usepackages_tex = [], []
83
+
84
+ def _try_read_list(self, folder_name: str, file_name: str):
85
+ """Try to read a list from a file in the templates directory.
86
+
87
+ Args:
88
+ folder_name (str): Name of the folder in templates directory.
89
+ file_name (str): Name of the file to read.
90
+
91
+ Returns:
92
+ list[str]: list of lines from the file, or empty list if file cannot be read.
93
+ """
94
+ path_file = os.path.join(self._path_templates, folder_name, file_name)
95
+
96
+ try:
97
+ data_list = read_list(path_file)
98
+ except Exception as e:
99
+ print(e)
100
+ data_list = []
101
+ return data_list
@@ -0,0 +1,380 @@
1
+ import copy
2
+ import os
3
+ import re
4
+ import subprocess
5
+ import time
6
+
7
+ from pyadvtools import (
8
+ combine_content_in_list,
9
+ delete_empty_lines_last_occur_add_new_line,
10
+ insert_list_in_list,
11
+ read_list,
12
+ substitute_in_list,
13
+ write_list,
14
+ )
15
+
16
+ from ..utils.utils import operate_on_generate_html
17
+ from .basic_input import BasicInput
18
+
19
+
20
+ class PandocMdTo(BasicInput):
21
+ r"""Pandoc markdown to various formats (md, tex, html, pdf).
22
+
23
+ Args:
24
+ options (dict): Configuration options.
25
+
26
+ Attributes:
27
+ markdown_name (str): Markdown name. Defaults to "multi-markdown".
28
+ markdown_citation (str): Markdown citation format. Defaults to "markdown_mmd".
29
+ columns_in_md (int): Number of columns in markdown. Defaults to 120.
30
+ display_one_line_reference_note (bool): Whether to display one line reference note. Defaults to False.
31
+ cite_flag_in_tex (str): Citation flag in LaTeX. Defaults to "cite".
32
+ add_url_for_basic_dict (bool): Whether to add url for items in basic dict. Defualts to True.
33
+ add_anchor_for_basic_dict (bool): Whether to add anchor for items in basic dict. Defaults to False.
34
+ add_anchor_for_beauty_dict (bool): Whether to add anchor for items in beauty dict. Defaults to False.
35
+ add_anchor_for_complex_dict (bool): Whether to add anchor for items in complex dict. Defaults to False.
36
+ details_to_bib_separator (str): Separator between <details> and bibliography content. Defaults to "\n".
37
+ """
38
+
39
+ def __init__(self, options: dict) -> None:
40
+ """Initialize PandocMdTo with configuration options.
41
+
42
+ Args:
43
+ options (dict): Configuration options.
44
+ """
45
+ super().__init__(options)
46
+
47
+ self.markdown_name: str = "multi-markdown"
48
+ self.markdown_citation: str = "markdown_mmd"
49
+ if self.markdown_name == "pandoc-markdown":
50
+ self.markdown_citation = "markdown-citations"
51
+
52
+ self.columns_in_md: int = options.get("columns_in_md", 120)
53
+ self.display_one_line_reference_note: bool = options.get("display_one_line_reference_note", False)
54
+ # tex
55
+ self.cite_flag_in_tex: str = options.get("cite_flag_in_tex", "cite")
56
+
57
+ self.add_url_for_basic_dict: bool = options.get("add_url_for_basic_dict", True)
58
+ self.add_anchor_for_basic_dict: bool = options.get("add_anchor_for_basic_dict", False)
59
+ self.add_anchor_for_beauty_dict: bool = options.get("add_anchor_for_beauty_dict", False)
60
+ self.add_anchor_for_complex_dict: bool = options.get("add_anchor_for_complex_dict", False)
61
+
62
+ self.details_to_bib_separator: str = options.get("details_to_bib_separator", "\n")
63
+
64
+ def pandoc_md_to_md(
65
+ self, path_bib: str, path_md_one: str, path_md_two: str, name_md_one: str | None, name_md_two: str | None
66
+ ) -> list[str]:
67
+ """Convert markdown to markdown using pandoc.
68
+
69
+ Args:
70
+ path_bib (str): Path to bibliography file.
71
+ path_md_one (str): Path to source markdown directory.
72
+ path_md_two (str): Path to destination markdown directory.
73
+ name_md_one (Optional[str]): Name of source markdown file.
74
+ name_md_two (Optional[str]): Name of destination markdown file.
75
+
76
+ Returns:
77
+ list[str]: list of processed markdown content lines.
78
+ """
79
+ full_one = path_md_one if name_md_one is None else os.path.join(path_md_one, name_md_one)
80
+ full_two = path_md_two if name_md_two is None else os.path.join(path_md_two, name_md_two)
81
+ return self._pandoc_md_to_md(full_one, full_two, path_bib)
82
+
83
+ def _pandoc_md_to_md(self, full_md_one: str, full_md_two: str, path_bib: str) -> list[str]:
84
+ """Internal method to convert markdown to markdown using pandoc.
85
+
86
+ Args:
87
+ full_md_one (str): Full path to source markdown file.
88
+ full_md_two (str): Full path to destination markdown file.
89
+ path_bib (str): Path to bibliography file.
90
+
91
+ Returns:
92
+ list[str]: list of processed markdown content lines.
93
+ """
94
+ if not os.path.exists(path_two := os.path.dirname(full_md_two)):
95
+ os.makedirs(path_two)
96
+
97
+ if os.path.exists(self.full_csl_style_pandoc):
98
+ cmd = (
99
+ f"pandoc {full_md_one} -t {self.markdown_citation} "
100
+ f"-o {full_md_two} -M reference-section-title='References' "
101
+ f"--citeproc --bibliography={path_bib} --csl={self.full_csl_style_pandoc} --columns {self.columns_in_md}"
102
+ )
103
+ else:
104
+ cmd = (
105
+ f"pandoc {full_md_one} -t {self.markdown_citation} "
106
+ f"-o {full_md_two} -M reference-section-title='References' "
107
+ f"--citeproc --bibliography={path_bib} --columns {self.columns_in_md}"
108
+ )
109
+
110
+ try:
111
+ subprocess.run(cmd.split(), check=True, capture_output=True, text=True)
112
+ except subprocess.CalledProcessError as e:
113
+ print("Pandoc error in pandoc md to md:", e.stderr)
114
+
115
+ if not os.path.exists(full_md_two):
116
+ print(f"- pandoc false from md to md: {os.path.basename(full_md_two)}\n")
117
+ return []
118
+
119
+ return self._standardize_markdown_content(full_md_two)
120
+
121
+ @staticmethod
122
+ def _standardize_markdown_content(full_md: str) -> list[str]:
123
+ regex = re.compile(r"(\s*>*\s*[-+*]+)\s\s\s(.*)")
124
+ for i in range(len(data_list := read_list(full_md, "r"))):
125
+ if mch := regex.match(data_list[i]):
126
+ data_list[i] = data_list[i].replace(mch.group(), mch.group(1) + " " + mch.group(2))
127
+ return data_list
128
+
129
+ # for pandoc markdown files to tex files
130
+ def pandoc_md_to_tex(
131
+ self, template_name: str, path_md: str, path_tex: str, name_md: str | None, name_tex: str | None
132
+ ) -> list[str]:
133
+ full_one = path_md if name_md is None else os.path.join(path_md, name_md)
134
+ full_two = path_tex if name_tex is None else os.path.join(path_tex, name_tex)
135
+ return self._pandoc_md_to_tex(full_one, full_two, template_name)
136
+
137
+ def _pandoc_md_to_tex(self, full_md: str, full_tex: str, template_name: str) -> list[str]:
138
+ """Pandoc."""
139
+ if not os.path.exists(path_tex := os.path.dirname(full_tex)):
140
+ os.makedirs(path_tex)
141
+
142
+ if template_name.lower() == "beamer":
143
+ cmd = f"pandoc {full_md} -t beamer -o {full_tex} --from markdown "
144
+ else:
145
+ cmd = f"pandoc {full_md} -o {full_tex} --from markdown "
146
+
147
+ try:
148
+ subprocess.run(cmd.split(), check=True, capture_output=True, text=True)
149
+ except subprocess.CalledProcessError as e:
150
+ print("Pandoc error in pandoc md to tex:", e.stderr)
151
+
152
+ if not os.path.exists(full_tex):
153
+ print(f"- pandoc false from md to tex: {os.path.basename(full_md)}\n")
154
+ return []
155
+
156
+ return self._substitute_in_tex_from_md(read_list(full_tex, "r", None))
157
+
158
+ def _substitute_in_tex_from_md(self, data_list: list[str]) -> list[str]:
159
+ old_str_list = [r"{\[}@", r"{\[}-@", r"{\[}", r"{\]}", r"\\_"]
160
+ new_str_list = [rf"\\{self.cite_flag_in_tex}" + "{", rf"\\{self.cite_flag_in_tex}" + "{", "{", "}", "_"]
161
+ old_str_list.extend([r"\\footnote<.->{", r";", r"@"])
162
+ new_str_list.extend([r"\\footnote{", ",", ""])
163
+ return substitute_in_list(old_str_list, new_str_list, data_list)
164
+
165
+ # for pandoc markdown files to html files
166
+ def pandoc_md_to_html(
167
+ self, path_md: str, path_html: str, name_md: str | None, name_html: str | None, operate: bool = False
168
+ ) -> str:
169
+ full_one = path_md if name_md is None else os.path.join(path_md, name_md)
170
+ full_two = path_html if name_html is None else os.path.join(path_html, name_html)
171
+ return self._pandoc_md_to_html(full_one, full_two, operate)
172
+
173
+ @staticmethod
174
+ def _pandoc_md_to_html(full_md: str, full_html: str, operate: bool = False) -> str:
175
+ """Pandoc."""
176
+ if not os.path.exists(path_html := os.path.dirname(full_html)):
177
+ os.makedirs(path_html)
178
+
179
+ cmd = f"pandoc {full_md} -o {full_html} --from markdown "
180
+
181
+ try:
182
+ subprocess.run(cmd.split(), check=True, capture_output=True, text=True)
183
+ except subprocess.CalledProcessError as e:
184
+ print("Pandoc error in pandoc md to html:", e.stderr)
185
+
186
+ if not os.path.exists(full_html):
187
+ return f"- pandoc false from md to html: {os.path.basename(full_md)}\n"
188
+
189
+ if operate:
190
+ operate_on_generate_html(full_html)
191
+ return ""
192
+
193
+ # for pandoc markdown files to pdf files
194
+ def pandoc_md_to_pdf(self, path_md: str, path_pdf: str, name_md: str | None, name_pdf: str | None) -> str:
195
+ full_one = path_md if name_md is None else os.path.join(path_md, name_md)
196
+ full_two = path_pdf if name_pdf is None else os.path.join(path_pdf, name_pdf)
197
+ return self._pandoc_md_to_pdf(full_one, full_two)
198
+
199
+ def _pandoc_md_to_pdf(self, full_md: str, full_pdf: str) -> str:
200
+ """Pandoc."""
201
+ if not os.path.exists(path_pdf := os.path.dirname(full_pdf)):
202
+ os.makedirs(path_pdf)
203
+
204
+ if os.path.exists(self.full_tex_article_template_pandoc):
205
+ cmd = (
206
+ f"pandoc {full_md} -o {full_pdf} --from markdown "
207
+ f"--template {self.full_tex_article_template_pandoc} --listings --pdf-engine=xelatex"
208
+ )
209
+ else:
210
+ cmd = f"pandoc {full_md} -o {full_pdf} --from markdown --listings --pdf-engine=xelatex"
211
+
212
+ try:
213
+ subprocess.run(cmd.split(), check=True, capture_output=True, text=True)
214
+ except subprocess.CalledProcessError as e:
215
+ print("Pandoc error in pandoc md to pdf:", e.stderr)
216
+
217
+ if not os.path.exists(full_pdf):
218
+ return f"- pandoc false from md to pdf: {os.path.basename(full_md)}\n"
219
+ return ""
220
+
221
+ # --------- --------- --------- --------- --------- --------- --------- --------- --------- #
222
+ # md
223
+ def generate_key_data_dict(
224
+ self, pandoc_md_data_list: list[str], key_url_http_bib_dict: dict[str, list[list[str]]]
225
+ ) -> tuple[dict[str, list[str]], dict[str, list[str]], dict[str, list[str]]]:
226
+ """Generate."""
227
+ key_reference_dict = self._generate_citation_key_reference_dict_from_pandoc_md(pandoc_md_data_list)
228
+ (key_basic_dict, key_beauty_dict, key_complex_dict) = self._generate_basic_beauty_complex_dict(
229
+ key_url_http_bib_dict, key_reference_dict
230
+ )
231
+ return key_basic_dict, key_beauty_dict, key_complex_dict
232
+
233
+ def _generate_citation_key_reference_dict_from_pandoc_md(
234
+ self, pandoc_md_data_list: list[str]
235
+ ) -> dict[str, list[str]]:
236
+ """Generate."""
237
+ pandoc_md_data_list = self.__append_pandoc_md_reference_part(pandoc_md_data_list)
238
+
239
+ line_index, len_data = 0, len(pandoc_md_data_list)
240
+ if self.markdown_name == "pandoc-markdown":
241
+ a_flag, b_flag = r"^:::\s{#ref-(.*)\s\.csl-entry}", r"^:::"
242
+ else: # multi-markdown
243
+ a_flag, b_flag = r'^<div\sid="ref-(.*?)"', r"^</div>"
244
+
245
+ regex_one, regex_two = re.compile(a_flag), re.compile(b_flag)
246
+ key_reference_dict = {}
247
+ while line_index < len_data:
248
+ match_one = regex_one.search(pandoc_md_data_list[line_index])
249
+ line_index += 1
250
+ if not match_one:
251
+ continue
252
+ citation_key = match_one.group(1).strip()
253
+
254
+ content = []
255
+ while line_index < len_data:
256
+ line = pandoc_md_data_list[line_index]
257
+ if regex_two.search(line):
258
+ break
259
+
260
+ line_index += 1
261
+ if mch := re.search(r"([<\[]https?://)", line):
262
+ content.append(line.split(mch.group(1))[0][:-1])
263
+ break
264
+ else:
265
+ if line.strip():
266
+ content.append(line)
267
+
268
+ key_reference_dict.update({citation_key: delete_empty_lines_last_occur_add_new_line(content)})
269
+ return key_reference_dict
270
+
271
+ def __append_pandoc_md_reference_part(self, pandoc_md_data_list: list[str]) -> list[str]:
272
+ """Append the line which starts with '::: {#'."""
273
+ line_index, len_data = 0, len(pandoc_md_data_list)
274
+ if self.markdown_name == "pandoc-markdown":
275
+ a_flag, b_flag = r":::\s{#", r"}"
276
+ else: # multi-markdown
277
+ a_flag, b_flag = r'<div\sid="ref', r">"
278
+ regex = re.compile(a_flag)
279
+ new_list = []
280
+ while line_index < len_data:
281
+ line = pandoc_md_data_list[line_index]
282
+ line_index += 1
283
+ if regex.search(line):
284
+ while line_index < len_data:
285
+ if b_flag != line.rstrip()[-1]:
286
+ line = line.rstrip() + " " + pandoc_md_data_list[line_index].lstrip()
287
+ line_index += 1
288
+ else:
289
+ new_list.append(line)
290
+ break
291
+ if line_index == len_data:
292
+ new_list.append(line)
293
+ else:
294
+ new_list.append(line)
295
+ return delete_empty_lines_last_occur_add_new_line(new_list)
296
+
297
+ def _generate_basic_beauty_complex_dict(
298
+ self, key_url_http_bib_dict: dict[str, list[list[str]]], key_reference_dict: dict[str, list]
299
+ ) -> tuple[dict[str, list[str]], dict[str, list[str]], dict[str, list[str]]]:
300
+ """Generate."""
301
+ header_list = [f"<details>{self.details_to_bib_separator}", "```\n"]
302
+ tail_list = ["```\n", "</details>\n"]
303
+
304
+ key_basic_dict: dict[str, list[str]] = {}
305
+ key_beauty_dict: dict[str, list[str]] = {}
306
+ key_complex_dict: dict[str, list[str]] = {}
307
+
308
+ key_list_http = list(key_url_http_bib_dict.keys())
309
+ key_list_md = list(key_reference_dict.keys())
310
+ if set(key_list_http) != set(key_list_md):
311
+ print(f"`key_list_md`: set({key_list_md}) should be the same with `key_list_http`: set({key_list_http}).")
312
+ return key_basic_dict, key_beauty_dict, key_complex_dict
313
+
314
+ for k in key_list_http:
315
+ a: list[str] = copy.deepcopy(key_reference_dict[k])
316
+ b: list[str] = copy.deepcopy(key_reference_dict[k])
317
+ aa: list[str] = key_url_http_bib_dict[k][0]
318
+ bb: list[str] = key_url_http_bib_dict[k][1]
319
+
320
+ # add url
321
+ if self.add_url_for_basic_dict:
322
+ a.extend(aa)
323
+
324
+ b.extend(bb)
325
+
326
+ # add anchor
327
+ if self.add_anchor_for_basic_dict:
328
+ a = [f'<a id="{k.lower()}"></a>\n', *a]
329
+ if self.add_anchor_for_beauty_dict or self.add_anchor_for_complex_dict:
330
+ b = [f'<a id="{k.lower()}"></a>\n', *b]
331
+
332
+ if self.display_one_line_reference_note:
333
+ a = ["".join(a).replace("\n", " ").strip() + "\n"]
334
+ b = ["".join(b).replace("\n", " ").strip() + "\n"]
335
+
336
+ c = combine_content_in_list([b, header_list, key_url_http_bib_dict[k][2], tail_list])
337
+ key_basic_dict.update({k: a})
338
+ key_beauty_dict.update({k: b})
339
+ key_complex_dict.update({k: c})
340
+ return key_basic_dict, key_beauty_dict, key_complex_dict
341
+
342
+ # --------- --------- --------- --------- --------- --------- --------- --------- --------- #
343
+ # tex
344
+ def generate_tex_content(self, file_prefix: str, path_subsection: str, path_bib: str, path_combine: str) -> None:
345
+ # for latex
346
+ # add template for tex file
347
+ add_bib_name = os.path.join(os.path.basename(path_bib), f"{file_prefix}-abbr.bib")
348
+ add_tex_name = os.path.join(os.path.basename(path_subsection), f"{file_prefix}.tex")
349
+ insert_part_one, insert_part_two = self._generate_tex_content(file_prefix, add_tex_name, add_bib_name)
350
+
351
+ # write tex
352
+ data_temp = insert_list_in_list(self.article_template_tex, insert_part_one, r"\\begin{document}", "before")
353
+ data_temp = insert_list_in_list(data_temp, insert_part_two, r"\\begin{document}", "after")
354
+ write_list(data_temp, f"{file_prefix}.tex", "w", os.path.join(path_combine, "tex"))
355
+ return None
356
+
357
+ @staticmethod
358
+ def _generate_tex_content(file_prefix: str, add_tex_name: str, add_bib_name: str) -> tuple[list[str], list[str]]:
359
+ if len(file_prefix) == 0:
360
+ file_prefix = "file_prefix"
361
+
362
+ part_one = [
363
+ "\\date{" + "{}".format(time.strftime("%B %d, %Y")) + "}\n\n",
364
+ "\\ifx \\fullpath \\undefined\n",
365
+ " \\addbibresource{" + os.path.join("..", add_bib_name) + "}\n",
366
+ "\\else\n",
367
+ " \\addbibresource{" + os.path.join("\\fullpath", add_bib_name) + "}\n",
368
+ "\\fi\n\n",
369
+ ]
370
+ part_two = [
371
+ "\n",
372
+ "% \\maketitle\n",
373
+ "\\tableofcontents\n\n",
374
+ "\\ifx \\fullpath \\undefined\n",
375
+ " \\input{" + os.path.join("..", add_tex_name) + "}\n",
376
+ "\\else\n",
377
+ " \\input{" + os.path.join("\\fullpath", add_tex_name) + "}\n",
378
+ "\\fi\n",
379
+ ]
380
+ return part_one, part_two