Skip to content

Commit f99c7e9

Browse files
authored
QR Code generation improvements (#1045)
* Make qr code generation dependent of hash, including baseurl * format
1 parent 0d380a9 commit f99c7e9

6 files changed

Lines changed: 115 additions & 35 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ Instructions: Add a subsection under `[Unreleased]` for additions, fixes, change
99

1010
## [Unreleased]
1111

12+
### Fixed
13+
14+
- Bug in which qrcodes don't generate for video/audio if no interactive or youtube elements exist.
15+
16+
### Changed
17+
18+
- qrcodes for pdf are now generated based on a hash of the elements they point to in addition to the baseurl for the publication file.
19+
1220
## [2.25.0] - 2025-07-26
1321

1422
Includes updates to core through commit: [45be2cf](https://github.com/PreTeXtBook/pretext/commit/45be2cfe85fd54a3e5c03743226919eb1a6b2085)

poetry.lock

Lines changed: 66 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pretext/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
VERSION = get_version("pretext", Path(__file__).parent.parent)
2020

2121

22-
CORE_COMMIT = "45be2cfe85fd54a3e5c03743226919eb1a6b2085"
22+
CORE_COMMIT = "f15f9b9fee75331d64d0fff4d757c479ef85fcb7"
2323

2424

2525
def activate() -> None:

pretext/constants.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"codelens",
3838
"datafile",
3939
"interactive",
40+
"qrcode",
4041
"mermaid",
4142
"myopenmath",
4243
"dynamic-subs",
@@ -50,6 +51,7 @@
5051
"codelens",
5152
"datafile",
5253
"interactive",
54+
"qrcode",
5355
"mermaid",
5456
"myopenmath",
5557
"dynamic-subs",
@@ -63,6 +65,7 @@
6365
"codelens",
6466
"datafile",
6567
"interactive",
68+
"qrcode",
6669
"mermaid",
6770
"myopenmath",
6871
"dynamic-subs",
@@ -76,6 +79,7 @@
7679
"codelens",
7780
"datafile",
7881
"interactive",
82+
"qrcode",
7983
"mermaid",
8084
"myopenmath",
8185
"dynamic-subs",
@@ -116,6 +120,7 @@
116120
"codelens",
117121
"datafile",
118122
"interactive",
123+
"qrcode",
119124
"mermaid",
120125
"myopenmath",
121126
"dynamic-subs",
@@ -132,6 +137,7 @@
132137
"codelens": ".//program[@interactive = 'codelens']",
133138
"datafile": ".//datafile",
134139
"interactive": ".//interactive",
140+
"qrcode": ".//audio[@source|@href]|.//video[@source|@href|@youtube|@youtubeplaylist|@vimeo]|.//interactive",
135141
"mermaid": ".//mermaid",
136142
"myopenmath": ".//myopenmath",
137143
"dynamic-subs": ".//statement[.//fillin and ancestor::exercise/evaluation]",
@@ -144,8 +150,9 @@
144150
"sageplot": ["sageplot"],
145151
"asymptote": ["asymptote"],
146152
"prefigure": ["prefigure"],
147-
"youtube": ["youtube", "play-button", "qrcode"],
148-
"interactive": ["preview", "qrcode"],
153+
"youtube": ["youtube", "play-button"],
154+
"interactive": ["preview"],
155+
"qrcode": ["qrcode"],
149156
"codelens": ["trace"],
150157
"datafile": ["datafile"],
151158
"mermaid": ["mermaid"],
@@ -159,14 +166,12 @@
159166
"latex-image": [],
160167
"sageplot": ["pdf", "png"],
161168
"prefigure": ["pdf"],
162-
"mermaid": ["png"],
163169
},
164170
"latex": {
165171
"asymptote": ["pdf"],
166172
"latex-image": [],
167173
"sageplot": ["pdf", "png"],
168174
"prefigure": ["pdf"],
169-
"mermaid": ["png"],
170175
},
171176
"html": {
172177
"asymptote": ["html"],
@@ -185,20 +190,17 @@
185190
"latex-image": ["svg"],
186191
"sageplot": ["svg"],
187192
"prefigure": ["svg"],
188-
"mermaid": ["png"],
189193
},
190194
"kindle": {
191195
"asymptote": ["png"],
192196
"latex-image": ["png"],
193197
"sageplot": ["png"],
194198
"prefigure": ["png"],
195-
"mermaid": ["png"],
196199
},
197200
"braille": {
198201
"asymptote": ["all"],
199202
"latex-image": ["all"],
200203
"sageplot": ["all"],
201-
"mermaid": ["png"],
202204
},
203205
"revealjs": {
204206
"asymptote": ["html"],
@@ -210,14 +212,12 @@
210212
"asymptote": [],
211213
"latex-image": [],
212214
"sageplot": [],
213-
"mermaid": [],
214215
},
215216
"custom": {
216217
"asymptote": ["all"],
217218
"latex-image": ["all"],
218219
"sageplot": ["all"],
219220
"prefigure": ["all"],
220-
"mermaid": ["png"],
221221
},
222222
}
223223

