atrep-cli 0.3.0__tar.gz → 0.3.1__tar.gz
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.
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/Cargo.lock +3 -3
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/Cargo.toml +2 -2
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/PKG-INFO +12 -7
- {atrep_cli-0.3.0/crates/atrep → atrep_cli-0.3.1}/README.md +11 -6
- {atrep_cli-0.3.0/crates/atrep-cli → atrep_cli-0.3.1/crates/atrep}/README.md +11 -6
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/endo.rs +386 -20
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-djot.at-markdown.iso +2 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-djot.dia +16 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-djot.dj.exo +4 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-docbook.dia +25 -1
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-docbook.docbook.exo +17 -1
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-html.at-rst.hom +2 -1
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-html.dia +11 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-html.html.exo +4 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-markdown.dia +11 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-markdown.md.exo +4 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-org.at-html.hom +1 -1
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-rst.dia +12 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-rst.rst.exo +4 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/litogramma.at-docbook.hom +9 -5
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/litogramma.at-html.hom +3 -2
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/litogramma.gemtext.exo +5 -3
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/djot.rs +20 -0
- atrep_cli-0.3.1/crates/atrep/tests/docbook.rs +180 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/html.rs +18 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/litogramma.rs +54 -21
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/markdown.rs +56 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/rst.rs +45 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/tasso.rs +1 -3
- {atrep_cli-0.3.0 → atrep_cli-0.3.1/crates/atrep-cli}/README.md +11 -6
- atrep_cli-0.3.0/crates/atrep/tests/docbook.rs +0 -78
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/LICENSE-APACHE +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/LICENSE-MIT +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/Cargo.toml +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/atramento.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/dendron.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/dialektos.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/error.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/exo.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/fetch.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/glossa.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/kanonizo.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/lib.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/litosis.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/morph.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/outline.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/parser.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/scan.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/sigil.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/source.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/src/zygosis.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-docbook.litogramma.hom +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-drama.dia +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-html.at-markdown.hom +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-html.at-org.hom +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-html.xhtml.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-org.dia +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-org.org.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-poesia.dia +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-prosa.dia +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-rst.at-html.hom +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-tei.dia +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-tei.tei.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-usfm.dia +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-usfm.latex.a5.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-usfm.latex.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-usfm.latex.redletter.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-usfm.latex.ru.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-usfm.osis.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-usfm.usfm.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/at-usfm.usx.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/bibliogramma.bib.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/bibliogramma.bibtex.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/bibliogramma.dia +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/koine.dia +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/koine.latex.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/litogramma.at-tei.hom +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/litogramma.dia +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/litogramma.html.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/std/litogramma.latex.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/atramento.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/attei.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/autonym.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/bibtex.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/collate.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/deixis.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/errors.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/exo.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/fixtures/base.dia +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/fixtures/child.dia +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/fixtures/exempli.html.exo +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/fixtures/exempli.lektos +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/fixtures/intro.atd +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/fixtures/pipeline.svg +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/fixtures/steps.txt +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/golden.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/jats.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/lektos.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/lex0.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/metagraphe.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/milestone.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/morph.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/org.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/outline.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/remote.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/stichoi.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/tei.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/usfm.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/vocab.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep/tests/zygo.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep-cli/Cargo.toml +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/crates/atrep-cli/src/main.rs +0 -0
- {atrep_cli-0.3.0 → atrep_cli-0.3.1}/pyproject.toml +0 -0
|
@@ -60,7 +60,7 @@ dependencies = [
|
|
|
60
60
|
|
|
61
61
|
[[package]]
|
|
62
62
|
name = "atrep"
|
|
63
|
-
version = "0.3.
|
|
63
|
+
version = "0.3.1"
|
|
64
64
|
dependencies = [
|
|
65
65
|
"flate2",
|
|
66
66
|
"serde",
|
|
@@ -73,7 +73,7 @@ dependencies = [
|
|
|
73
73
|
|
|
74
74
|
[[package]]
|
|
75
75
|
name = "atrep-cli"
|
|
76
|
-
version = "0.3.
|
|
76
|
+
version = "0.3.1"
|
|
77
77
|
dependencies = [
|
|
78
78
|
"atrep",
|
|
79
79
|
"clap",
|
|
@@ -81,7 +81,7 @@ dependencies = [
|
|
|
81
81
|
|
|
82
82
|
[[package]]
|
|
83
83
|
name = "atrep-lsp"
|
|
84
|
-
version = "0.3.
|
|
84
|
+
version = "0.3.1"
|
|
85
85
|
dependencies = [
|
|
86
86
|
"atrep",
|
|
87
87
|
"lsp-server",
|
|
@@ -3,14 +3,14 @@ resolver = "2"
|
|
|
3
3
|
members = ["crates/atrep", "crates/atrep-cli"]
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.3.
|
|
6
|
+
version = "0.3.1"
|
|
7
7
|
edition = "2024"
|
|
8
8
|
license = "MIT OR Apache-2.0"
|
|
9
9
|
authors = ["Bojan Durickovic <dev@deyanovich.org>"]
|
|
10
10
|
repository = "https://gitlab.com/atrep/atrep-rs"
|
|
11
11
|
|
|
12
12
|
[workspace.dependencies]
|
|
13
|
-
atrep = { path = "crates/atrep", version = "0.3.
|
|
13
|
+
atrep = { path = "crates/atrep", version = "0.3.1" }
|
|
14
14
|
unicode-normalization = "0.1"
|
|
15
15
|
sha2 = "0.10"
|
|
16
16
|
ureq = "3"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atrep-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: Programming Language :: Rust
|
|
@@ -262,7 +262,8 @@ Implemented:
|
|
|
262
262
|
and never across a non-injective rename onto a trigger (peer
|
|
263
263
|
triggers would share a rank the serialized form cannot
|
|
264
264
|
express; spec v0.11.1) — everywhere else `apply_route` falls
|
|
265
|
-
back to staged application automatically.
|
|
265
|
+
back to staged application automatically.
|
|
266
|
+
`atrep compose a b [c ...]` writes
|
|
266
267
|
the composite as an ordinary `.hom` file in normal form —
|
|
267
268
|
group rules in rank order, table rules sorted, implicit
|
|
268
269
|
identities elided, with `@=via` declarations recording the
|
|
@@ -280,18 +281,22 @@ Implemented:
|
|
|
280
281
|
HTML-subset, and reStructuredText-subset importers into
|
|
281
282
|
`at-markdown`/`at-html`/`at-rst` (strict over the canonical
|
|
282
283
|
subsets; RST footnotes become deixis callouts, fixed adornment
|
|
283
|
-
table for title levels
|
|
284
|
-
|
|
285
|
-
|
|
284
|
+
table for title levels, hyperlink references with embedded
|
|
285
|
+
URIs as the visible-URL link), Org-mode and Djot subset
|
|
286
|
+
importers into the `at-org` and `at-djot` std dialektoi, a
|
|
287
|
+
DocBook subset importer into `at-docbook` (`.dbk`; quote and
|
|
288
|
+
link included); the `at-tei` std dialektos
|
|
286
289
|
applies the bibliogramma pattern to TEI — ~15 form sims with
|
|
287
290
|
the TEI element identity in vocabulary-bound genoses
|
|
288
291
|
(`@,x,@.persname`), a `tei` exo emitting real TEI XML, and a
|
|
289
|
-
litogramma hom giving litogramma TEI export via morph+exo, a
|
|
292
|
+
litogramma hom giving litogramma TEI export via morph+exo, a
|
|
293
|
+
BibTeX importer into
|
|
290
294
|
`bibliogramma` (`.bib`), a JATS subset importer (`.jats`) into
|
|
291
295
|
litogramma with the ref-list embedded as a bibliogramma
|
|
292
296
|
englossis — the BibTeX-isomorphic bibliography
|
|
293
297
|
extension defined beside litogramma (entry lemma = citation
|
|
294
|
-
key, genos = entry type, fields as lemma-named sims) — the
|
|
298
|
+
key, genos = entry type, fields as lemma-named sims) — the
|
|
299
|
+
first *nested* std
|
|
295
300
|
dialektos: one uniform section sim nests, so
|
|
296
301
|
structure-preserving morphisms to and from litogramma need
|
|
297
302
|
no flattening — (`.org`: star headings, the emphasis
|
|
@@ -245,7 +245,8 @@ Implemented:
|
|
|
245
245
|
and never across a non-injective rename onto a trigger (peer
|
|
246
246
|
triggers would share a rank the serialized form cannot
|
|
247
247
|
express; spec v0.11.1) — everywhere else `apply_route` falls
|
|
248
|
-
back to staged application automatically.
|
|
248
|
+
back to staged application automatically.
|
|
249
|
+
`atrep compose a b [c ...]` writes
|
|
249
250
|
the composite as an ordinary `.hom` file in normal form —
|
|
250
251
|
group rules in rank order, table rules sorted, implicit
|
|
251
252
|
identities elided, with `@=via` declarations recording the
|
|
@@ -263,18 +264,22 @@ Implemented:
|
|
|
263
264
|
HTML-subset, and reStructuredText-subset importers into
|
|
264
265
|
`at-markdown`/`at-html`/`at-rst` (strict over the canonical
|
|
265
266
|
subsets; RST footnotes become deixis callouts, fixed adornment
|
|
266
|
-
table for title levels
|
|
267
|
-
|
|
268
|
-
|
|
267
|
+
table for title levels, hyperlink references with embedded
|
|
268
|
+
URIs as the visible-URL link), Org-mode and Djot subset
|
|
269
|
+
importers into the `at-org` and `at-djot` std dialektoi, a
|
|
270
|
+
DocBook subset importer into `at-docbook` (`.dbk`; quote and
|
|
271
|
+
link included); the `at-tei` std dialektos
|
|
269
272
|
applies the bibliogramma pattern to TEI — ~15 form sims with
|
|
270
273
|
the TEI element identity in vocabulary-bound genoses
|
|
271
274
|
(`@,x,@.persname`), a `tei` exo emitting real TEI XML, and a
|
|
272
|
-
litogramma hom giving litogramma TEI export via morph+exo, a
|
|
275
|
+
litogramma hom giving litogramma TEI export via morph+exo, a
|
|
276
|
+
BibTeX importer into
|
|
273
277
|
`bibliogramma` (`.bib`), a JATS subset importer (`.jats`) into
|
|
274
278
|
litogramma with the ref-list embedded as a bibliogramma
|
|
275
279
|
englossis — the BibTeX-isomorphic bibliography
|
|
276
280
|
extension defined beside litogramma (entry lemma = citation
|
|
277
|
-
key, genos = entry type, fields as lemma-named sims) — the
|
|
281
|
+
key, genos = entry type, fields as lemma-named sims) — the
|
|
282
|
+
first *nested* std
|
|
278
283
|
dialektos: one uniform section sim nests, so
|
|
279
284
|
structure-preserving morphisms to and from litogramma need
|
|
280
285
|
no flattening — (`.org`: star headings, the emphasis
|
|
@@ -245,7 +245,8 @@ Implemented:
|
|
|
245
245
|
and never across a non-injective rename onto a trigger (peer
|
|
246
246
|
triggers would share a rank the serialized form cannot
|
|
247
247
|
express; spec v0.11.1) — everywhere else `apply_route` falls
|
|
248
|
-
back to staged application automatically.
|
|
248
|
+
back to staged application automatically.
|
|
249
|
+
`atrep compose a b [c ...]` writes
|
|
249
250
|
the composite as an ordinary `.hom` file in normal form —
|
|
250
251
|
group rules in rank order, table rules sorted, implicit
|
|
251
252
|
identities elided, with `@=via` declarations recording the
|
|
@@ -263,18 +264,22 @@ Implemented:
|
|
|
263
264
|
HTML-subset, and reStructuredText-subset importers into
|
|
264
265
|
`at-markdown`/`at-html`/`at-rst` (strict over the canonical
|
|
265
266
|
subsets; RST footnotes become deixis callouts, fixed adornment
|
|
266
|
-
table for title levels
|
|
267
|
-
|
|
268
|
-
|
|
267
|
+
table for title levels, hyperlink references with embedded
|
|
268
|
+
URIs as the visible-URL link), Org-mode and Djot subset
|
|
269
|
+
importers into the `at-org` and `at-djot` std dialektoi, a
|
|
270
|
+
DocBook subset importer into `at-docbook` (`.dbk`; quote and
|
|
271
|
+
link included); the `at-tei` std dialektos
|
|
269
272
|
applies the bibliogramma pattern to TEI — ~15 form sims with
|
|
270
273
|
the TEI element identity in vocabulary-bound genoses
|
|
271
274
|
(`@,x,@.persname`), a `tei` exo emitting real TEI XML, and a
|
|
272
|
-
litogramma hom giving litogramma TEI export via morph+exo, a
|
|
275
|
+
litogramma hom giving litogramma TEI export via morph+exo, a
|
|
276
|
+
BibTeX importer into
|
|
273
277
|
`bibliogramma` (`.bib`), a JATS subset importer (`.jats`) into
|
|
274
278
|
litogramma with the ref-list embedded as a bibliogramma
|
|
275
279
|
englossis — the BibTeX-isomorphic bibliography
|
|
276
280
|
extension defined beside litogramma (entry lemma = citation
|
|
277
|
-
key, genos = entry type, fields as lemma-named sims) — the
|
|
281
|
+
key, genos = entry type, fields as lemma-named sims) — the
|
|
282
|
+
first *nested* std
|
|
278
283
|
dialektos: one uniform section sim nests, so
|
|
279
284
|
structure-preserving morphisms to and from litogramma need
|
|
280
285
|
no flattening — (`.org`: star headings, the emphasis
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
//! at-markdown models - ATX headings, paragraphs, blockquotes,
|
|
10
10
|
//! flat list items, fenced code (info string becomes a genos),
|
|
11
11
|
//! standalone images, emphasis/strong, code spans, backslash
|
|
12
|
-
//! escapes
|
|
12
|
+
//! escapes, and the footnote extension (`[^name]` callouts as
|
|
13
|
+
//! deixes, `[^name]: body` definitions as footnote bodies).
|
|
13
14
|
//! - HTML into `at-html`: the canonical subset the at-html syntax
|
|
14
15
|
//! mapper models - h1-h6, p, em, strong, span/div (class maps
|
|
15
16
|
//! to genoses), blockquote, ul/ol/li, pre>code, inline code,
|
|
@@ -142,6 +143,29 @@ fn parse_blocks(lines: &[&str]) -> Result<Vec<Block>> {
|
|
|
142
143
|
continue;
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
// Footnote definition `[^name]: body` (the footnote
|
|
147
|
+
// extension); continuation lines indent four spaces.
|
|
148
|
+
if let Some(after) = line.strip_prefix("[^")
|
|
149
|
+
&& let Some((name, body)) = after.split_once("]: ")
|
|
150
|
+
&& !name.is_empty()
|
|
151
|
+
{
|
|
152
|
+
let (children, next) = item_content(lines, i, body, " ")?;
|
|
153
|
+
blocks.push(Block::Para {
|
|
154
|
+
symbol: "^".to_string(),
|
|
155
|
+
taxis: None,
|
|
156
|
+
lemma: vec![],
|
|
157
|
+
children,
|
|
158
|
+
hypograph: vec![],
|
|
159
|
+
bracket_matching: true,
|
|
160
|
+
ann: Annotations {
|
|
161
|
+
onym: Some(name.to_string()),
|
|
162
|
+
genoses: vec![],
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
i = next;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
|
|
145
169
|
// Standalone image: enmedia.
|
|
146
170
|
if let Some(target) = line
|
|
147
171
|
.trim_end()
|
|
@@ -225,6 +249,39 @@ fn ordered_marker(line: &str) -> Option<(u64, &str)> {
|
|
|
225
249
|
|
|
226
250
|
/// Parse inline Markdown: code spans, strong, emphasis, backslash
|
|
227
251
|
/// escapes. Unclosed delimiters fall back to literal text.
|
|
252
|
+
/// The visible-URL link endo: the grammata IS the displayed
|
|
253
|
+
/// target (the link sim's own doctrine). Hidden-href sources
|
|
254
|
+
/// project to prose text with this beside it, pending F9.
|
|
255
|
+
fn link_endo(url: String) -> Inline {
|
|
256
|
+
Inline::Endo {
|
|
257
|
+
symbol: "><".to_string(),
|
|
258
|
+
content: vec![Inline::Text(url)],
|
|
259
|
+
bracket_matching: true,
|
|
260
|
+
ann: Annotations::default(),
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/// A CommonMark-shaped autolink at `chars[open] == '<'`: an
|
|
265
|
+
/// absolute URI (ASCII-alphabetic scheme, then `:`), no
|
|
266
|
+
/// whitespace or `<` inside, closed by `>`. Returns the URI and
|
|
267
|
+
/// the index past the closing `>`.
|
|
268
|
+
fn autolink_target(chars: &[char], open: usize) -> Option<(String, usize)> {
|
|
269
|
+
let close = chars[open + 1..].iter().position(|&c| c == '>')? + open + 1;
|
|
270
|
+
let inner: String = chars[open + 1..close].iter().collect();
|
|
271
|
+
if inner.is_empty() || inner.chars().any(|c| c.is_whitespace() || c == '<') {
|
|
272
|
+
return None;
|
|
273
|
+
}
|
|
274
|
+
let (scheme, rest) = inner.split_once(':')?;
|
|
275
|
+
let mut sc = scheme.chars();
|
|
276
|
+
if !sc.next().is_some_and(|c| c.is_ascii_alphabetic())
|
|
277
|
+
|| !sc.all(|c| c.is_ascii_alphanumeric() || matches!(c, '+' | '.' | '-'))
|
|
278
|
+
|| rest.is_empty()
|
|
279
|
+
{
|
|
280
|
+
return None;
|
|
281
|
+
}
|
|
282
|
+
Some((inner, close + 1))
|
|
283
|
+
}
|
|
284
|
+
|
|
228
285
|
fn parse_inline(text: &str) -> Vec<Inline> {
|
|
229
286
|
let chars: Vec<char> = text.chars().collect();
|
|
230
287
|
let mut inlines: Vec<Inline> = Vec::new();
|
|
@@ -260,6 +317,61 @@ fn parse_inline(text: &str) -> Vec<Inline> {
|
|
|
260
317
|
i = close + 1;
|
|
261
318
|
continue;
|
|
262
319
|
}
|
|
320
|
+
// Footnote callout `[^name]` (the footnote extension).
|
|
321
|
+
if c == '['
|
|
322
|
+
&& chars.get(i + 1) == Some(&'^')
|
|
323
|
+
&& let Some(close) = find(&chars, i + 2, &[']'])
|
|
324
|
+
{
|
|
325
|
+
flush(&mut lit, &mut inlines);
|
|
326
|
+
inlines.push(Inline::Deixis {
|
|
327
|
+
symbol: "^".to_string(),
|
|
328
|
+
onym: chars[i + 2..close].iter().collect(),
|
|
329
|
+
ann: Annotations::default(),
|
|
330
|
+
});
|
|
331
|
+
i = close + 1;
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
// Autolink `<URL>` — the visible-URL link: the target IS
|
|
335
|
+
// the display, exactly the link sim's shape.
|
|
336
|
+
if c == '<'
|
|
337
|
+
&& let Some((url, next)) = autolink_target(&chars, i)
|
|
338
|
+
{
|
|
339
|
+
flush(&mut lit, &mut inlines);
|
|
340
|
+
inlines.push(link_endo(url));
|
|
341
|
+
i = next;
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
// Inline link `[text](url)`: a hidden href. The faithful
|
|
345
|
+
// form waits on F9; meanwhile the org projection applies —
|
|
346
|
+
// the text stays prose with the visible URL beside it,
|
|
347
|
+
// `text (url)`, and nothing is lost. (An image's `![` is
|
|
348
|
+
// not a link; nested brackets are outside the subset.)
|
|
349
|
+
if c == '['
|
|
350
|
+
&& (i == 0 || chars[i - 1] != '!')
|
|
351
|
+
&& let Some(close) = find(&chars, i + 1, &[']'])
|
|
352
|
+
&& chars.get(close + 1) == Some(&'(')
|
|
353
|
+
&& let Some(end) = find(&chars, close + 2, &[')'])
|
|
354
|
+
{
|
|
355
|
+
let text: String = chars[i + 1..close].iter().collect();
|
|
356
|
+
let url: String = chars[close + 2..end]
|
|
357
|
+
.iter()
|
|
358
|
+
.collect::<String>()
|
|
359
|
+
.trim()
|
|
360
|
+
.to_string();
|
|
361
|
+
flush(&mut lit, &mut inlines);
|
|
362
|
+
if url.is_empty() {
|
|
363
|
+
inlines.extend(parse_inline(&text));
|
|
364
|
+
} else if text.trim().is_empty() || text.trim() == url {
|
|
365
|
+
inlines.push(link_endo(url));
|
|
366
|
+
} else {
|
|
367
|
+
inlines.extend(parse_inline(&text));
|
|
368
|
+
inlines.push(Inline::Text(" (".to_string()));
|
|
369
|
+
inlines.push(link_endo(url));
|
|
370
|
+
inlines.push(Inline::Text(")".to_string()));
|
|
371
|
+
}
|
|
372
|
+
i = end + 1;
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
263
375
|
// Strong, then emphasis.
|
|
264
376
|
if c == '*' {
|
|
265
377
|
let strong = chars.get(i + 1) == Some(&'*');
|
|
@@ -862,6 +974,35 @@ fn parse_html_inlines(
|
|
|
862
974
|
ann: Annotations::default(),
|
|
863
975
|
});
|
|
864
976
|
}
|
|
977
|
+
"a" => {
|
|
978
|
+
// The visible-URL link: an anchor whose text
|
|
979
|
+
// is its target (or none) is the link sim
|
|
980
|
+
// exactly; a hidden href projects as prose
|
|
981
|
+
// text with the visible URL beside it — the
|
|
982
|
+
// org projection, pending F9's faithful form.
|
|
983
|
+
let href = attr(attrs, "href")
|
|
984
|
+
.map(|h| h.trim().to_string())
|
|
985
|
+
.unwrap_or_default();
|
|
986
|
+
let (content, next) = parse_html_inlines(toks, i + 1, name, breaks)?;
|
|
987
|
+
if href.is_empty() {
|
|
988
|
+
inlines.extend(content);
|
|
989
|
+
} else {
|
|
990
|
+
let visible = match content.as_slice() {
|
|
991
|
+
[] => true,
|
|
992
|
+
[Inline::Text(t)] => t.trim() == href,
|
|
993
|
+
_ => false,
|
|
994
|
+
};
|
|
995
|
+
if visible {
|
|
996
|
+
inlines.push(link_endo(href));
|
|
997
|
+
} else {
|
|
998
|
+
inlines.extend(content);
|
|
999
|
+
inlines.push(Inline::Text(" (".to_string()));
|
|
1000
|
+
inlines.push(link_endo(href));
|
|
1001
|
+
inlines.push(Inline::Text(")".to_string()));
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
i = next;
|
|
1005
|
+
}
|
|
865
1006
|
other => {
|
|
866
1007
|
return Err(html_err(format!("unsupported inline element: `<{other}>`")));
|
|
867
1008
|
}
|
|
@@ -1193,6 +1334,32 @@ fn parse_rst_inline(text: &str) -> Vec<Inline> {
|
|
|
1193
1334
|
i = close + 2;
|
|
1194
1335
|
continue;
|
|
1195
1336
|
}
|
|
1337
|
+
// Hyperlink reference with embedded URI, `text <url>`_ (or
|
|
1338
|
+
// anonymous, `__). Text equal to the URL, or absent, is the
|
|
1339
|
+
// visible-URL link sim exactly; distinct text projects as
|
|
1340
|
+
// prose with the visible URL beside it, pending F9. Named
|
|
1341
|
+
// references without a URI stay literal, as do bare URLs.
|
|
1342
|
+
if c == '`'
|
|
1343
|
+
&& chars.get(i + 1) != Some(&'`')
|
|
1344
|
+
&& let Some(close) = find(&chars, i + 1, &['`', '_'])
|
|
1345
|
+
&& let Some((text, url)) = rst_embedded_uri(&chars[i + 1..close])
|
|
1346
|
+
{
|
|
1347
|
+
flush(&mut lit, &mut inlines);
|
|
1348
|
+
let text = text.trim();
|
|
1349
|
+
if text.is_empty() || text == url {
|
|
1350
|
+
inlines.push(link_endo(url));
|
|
1351
|
+
} else {
|
|
1352
|
+
inlines.extend(parse_rst_inline(text));
|
|
1353
|
+
inlines.push(Inline::Text(" (".to_string()));
|
|
1354
|
+
inlines.push(link_endo(url));
|
|
1355
|
+
inlines.push(Inline::Text(")".to_string()));
|
|
1356
|
+
}
|
|
1357
|
+
i = close + 2;
|
|
1358
|
+
if chars.get(i) == Some(&'_') {
|
|
1359
|
+
i += 1;
|
|
1360
|
+
}
|
|
1361
|
+
continue;
|
|
1362
|
+
}
|
|
1196
1363
|
// Strong, then emphasis.
|
|
1197
1364
|
if c == '*' {
|
|
1198
1365
|
let strong = chars.get(i + 1) == Some(&'*');
|
|
@@ -1239,6 +1406,27 @@ fn parse_rst_inline(text: &str) -> Vec<Inline> {
|
|
|
1239
1406
|
|
|
1240
1407
|
/// A choice element: prefer the regularized reading
|
|
1241
1408
|
/// (expan/corr/reg) over the source form (abbr/sic/orig).
|
|
1409
|
+
/// Split the inside of a `` `...`_ `` reference into (text, URI)
|
|
1410
|
+
/// when it carries an embedded URI: `text <uri>` with the angle
|
|
1411
|
+
/// group last and preceded by whitespace (or standing alone). A
|
|
1412
|
+
/// `<name_>` alias, whitespace inside the target, or a stray
|
|
1413
|
+
/// backtick disqualifies it.
|
|
1414
|
+
fn rst_embedded_uri(inner: &[char]) -> Option<(String, String)> {
|
|
1415
|
+
if inner.last() != Some(&'>') || inner.contains(&'`') {
|
|
1416
|
+
return None;
|
|
1417
|
+
}
|
|
1418
|
+
let open = inner.iter().rposition(|&c| c == '<')?;
|
|
1419
|
+
if open > 0 && !inner[open - 1].is_whitespace() {
|
|
1420
|
+
return None;
|
|
1421
|
+
}
|
|
1422
|
+
let url: String = inner[open + 1..inner.len() - 1].iter().collect();
|
|
1423
|
+
if url.is_empty() || url.chars().any(char::is_whitespace) || url.ends_with('_') {
|
|
1424
|
+
return None;
|
|
1425
|
+
}
|
|
1426
|
+
let text: String = inner[..open].iter().collect();
|
|
1427
|
+
Some((text, url))
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1242
1430
|
fn tei_choice(toks: &[Tok], mut i: usize, notes: &mut usize) -> Result<(Vec<Inline>, usize)> {
|
|
1243
1431
|
let mut preferred: Vec<Inline> = Vec::new();
|
|
1244
1432
|
let mut fallback: Vec<Inline> = Vec::new();
|
|
@@ -4775,6 +4963,48 @@ fn djot_inlines(text: &str) -> Result<Vec<Inline>> {
|
|
|
4775
4963
|
i = end + 1;
|
|
4776
4964
|
continue;
|
|
4777
4965
|
}
|
|
4966
|
+
// Autolink `<URL>` — the visible-URL link.
|
|
4967
|
+
if c == '<'
|
|
4968
|
+
&& let Some((url, next)) = autolink_target(&chars, i)
|
|
4969
|
+
{
|
|
4970
|
+
flush_plain(&mut plain, &mut inlines);
|
|
4971
|
+
inlines.push(link_endo(url));
|
|
4972
|
+
i = next;
|
|
4973
|
+
continue;
|
|
4974
|
+
}
|
|
4975
|
+
// Inline link `[text](url)`: the org projection, as in
|
|
4976
|
+
// at-markdown (the iso pair reads links identically).
|
|
4977
|
+
if c == '['
|
|
4978
|
+
&& (i == 0 || chars[i - 1] != '!')
|
|
4979
|
+
&& chars.get(i + 1) != Some(&'^')
|
|
4980
|
+
&& let Some(rel) = chars[i + 1..].iter().position(|&ch| ch == ']')
|
|
4981
|
+
{
|
|
4982
|
+
let close = i + 1 + rel;
|
|
4983
|
+
if chars.get(close + 1) == Some(&'(')
|
|
4984
|
+
&& let Some(rel2) = chars[close + 2..].iter().position(|&ch| ch == ')')
|
|
4985
|
+
{
|
|
4986
|
+
let end = close + 2 + rel2;
|
|
4987
|
+
let text: String = chars[i + 1..close].iter().collect();
|
|
4988
|
+
let url: String = chars[close + 2..end]
|
|
4989
|
+
.iter()
|
|
4990
|
+
.collect::<String>()
|
|
4991
|
+
.trim()
|
|
4992
|
+
.to_string();
|
|
4993
|
+
flush_plain(&mut plain, &mut inlines);
|
|
4994
|
+
if url.is_empty() {
|
|
4995
|
+
inlines.extend(djot_inlines(&text)?);
|
|
4996
|
+
} else if text.trim().is_empty() || text.trim() == url {
|
|
4997
|
+
inlines.push(link_endo(url));
|
|
4998
|
+
} else {
|
|
4999
|
+
inlines.extend(djot_inlines(&text)?);
|
|
5000
|
+
inlines.push(Inline::Text(" (".to_string()));
|
|
5001
|
+
inlines.push(link_endo(url));
|
|
5002
|
+
inlines.push(Inline::Text(")".to_string()));
|
|
5003
|
+
}
|
|
5004
|
+
i = end + 1;
|
|
5005
|
+
continue;
|
|
5006
|
+
}
|
|
5007
|
+
}
|
|
4778
5008
|
plain.push(c);
|
|
4779
5009
|
i += 1;
|
|
4780
5010
|
}
|
|
@@ -4807,7 +5037,17 @@ pub fn docbook_to_document(xml: &str) -> Result<Document> {
|
|
|
4807
5037
|
match &toks[i] {
|
|
4808
5038
|
Tok::Text(t) if t.trim().is_empty() => i += 1,
|
|
4809
5039
|
Tok::Open { name, .. } if name == "article" || name == "book" || name == "chapter" => {
|
|
4810
|
-
let (inner, next) = docbook_blocks(&toks, i + 1, name.clone(), &mut notes)?;
|
|
5040
|
+
let (mut inner, next) = docbook_blocks(&toks, i + 1, name.clone(), &mut notes)?;
|
|
5041
|
+
// The root's leading title (bare, or from <info>)
|
|
5042
|
+
// is the document title, standing alone first.
|
|
5043
|
+
if let Some(content) = docbook_take_title(&mut inner) {
|
|
5044
|
+
blocks.push(Block::Paragraph(vec![Inline::Endo {
|
|
5045
|
+
symbol: "=".to_string(),
|
|
5046
|
+
content,
|
|
5047
|
+
bracket_matching: true,
|
|
5048
|
+
ann: Annotations::default(),
|
|
5049
|
+
}]));
|
|
5050
|
+
}
|
|
4811
5051
|
blocks.extend(inner);
|
|
4812
5052
|
i = next;
|
|
4813
5053
|
}
|
|
@@ -4818,6 +5058,7 @@ pub fn docbook_to_document(xml: &str) -> Result<Document> {
|
|
|
4818
5058
|
}
|
|
4819
5059
|
}
|
|
4820
5060
|
}
|
|
5061
|
+
docbook_settle_titles(&mut blocks);
|
|
4821
5062
|
Ok(Document {
|
|
4822
5063
|
dialect_id: "at-docbook".to_string(),
|
|
4823
5064
|
dialect_version: None,
|
|
@@ -4825,6 +5066,50 @@ pub fn docbook_to_document(xml: &str) -> Result<Document> {
|
|
|
4825
5066
|
})
|
|
4826
5067
|
}
|
|
4827
5068
|
|
|
5069
|
+
/// The sentinel symbol a `<title>` carries until its container
|
|
5070
|
+
/// claims it (section lemma, document title).
|
|
5071
|
+
const DOCBOOK_TITLE: &str = "\u{0}title";
|
|
5072
|
+
|
|
5073
|
+
/// Take a leading sentinel title paragraph off a block run.
|
|
5074
|
+
fn docbook_take_title(blocks: &mut Vec<Block>) -> Option<Vec<Inline>> {
|
|
5075
|
+
match blocks.first() {
|
|
5076
|
+
Some(Block::Paragraph(inlines))
|
|
5077
|
+
if matches!(inlines.first(),
|
|
5078
|
+
Some(Inline::Endo { symbol, .. }) if symbol == DOCBOOK_TITLE) => {}
|
|
5079
|
+
_ => return None,
|
|
5080
|
+
}
|
|
5081
|
+
let Block::Paragraph(mut inlines) = blocks.remove(0) else {
|
|
5082
|
+
unreachable!()
|
|
5083
|
+
};
|
|
5084
|
+
let Some(Inline::Endo { content, .. }) = inlines.pop() else {
|
|
5085
|
+
unreachable!()
|
|
5086
|
+
};
|
|
5087
|
+
Some(content)
|
|
5088
|
+
}
|
|
5089
|
+
|
|
5090
|
+
/// A `<title>` no container claimed (inside a blockquote, an
|
|
5091
|
+
/// admonition, a list) is a caption: it settles as a plain
|
|
5092
|
+
/// paragraph of its text rather than leaking the sentinel.
|
|
5093
|
+
fn docbook_settle_titles(blocks: &mut [Block]) {
|
|
5094
|
+
for block in blocks.iter_mut() {
|
|
5095
|
+
match block {
|
|
5096
|
+
Block::Paragraph(inlines) => {
|
|
5097
|
+
if let [
|
|
5098
|
+
Inline::Endo {
|
|
5099
|
+
symbol, content, ..
|
|
5100
|
+
},
|
|
5101
|
+
] = inlines.as_mut_slice()
|
|
5102
|
+
&& symbol == DOCBOOK_TITLE
|
|
5103
|
+
{
|
|
5104
|
+
*inlines = std::mem::take(content);
|
|
5105
|
+
}
|
|
5106
|
+
}
|
|
5107
|
+
Block::Para { children, .. } => docbook_settle_titles(children),
|
|
5108
|
+
_ => {}
|
|
5109
|
+
}
|
|
5110
|
+
}
|
|
5111
|
+
}
|
|
5112
|
+
|
|
4828
5113
|
fn docbook_blocks(
|
|
4829
5114
|
toks: &[Tok],
|
|
4830
5115
|
mut i: usize,
|
|
@@ -4843,14 +5128,53 @@ fn docbook_blocks(
|
|
|
4843
5128
|
)));
|
|
4844
5129
|
}
|
|
4845
5130
|
Tok::Open { name, .. } if name == "info" => {
|
|
4846
|
-
|
|
5131
|
+
// Metadata is skipped, except the title, which
|
|
5132
|
+
// rides the sentinel like a bare <title>.
|
|
5133
|
+
i += 1;
|
|
5134
|
+
loop {
|
|
5135
|
+
match toks.get(i) {
|
|
5136
|
+
None => return Err(docbook_err("unterminated <info>".into())),
|
|
5137
|
+
Some(Tok::Close(name)) if name == "info" => {
|
|
5138
|
+
i += 1;
|
|
5139
|
+
break;
|
|
5140
|
+
}
|
|
5141
|
+
Some(Tok::Open {
|
|
5142
|
+
name, self_closing, ..
|
|
5143
|
+
}) if name == "title" => {
|
|
5144
|
+
if *self_closing {
|
|
5145
|
+
i += 1;
|
|
5146
|
+
continue;
|
|
5147
|
+
}
|
|
5148
|
+
let ((content, inner), next) =
|
|
5149
|
+
docbook_inline_run(toks, i + 1, "title", notes)?;
|
|
5150
|
+
blocks.push(Block::Paragraph(vec![Inline::Endo {
|
|
5151
|
+
symbol: DOCBOOK_TITLE.to_string(),
|
|
5152
|
+
content,
|
|
5153
|
+
bracket_matching: true,
|
|
5154
|
+
ann: Annotations::default(),
|
|
5155
|
+
}]));
|
|
5156
|
+
blocks.extend(inner);
|
|
5157
|
+
i = next;
|
|
5158
|
+
}
|
|
5159
|
+
Some(Tok::Open {
|
|
5160
|
+
name, self_closing, ..
|
|
5161
|
+
}) => {
|
|
5162
|
+
i = if *self_closing {
|
|
5163
|
+
i + 1
|
|
5164
|
+
} else {
|
|
5165
|
+
skip_element(toks, i + 1, name.clone())?
|
|
5166
|
+
};
|
|
5167
|
+
}
|
|
5168
|
+
Some(_) => i += 1,
|
|
5169
|
+
}
|
|
5170
|
+
}
|
|
4847
5171
|
}
|
|
4848
5172
|
Tok::Open { name, .. } if name == "title" => {
|
|
4849
|
-
// Sentinel-wrapped; the enclosing section
|
|
4850
|
-
// promotes it to the lemma.
|
|
5173
|
+
// Sentinel-wrapped; the enclosing section (or the
|
|
5174
|
+
// root) promotes it to the lemma (or the title).
|
|
4851
5175
|
let ((content, inner), next) = docbook_inline_run(toks, i + 1, "title", notes)?;
|
|
4852
5176
|
blocks.push(Block::Paragraph(vec![Inline::Endo {
|
|
4853
|
-
symbol:
|
|
5177
|
+
symbol: DOCBOOK_TITLE.to_string(),
|
|
4854
5178
|
content,
|
|
4855
5179
|
bracket_matching: true,
|
|
4856
5180
|
ann: Annotations::default(),
|
|
@@ -4863,20 +5187,8 @@ fn docbook_blocks(
|
|
|
4863
5187
|
let n = name.clone();
|
|
4864
5188
|
let (mut children, next) = docbook_blocks(toks, i + 1, n, notes)?;
|
|
4865
5189
|
// The leading title paragraph becomes the lemma.
|
|
4866
|
-
let lemma =
|
|
4867
|
-
|
|
4868
|
-
if matches!(inlines.first(),
|
|
4869
|
-
Some(Inline::Endo { symbol, .. }) if symbol == "\u{0}title") =>
|
|
4870
|
-
{
|
|
4871
|
-
let Some(Block::Paragraph(mut inlines)) = Some(children.remove(0)) else {
|
|
4872
|
-
unreachable!()
|
|
4873
|
-
};
|
|
4874
|
-
let Some(Inline::Endo { content, .. }) = inlines.pop() else {
|
|
4875
|
-
unreachable!()
|
|
4876
|
-
};
|
|
4877
|
-
content
|
|
4878
|
-
}
|
|
4879
|
-
_ => return Err(docbook_err("section without a title".into())),
|
|
5190
|
+
let Some(lemma) = docbook_take_title(&mut children) else {
|
|
5191
|
+
return Err(docbook_err("section without a title".into()));
|
|
4880
5192
|
};
|
|
4881
5193
|
blocks.push(Block::Para {
|
|
4882
5194
|
symbol: "#".to_string(),
|
|
@@ -5094,6 +5406,60 @@ fn docbook_inline_run(
|
|
|
5094
5406
|
});
|
|
5095
5407
|
i = next;
|
|
5096
5408
|
}
|
|
5409
|
+
Tok::Open { name, .. } if name == "quote" => {
|
|
5410
|
+
let ((content, inner), next) = docbook_inline_run(toks, i + 1, "quote", notes)?;
|
|
5411
|
+
inlines.push(Inline::Endo {
|
|
5412
|
+
symbol: "\"\"".to_string(),
|
|
5413
|
+
content,
|
|
5414
|
+
bracket_matching: true,
|
|
5415
|
+
ann: Annotations::default(),
|
|
5416
|
+
});
|
|
5417
|
+
bodies.extend(inner);
|
|
5418
|
+
i = next;
|
|
5419
|
+
}
|
|
5420
|
+
Tok::Open {
|
|
5421
|
+
name,
|
|
5422
|
+
attrs,
|
|
5423
|
+
self_closing,
|
|
5424
|
+
..
|
|
5425
|
+
} if name == "link" || name == "ulink" => {
|
|
5426
|
+
// The visible-URL link: a DocBook 5 xlink:href (or
|
|
5427
|
+
// DocBook 4 ulink url) whose text is its target, or
|
|
5428
|
+
// none, is the link sim exactly; a hidden href
|
|
5429
|
+
// projects as prose text with the visible URL beside
|
|
5430
|
+
// it — the html projection, pending F9's faithful
|
|
5431
|
+
// form. An internal linkend has no URL: prose only.
|
|
5432
|
+
let url = attr(attrs, "xlink:href")
|
|
5433
|
+
.or_else(|| attr(attrs, "url"))
|
|
5434
|
+
.map(|u| u.trim().to_string())
|
|
5435
|
+
.unwrap_or_default();
|
|
5436
|
+
let (content, next) = if *self_closing {
|
|
5437
|
+
(Vec::new(), i + 1)
|
|
5438
|
+
} else {
|
|
5439
|
+
let n = name.clone();
|
|
5440
|
+
let ((content, inner), next) = docbook_inline_run(toks, i + 1, &n, notes)?;
|
|
5441
|
+
bodies.extend(inner);
|
|
5442
|
+
(content, next)
|
|
5443
|
+
};
|
|
5444
|
+
if url.is_empty() {
|
|
5445
|
+
inlines.extend(content);
|
|
5446
|
+
} else {
|
|
5447
|
+
let visible = match content.as_slice() {
|
|
5448
|
+
[] => true,
|
|
5449
|
+
[Inline::Text(t)] => t.trim() == url,
|
|
5450
|
+
_ => false,
|
|
5451
|
+
};
|
|
5452
|
+
if visible {
|
|
5453
|
+
inlines.push(link_endo(url));
|
|
5454
|
+
} else {
|
|
5455
|
+
inlines.extend(content);
|
|
5456
|
+
inlines.push(Inline::Text(" (".to_string()));
|
|
5457
|
+
inlines.push(link_endo(url));
|
|
5458
|
+
inlines.push(Inline::Text(")".to_string()));
|
|
5459
|
+
}
|
|
5460
|
+
}
|
|
5461
|
+
i = next;
|
|
5462
|
+
}
|
|
5097
5463
|
other => return Err(docbook_err(format!("unsupported {other:?} inline"))),
|
|
5098
5464
|
}
|
|
5099
5465
|
}
|