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.
- pyeasyphd/.python-version +1 -0
- pyeasyphd/Main.sublime-menu +43 -0
- pyeasyphd/__init__.py +5 -0
- pyeasyphd/data/templates/csl/apa-no-ampersand.csl +2183 -0
- pyeasyphd/data/templates/csl/apa.csl +2133 -0
- pyeasyphd/data/templates/csl/ieee.csl +512 -0
- pyeasyphd/data/templates/tex/Article.tex +38 -0
- pyeasyphd/data/templates/tex/Article_Header.tex +29 -0
- pyeasyphd/data/templates/tex/Article_Tail.tex +3 -0
- pyeasyphd/data/templates/tex/Beamer_Header.tex +79 -0
- pyeasyphd/data/templates/tex/Beamer_Tail.tex +14 -0
- pyeasyphd/data/templates/tex/Style.tex +240 -0
- pyeasyphd/data/templates/tex/TEVC_Header.tex +52 -0
- pyeasyphd/data/templates/tex/TEVC_Tail.tex +4 -0
- pyeasyphd/data/templates/tex/eisvogel.tex +1064 -0
- pyeasyphd/data/templates/tex/math.tex +201 -0
- pyeasyphd/data/templates/tex/math_commands.tex +677 -0
- pyeasyphd/data/templates/tex/nextaimathmacros.sty +681 -0
- pyeasyphd/main/__init__.py +6 -0
- pyeasyphd/main/basic_input.py +101 -0
- pyeasyphd/main/pandoc_md_to.py +380 -0
- pyeasyphd/main/python_run_md.py +320 -0
- pyeasyphd/main/python_run_tex.py +200 -0
- pyeasyphd/pyeasyphd.py +86 -0
- pyeasyphd/pyeasyphd.sublime-settings +100 -0
- pyeasyphd/pyeasyphd.sublime-syntax +5 -0
- pyeasyphd/scripts/__init__.py +34 -0
- pyeasyphd/scripts/_base.py +65 -0
- pyeasyphd/scripts/run_article_md.py +101 -0
- pyeasyphd/scripts/run_article_tex.py +94 -0
- pyeasyphd/scripts/run_beamer_tex.py +84 -0
- pyeasyphd/scripts/run_compare.py +71 -0
- pyeasyphd/scripts/run_format.py +62 -0
- pyeasyphd/scripts/run_generate.py +211 -0
- pyeasyphd/scripts/run_replace.py +34 -0
- pyeasyphd/scripts/run_search.py +251 -0
- pyeasyphd/tools/__init__.py +12 -0
- pyeasyphd/tools/generate/generate_from_bibs.py +181 -0
- pyeasyphd/tools/generate/generate_html.py +166 -0
- pyeasyphd/tools/generate/generate_library.py +203 -0
- pyeasyphd/tools/generate/generate_links.py +400 -0
- pyeasyphd/tools/py_run_bib_md_tex.py +398 -0
- pyeasyphd/tools/search/data.py +282 -0
- pyeasyphd/tools/search/search_base.py +146 -0
- pyeasyphd/tools/search/search_core.py +400 -0
- pyeasyphd/tools/search/search_keywords.py +229 -0
- pyeasyphd/tools/search/search_writers.py +350 -0
- pyeasyphd/tools/search/utils.py +190 -0
- pyeasyphd/utils/utils.py +99 -0
- pyeasyphd-0.4.42.dist-info/METADATA +33 -0
- pyeasyphd-0.4.42.dist-info/RECORD +53 -0
- pyeasyphd-0.4.42.dist-info/WHEEL +4 -0
- pyeasyphd-0.4.42.dist-info/licenses/LICENSE +674 -0
|
@@ -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
|