pretext/project/__init__.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,15 @@ class Format(str, Enum):
6161

6262

6363
# The CLI only needs two values from the publication file. Therefore, this class ignores the vast majority of a publication file's contents, loading and validating only a (small) relevant subset.
64+
# Since we will want to hash the baseurl for generating qr codes, we also load it here.
6465
class PublicationSubset(
6566
pxml.BaseXmlModel, tag="publication", search_mode=SearchMode.UNORDERED
6667
):
6768
external: Path = pxml.wrapped("source/directories", pxml.attr())
6869
generated: Path = pxml.wrapped("source/directories", pxml.attr())
70+
baseurl: t.Optional[str] = pxml.wrapped(
71+
"html/baseurl", pxml.attr(name="href", default=None)
72+
)
6973

7074

7175
class BrailleMode(str, Enum):
@@ -517,6 +521,12 @@ def generate_asset_table(self) -> pt.AssetTable:
517521
for node in source_assets:
518522
assert isinstance(node, ET._Element)
519523
hash.update(ET.tostring(node))
524+
# For QR codes, we also hash the base URL, if it exists.
525+
if asset == "qrcode":
526+
base_url = self._read_publication_file_subset().baseurl
527+
if base_url is not None:
528+
hash.update(base_url.encode("utf-8"))
529+
# Finally, we store the hash as a string in the dictionary.
520530
asset_hash_dict[asset] = hash.hexdigest()
521531
return asset_hash_dict
522532

@@ -1123,6 +1133,26 @@ def generate_assets(
11231133
log.debug(e, exc_info=True)
11241134
# youtube also requires the play button.
11251135
self.ensure_play_button()
1136+
if "qrcode" in assets_to_generate:
1137+
try:
1138+
# Warn if trying to generate qrcodes without a base URL.
1139+
base_url = self._read_publication_file_subset().baseurl
1140+
if base_url is None:
1141+
log.warning(
1142+
"You are trying to generate qrcodes, but the publication file does not have a base URL. "
1143+
+ "This will result in qrcodes that do not point to anything meaningful."
1144+
)
1145+
core.qrcode(
1146+
xml_source=self.source_abspath(),
1147+
pub_file=self.publication_abspath().as_posix(),
1148+
stringparams=stringparams_copy,
1149+
xmlid_root=xmlid,
1150+
dest_dir=self.generated_dir_abspath() / "qrcode",
1151+
)
1152+
successful_assets.append("qrcode")
1153+
except Exception as e:
1154+
log.error(f"Unable to generate some qrcodes:\n {e}")
1155+
log.debug(e, exc_info=True)
11261156
if "mermaid" in assets_to_generate:
11271157
try:
11281158
core.mermaid_images(
@@ -1162,20 +1192,6 @@ def generate_assets(
11621192
except Exception as e:
11631193
log.error(f"Unable to generate some datafiles:\n {e}")
11641194
log.debug(e, exc_info=True)
1165-
# Finally, also generate the qrcodes for interactive and youtube assets:
1166-
# NOTE: we do not currently check for success of this for saving assets to the asset cache.
1167-
if "interactive" in assets_to_generate or "youtube" in assets_to_generate:
1168-
try:
1169-
core.qrcode(
1170-
xml_source=self.source_abspath(),
1171-
pub_file=self.publication_abspath().as_posix(),
1172-
stringparams=stringparams_copy,
1173-
xmlid_root=xmlid,
1174-
dest_dir=self.generated_dir_abspath() / "qrcode",
1175-
)
1176-
except Exception as e:
1177-
log.error(f"Unable to generate some qrcodes:\n {e}", exc_info=True)
1178-
log.debug(e, exc_info=True)
11791195
# Delete temporary directories left behind by core:
11801196
try:
11811197
core.release_temporary_directories()

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ plastex = "^3"
4545
jinja2 = "^3"
4646
coloraide = "^4"
4747
pelican = { extras = ["markdown"], version = "^4.10", optional = true }
48-
prefig = { extras = ["text"], version = "^0.3.6", optional = true }
48+
prefig = { extras = ["text"], version = "^0.3.9", optional = true }
4949

5050

5151
# Development dependencies

0 commit comments

Comments
 (0)