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,166 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from pyadvtools import write_list
|
|
5
|
+
from pybibtexer.bib.bibtexparser import Library
|
|
6
|
+
from pybibtexer.main import PythonRunBib, PythonWriters
|
|
7
|
+
|
|
8
|
+
from ...utils.utils import html_head, html_style, html_tail, textarea_header, textarea_tail
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def generate_html_content(html_body, abbr_standard):
|
|
12
|
+
"""Create complete HTML document from body content.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
html_body: list of HTML body content lines.
|
|
16
|
+
abbr_standard (str): Standard abbreviation for the document.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
list[str]: Complete HTML document as list of lines.
|
|
20
|
+
"""
|
|
21
|
+
return [html_head.format(abbr_standard), html_style, "\n", *html_body, *html_tail]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def generate_html_from_bib_data(
|
|
25
|
+
abbr_standard: str,
|
|
26
|
+
original_bib_data: list[str] | str | Library,
|
|
27
|
+
path_output: str,
|
|
28
|
+
options: dict[str, Any] | None = None,
|
|
29
|
+
) -> list[str]:
|
|
30
|
+
"""Generate HTML from bibliography data.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
abbr_standard (str): Standard abbreviation for the publication.
|
|
34
|
+
original_bib_data (list[str] | str | Library): Bibliography data in various formats.
|
|
35
|
+
path_output (str): Path to output directory.
|
|
36
|
+
options (dict[str, Any], optional): Additional processing options. Defaults to {}.
|
|
37
|
+
full_json_c (str, optional): Path to conferences JSON file. Defaults to "".
|
|
38
|
+
full_json_j (str, optional): Path to journals JSON file. Defaults to "".
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
list[str]: list of HTML body content lines.
|
|
42
|
+
"""
|
|
43
|
+
if options is None:
|
|
44
|
+
options = {}
|
|
45
|
+
|
|
46
|
+
# Set processing options
|
|
47
|
+
processing_options: dict = {
|
|
48
|
+
# convert_str_to_library
|
|
49
|
+
"is_standardize_bib": False,
|
|
50
|
+
# middlewares_str_to_library.py
|
|
51
|
+
"is_display_implicit_comments": False,
|
|
52
|
+
#
|
|
53
|
+
# convert_library_to_library.py
|
|
54
|
+
# middlewares_library_to_library.py
|
|
55
|
+
"function_common_again": False,
|
|
56
|
+
"function_common_again_for_abbr": False,
|
|
57
|
+
"function_common_again_for_zotero": False,
|
|
58
|
+
"function_common_again_for_save": False,
|
|
59
|
+
"abbr_index_article_for_abbr": 2,
|
|
60
|
+
"abbr_index_inproceedings_for_abbr": 2,
|
|
61
|
+
#
|
|
62
|
+
# convert_library_to_str.py
|
|
63
|
+
"empty_entry_cite_keys": True,
|
|
64
|
+
# middlewares_library_to_str.py
|
|
65
|
+
"is_sort_entry_fields": True,
|
|
66
|
+
"is_sort_blocks": True,
|
|
67
|
+
"sort_entries_by_field_keys_reverse": True,
|
|
68
|
+
}
|
|
69
|
+
# Update with provided options
|
|
70
|
+
processing_options.update(options)
|
|
71
|
+
|
|
72
|
+
# Process bibliography data
|
|
73
|
+
_python_bib = PythonRunBib(processing_options)
|
|
74
|
+
_, zotero_library, _ = _python_bib.parse_to_multi_standard_library(original_bib_data)
|
|
75
|
+
|
|
76
|
+
_python_writer = PythonWriters(processing_options)
|
|
77
|
+
|
|
78
|
+
# Generate HTML content for each entry
|
|
79
|
+
html_body = []
|
|
80
|
+
for entry in zotero_library.entries:
|
|
81
|
+
html_body.append(_format_entry_to_html(entry, abbr_standard, _python_writer.write_to_str([entry])))
|
|
82
|
+
|
|
83
|
+
# Create complete HTML document if entries exist
|
|
84
|
+
if len(html_body) > 0:
|
|
85
|
+
html_body = [
|
|
86
|
+
f'<h2 id="{abbr_standard.lower()}">{abbr_standard} - {len(zotero_library.entries)}</h2>\n',
|
|
87
|
+
"<ul>\n",
|
|
88
|
+
*html_body,
|
|
89
|
+
"</ul>\n",
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
html_content = generate_html_content(html_body, abbr_standard)
|
|
93
|
+
output_dir = os.path.join(path_output, abbr_standard)
|
|
94
|
+
|
|
95
|
+
# Write output file
|
|
96
|
+
write_list(html_content, f"{abbr_standard}.html", "w", output_dir, False)
|
|
97
|
+
|
|
98
|
+
return html_body
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _format_entry_to_html(entry, abbr, data_list):
|
|
102
|
+
"""Format a single bibliography entry into HTML.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
entry: Bibliography entry dictionary.
|
|
106
|
+
abbr (str): Publication abbreviation.
|
|
107
|
+
data_list: list of formatted bibliography data.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
str: HTML formatted entry string.
|
|
111
|
+
"""
|
|
112
|
+
# Extract entry fields
|
|
113
|
+
number = entry["number"] if "number" in entry else ""
|
|
114
|
+
pages = entry["pages"] if "pages" in entry else ""
|
|
115
|
+
title = entry["title"] if "title" in entry else ""
|
|
116
|
+
year = entry["year"] if "year" in entry else ""
|
|
117
|
+
volume = entry["volume"] if "volume" in entry else ""
|
|
118
|
+
|
|
119
|
+
# Get URL (DOI preferred, fall back to URL)
|
|
120
|
+
url = ""
|
|
121
|
+
if "doi" in entry:
|
|
122
|
+
doi = entry["doi"]
|
|
123
|
+
url = doi if doi.startswith("http") else f"https://doi.org/{doi}"
|
|
124
|
+
elif "url" in entry:
|
|
125
|
+
url = entry["url"]
|
|
126
|
+
|
|
127
|
+
# Format entry in APA style
|
|
128
|
+
line = _format_entry_to_apa_style(title, year, volume, number, pages, url, abbr)
|
|
129
|
+
|
|
130
|
+
line = f"<li><details>\n<summary>\n{line.strip()}\n</summary>\n"
|
|
131
|
+
|
|
132
|
+
# Create HTML structure with details
|
|
133
|
+
return line + textarea_header + "".join(data_list).rstrip() + textarea_tail + "\n</details></li>\n"
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _format_entry_to_apa_style(title, year, volume, number, pages, url, abbr):
|
|
137
|
+
"""Format entry in APA citation style.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
title (str): Article title.
|
|
141
|
+
year (str): Publication year.
|
|
142
|
+
volume (str): Journal volume.
|
|
143
|
+
number (str): Issue number.
|
|
144
|
+
pages (str): Page numbers.
|
|
145
|
+
url (str): Article URL.
|
|
146
|
+
abbr (str): Publication abbreviation.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
str: APA formatted citation string.
|
|
150
|
+
"""
|
|
151
|
+
line = f"({year}). {title}. <em>{abbr}</em>"
|
|
152
|
+
|
|
153
|
+
if volume:
|
|
154
|
+
line += f", <em>{volume}</em>"
|
|
155
|
+
if number:
|
|
156
|
+
line += f"({number})"
|
|
157
|
+
|
|
158
|
+
if pages:
|
|
159
|
+
line += f", {pages}"
|
|
160
|
+
|
|
161
|
+
line += "."
|
|
162
|
+
|
|
163
|
+
if url:
|
|
164
|
+
line += f" (<a href='{url}'>www</a>)"
|
|
165
|
+
|
|
166
|
+
return line
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from pyadvtools import IterateSortDict
|
|
4
|
+
from pybibtexer.bib.bibtexparser import Entry, Library
|
|
5
|
+
from pybibtexer.main import PythonRunBib
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def generate_library_by_filters(
|
|
9
|
+
original_data: list[str] | str | Library,
|
|
10
|
+
issue_or_month_flag: str | list[str], # filter
|
|
11
|
+
year_flag: str | list[str] = "current_year", # filter
|
|
12
|
+
options: dict[str, Any] | None = None,
|
|
13
|
+
) -> Library:
|
|
14
|
+
"""Generate a Library object from input data with given filters.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
original_data (list[str] | str | Library): Input bibliography data.
|
|
18
|
+
issue_or_month_flag (str | list[str]): Flag for issue/month selection.
|
|
19
|
+
year_flag (str | list[str], optional): Flag for year selection. Defaults to "current_year".
|
|
20
|
+
options (dict[str, Any], optional): Additional options. Defaults to {}.
|
|
21
|
+
full_json_c (str, optional): JSON configuration for conference proceedings. Defaults to "".
|
|
22
|
+
full_json_j (str, optional): JSON configuration for journal articles. Defaults to "".
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Library: Processed library object.
|
|
26
|
+
"""
|
|
27
|
+
if options is None:
|
|
28
|
+
options = {}
|
|
29
|
+
|
|
30
|
+
_options = {}
|
|
31
|
+
# convert_str_to_library
|
|
32
|
+
_options["is_standardize_bib"] = False # default is True
|
|
33
|
+
# middlewares_str_to_library.py
|
|
34
|
+
_options["is_display_implicit_comments"] = False # default is True
|
|
35
|
+
|
|
36
|
+
# convert_library_to_library.py
|
|
37
|
+
_options["choose_abbr_zotero_save"] = "save" # default is "save"
|
|
38
|
+
# middlewares_library_to_library.py
|
|
39
|
+
_options["generate_entry_cite_keys"] = False # default is False
|
|
40
|
+
_options["function_common_again"] = False # default is True
|
|
41
|
+
_options["function_common_again_for_abbr"] = False # default is True
|
|
42
|
+
_options["function_common_again_for_zotero"] = False # default is True
|
|
43
|
+
_options["function_common_again_for_save"] = False # default is True
|
|
44
|
+
|
|
45
|
+
# convert_library_to_str.py
|
|
46
|
+
# middlewares_library_to_str.py
|
|
47
|
+
_options["is_sort_entry_fields"] = True # compulsory
|
|
48
|
+
_options["is_sort_blocks"] = True # compulsory
|
|
49
|
+
_options["sort_entries_by_field_keys_reverse"] = True # compulsory
|
|
50
|
+
|
|
51
|
+
# convert_str_to_str.py
|
|
52
|
+
_options["default_additional_field_list"] = []
|
|
53
|
+
# middlewares_str_to_str.py
|
|
54
|
+
_options["substitute_in_bib"] = False # default is True
|
|
55
|
+
|
|
56
|
+
_options.update(options)
|
|
57
|
+
_python_bib = PythonRunBib(_options)
|
|
58
|
+
|
|
59
|
+
# Generate nested entries dictionary
|
|
60
|
+
entry_type_year_volume_number_month_entry_dict = _python_bib.parse_to_nested_entries_dict(original_data)
|
|
61
|
+
old_dict = entry_type_year_volume_number_month_entry_dict
|
|
62
|
+
|
|
63
|
+
# Filter by year flag
|
|
64
|
+
new_dict = _obtain_year_flag_library(old_dict, year_flag)
|
|
65
|
+
|
|
66
|
+
# Filter by year flag
|
|
67
|
+
if not (isinstance(year_flag, str) and (year_flag.lower().strip() == "current_year")):
|
|
68
|
+
issue_or_month_flag = "all_months"
|
|
69
|
+
|
|
70
|
+
# Filter by issue flag
|
|
71
|
+
if issue_or_month_flag in ["current_issue"]:
|
|
72
|
+
return _obtain_issue_flag_library(new_dict, issue_or_month_flag)
|
|
73
|
+
|
|
74
|
+
# Filter by month flag
|
|
75
|
+
return _obtain_month_flag_library(new_dict, issue_or_month_flag)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _obtain_year_flag_library(
|
|
79
|
+
nested_entries: dict[str, dict[str, dict[str, dict[str, dict[str, list[Entry]]]]]],
|
|
80
|
+
year_flag: str | list[str] = "current_year",
|
|
81
|
+
):
|
|
82
|
+
"""Filter dictionary by year flag.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
nested_entries: Nested dictionary containing bibliography entries.
|
|
86
|
+
year_flag (str | list[str], optional): Year filter flag. Defaults to "current_year".
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
dict: Filtered dictionary by year.
|
|
90
|
+
"""
|
|
91
|
+
new_dict = {}
|
|
92
|
+
for entry_type in nested_entries:
|
|
93
|
+
years = list(nested_entries[entry_type])
|
|
94
|
+
|
|
95
|
+
# Update years
|
|
96
|
+
if isinstance(year_flag, list): # given_years
|
|
97
|
+
years = sorted(set(years).intersection(set(year_flag)))
|
|
98
|
+
elif year_flag.lower().strip() == "all_years": # all_years
|
|
99
|
+
years = years
|
|
100
|
+
elif year_flag.lower().strip() == "current_year": # current_year
|
|
101
|
+
years = years[:1]
|
|
102
|
+
else:
|
|
103
|
+
years = []
|
|
104
|
+
print(f"Unknown year flag: {year_flag}.")
|
|
105
|
+
|
|
106
|
+
for year in years:
|
|
107
|
+
new_dict.setdefault(entry_type, {}).update({year: nested_entries[entry_type][year]})
|
|
108
|
+
|
|
109
|
+
return new_dict
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _obtain_issue_flag_library(
|
|
113
|
+
nested_entries: dict[str, dict[str, dict[str, dict[str, dict[str, list[Entry]]]]]],
|
|
114
|
+
issue_flag: str = "current_issue",
|
|
115
|
+
) -> Library:
|
|
116
|
+
"""Filter dictionary by issue flag.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
nested_entries: Nested dictionary containing bibliography entries.
|
|
120
|
+
issue_flag (str, optional): Issue filter flag. Defaults to "current_issue".
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Library: Filtered library object.
|
|
124
|
+
"""
|
|
125
|
+
nested_entries = IterateSortDict(True).dict_update(nested_entries)
|
|
126
|
+
|
|
127
|
+
entries = []
|
|
128
|
+
for entry_type in nested_entries:
|
|
129
|
+
for year in nested_entries[entry_type]:
|
|
130
|
+
temp_dict = nested_entries[entry_type][year]
|
|
131
|
+
|
|
132
|
+
# Article entries
|
|
133
|
+
if entry_type.lower() == "article":
|
|
134
|
+
volumes, numbers, months = [], [], []
|
|
135
|
+
for volume in (volumes := list(temp_dict)):
|
|
136
|
+
for number in (numbers := list(temp_dict[volume])):
|
|
137
|
+
months = list(temp_dict[volume][number])
|
|
138
|
+
break
|
|
139
|
+
break
|
|
140
|
+
|
|
141
|
+
if issue_flag == "current_issue": # current volume, current issue, and current month
|
|
142
|
+
entries.extend(temp_dict[volumes[0]][numbers[0]][months[0]])
|
|
143
|
+
else:
|
|
144
|
+
print(f"Unknown issue flag: {issue_flag}.")
|
|
145
|
+
|
|
146
|
+
else:
|
|
147
|
+
# Non-article entries
|
|
148
|
+
for volume in temp_dict:
|
|
149
|
+
for number in temp_dict[volume]:
|
|
150
|
+
for month in temp_dict[volume][number]:
|
|
151
|
+
entries.extend(temp_dict[volume][number][month])
|
|
152
|
+
|
|
153
|
+
return Library(entries)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def _obtain_month_flag_library(
|
|
157
|
+
nested_entries: dict[str, dict[str, dict[str, dict[str, dict[str, list[Entry]]]]]],
|
|
158
|
+
month_flag: str | list[str] = "current_month",
|
|
159
|
+
) -> Library:
|
|
160
|
+
"""Filter dictionary by month flag.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
nested_entries: Nested dictionary containing bibliography entries.
|
|
164
|
+
month_flag (str | list[str], optional): Month filter flag. Defaults to "current_month".
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
Library: Filtered library object.
|
|
168
|
+
"""
|
|
169
|
+
new_dict = {}
|
|
170
|
+
for entry_type in nested_entries:
|
|
171
|
+
for year in nested_entries[entry_type]:
|
|
172
|
+
for volume in nested_entries[entry_type][year]:
|
|
173
|
+
for number in nested_entries[entry_type][year][volume]:
|
|
174
|
+
for month in nested_entries[entry_type][year][volume][number]:
|
|
175
|
+
new_dict.setdefault(entry_type, {}).setdefault(year, {}).setdefault(month, {}).setdefault(
|
|
176
|
+
volume, {}
|
|
177
|
+
).setdefault(number, []).extend(nested_entries[entry_type][year][volume][number][month])
|
|
178
|
+
|
|
179
|
+
# Sort
|
|
180
|
+
nested_entries = IterateSortDict(True).dict_update(new_dict)
|
|
181
|
+
|
|
182
|
+
entries = []
|
|
183
|
+
for entry_type in nested_entries:
|
|
184
|
+
for year in nested_entries[entry_type]:
|
|
185
|
+
temp_dict = nested_entries[entry_type][year]
|
|
186
|
+
default_months = list(temp_dict)
|
|
187
|
+
|
|
188
|
+
# Update month
|
|
189
|
+
new_months = []
|
|
190
|
+
if month_flag == "current_month": # current_month
|
|
191
|
+
new_months = default_months[:1]
|
|
192
|
+
elif month_flag == "all_months": # all months
|
|
193
|
+
new_months = default_months
|
|
194
|
+
else:
|
|
195
|
+
print(f"Unknown month flag: {month_flag}.")
|
|
196
|
+
|
|
197
|
+
# Filter by month
|
|
198
|
+
for month in new_months:
|
|
199
|
+
for volume in temp_dict[month]:
|
|
200
|
+
for number in temp_dict[month][volume]:
|
|
201
|
+
entries.extend(temp_dict[month][volume][number])
|
|
202
|
+
|
|
203
|
+
return Library(entries)
|