pandoc-para 0.2.0__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.
- pandoc_para-0.2.0/.gitignore +33 -0
- pandoc_para-0.2.0/AUTHORS.rst +5 -0
- pandoc_para-0.2.0/CHANGELOG.md +48 -0
- pandoc_para-0.2.0/LICENSE +29 -0
- pandoc_para-0.2.0/PKG-INFO +69 -0
- pandoc_para-0.2.0/README.md +27 -0
- pandoc_para-0.2.0/docs/makefile +15 -0
- pandoc_para-0.2.0/docs/pages/builds.md +89 -0
- pandoc_para-0.2.0/docs/pages/configuration.md +57 -0
- pandoc_para-0.2.0/docs/pages/filters.md +67 -0
- pandoc_para-0.2.0/docs/pages/front-matter.md +38 -0
- pandoc_para-0.2.0/docs/pages/index.md +63 -0
- pandoc_para-0.2.0/docs/pages/install.md +46 -0
- pandoc_para-0.2.0/docs/pages/languages.md +54 -0
- pandoc_para-0.2.0/docs/pages/migrating.md +42 -0
- pandoc_para-0.2.0/docs/pages/profiles.md +90 -0
- pandoc_para-0.2.0/docs/pages/reference.md +248 -0
- pandoc_para-0.2.0/docs/parasite.toml +50 -0
- pandoc_para-0.2.0/pyproject.toml +175 -0
- pandoc_para-0.2.0/src/para/__init__.py +1 -0
- pandoc_para-0.2.0/src/para/__main__.py +3 -0
- pandoc_para-0.2.0/src/para/apps.py +315 -0
- pandoc_para-0.2.0/src/para/check.py +52 -0
- pandoc_para-0.2.0/src/para/config.py +411 -0
- pandoc_para-0.2.0/src/para/data.py +438 -0
- pandoc_para-0.2.0/src/para/defaults.toml +237 -0
- pandoc_para-0.2.0/src/para/deps.py +121 -0
- pandoc_para-0.2.0/src/para/filters.py +184 -0
- pandoc_para-0.2.0/src/para/graph.py +116 -0
- pandoc_para-0.2.0/src/para/helpers.py +198 -0
- pandoc_para-0.2.0/src/para/lang.py +115 -0
- pandoc_para-0.2.0/src/para/live.py +343 -0
- pandoc_para-0.2.0/src/para/media.py +251 -0
- pandoc_para-0.2.0/src/para/output.py +125 -0
- pandoc_para-0.2.0/src/para/panflute_filters.py +266 -0
- pandoc_para-0.2.0/src/para/record.py +191 -0
- pandoc_para-0.2.0/src/para/search.py +201 -0
- pandoc_para-0.2.0/src/para/settings.py +89 -0
- pandoc_para-0.2.0/src/para/site.py +700 -0
- pandoc_para-0.2.0/src/para/store.py +175 -0
- pandoc_para-0.2.0/src/para/templates/README.md +6 -0
- pandoc_para-0.2.0/src/para/templates/__init__.py +14 -0
- pandoc_para-0.2.0/src/para/templates/index.html +189 -0
- pandoc_para-0.2.0/src/para/templates/post.html +193 -0
- pandoc_para-0.2.0/src/para/templates/slidy.html +82 -0
- pandoc_para-0.2.0/src/para/theme/README.md +10 -0
- pandoc_para-0.2.0/src/para/theme/_css/bootblog.css +225 -0
- pandoc_para-0.2.0/src/para/theme/_css/bootstrap.css +10517 -0
- pandoc_para-0.2.0/src/para/theme/_css/code.css +85 -0
- pandoc_para-0.2.0/src/para/theme/_css/custom.css +183 -0
- pandoc_para-0.2.0/src/para/theme/_css/nikola_rst.css +79 -0
- pandoc_para-0.2.0/src/para/theme/_css/rst_base.css +474 -0
- pandoc_para-0.2.0/src/para/theme/_css/theme.css +237 -0
- pandoc_para-0.2.0/src/para/to_ast.py +216 -0
- pandoc_para-0.2.0/src/para/translate.py +31 -0
- pandoc_para-0.2.0/src/para/util.py +65 -0
- pandoc_para-0.2.0/tests/conftest.py +20 -0
- pandoc_para-0.2.0/tests/test_apps.py +103 -0
- pandoc_para-0.2.0/tests/test_check.py +21 -0
- pandoc_para-0.2.0/tests/test_data.py +95 -0
- pandoc_para-0.2.0/tests/test_deps.py +41 -0
- pandoc_para-0.2.0/tests/test_filters.py +75 -0
- pandoc_para-0.2.0/tests/test_front_matter.py +65 -0
- pandoc_para-0.2.0/tests/test_graph.py +45 -0
- pandoc_para-0.2.0/tests/test_lang.py +31 -0
- pandoc_para-0.2.0/tests/test_pdf.py +46 -0
- pandoc_para-0.2.0/tests/test_search.py +50 -0
- pandoc_para-0.2.0/tests/test_settings.py +69 -0
- pandoc_para-0.2.0/tests/test_store.py +50 -0
- pandoc_para-0.2.0/tests/test_translations.py +60 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
*.py[cod]
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
|
|
8
|
+
# environments
|
|
9
|
+
.pixi/
|
|
10
|
+
.venv/
|
|
11
|
+
venv*/
|
|
12
|
+
.env
|
|
13
|
+
|
|
14
|
+
# tools' caches
|
|
15
|
+
.pytest_cache/
|
|
16
|
+
.ruff_cache/
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.dmypy.json
|
|
19
|
+
.coverage
|
|
20
|
+
.coverage.*
|
|
21
|
+
coverage.xml
|
|
22
|
+
htmlcov/
|
|
23
|
+
.benchmarks/
|
|
24
|
+
|
|
25
|
+
# editors and OS
|
|
26
|
+
.idea/
|
|
27
|
+
.vscode/
|
|
28
|
+
.DS_Store
|
|
29
|
+
*~
|
|
30
|
+
.*.sw[po]
|
|
31
|
+
*.bak
|
|
32
|
+
|
|
33
|
+
# the docs' build (docs/output/, docs/.para/) is ignored by docs/.gitignore
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Revision history for `para`
|
|
2
|
+
|
|
3
|
+
## v0.2.0
|
|
4
|
+
|
|
5
|
+
A rewrite around records, output profiles and incremental builds. The package is
|
|
6
|
+
`para` (on PyPI as `pandoc-para`), the site generator `para.site` (`from para.site
|
|
7
|
+
import Config, cli`); the command is `parasite`.
|
|
8
|
+
|
|
9
|
+
- **Configuration:** a site is configured by `parasite.toml`, merged over
|
|
10
|
+
`para/defaults.toml`, which documents every key. A site's `run.py` is no longer
|
|
11
|
+
needed (see the docs' migration page).
|
|
12
|
+
- **Pipeline:** sources are read into records (URL, title, dates, category, tags,
|
|
13
|
+
description, search text, links, citations, outputs, media). Listings, feeds, the
|
|
14
|
+
sitemap, search and the post graph come from records, and every file goes through one
|
|
15
|
+
output tree. That tree refuses two producers of one path, writes only changed bytes,
|
|
16
|
+
and reports or prunes (`--prune`) what the build no longer produces.
|
|
17
|
+
- **Incremental builds:** a record store (`.para/store.sqlite`). A source is read again
|
|
18
|
+
only when its bytes, the site's code, pandoc, config, or a file its read touched
|
|
19
|
+
changed; `--full` ignores the store.
|
|
20
|
+
- **Output profiles:** a source has an output per profile (`format: [html, slides]`).
|
|
21
|
+
Content for some outputs uses Quarto's `.content-visible`/`.content-hidden`, and an
|
|
22
|
+
output can have its own metadata (`format: NAME: metadata:`) and pandoc variables.
|
|
23
|
+
Also `output-file`, and `format-links` with a profile's `label`.
|
|
24
|
+
- **PDF output:** a `pdf` profile, Typst by default, dated by the page, so a PDF is the
|
|
25
|
+
same from build to build.
|
|
26
|
+
- **Languages:** BCP 47 tags, with lookups from the most specific to the least.
|
|
27
|
+
Translations: `x.LANG.md` beside `x.md`, or made by OpenCC
|
|
28
|
+
(`pandoc-para[opencc]`), linked with `hreflang`.
|
|
29
|
+
- **Filters by name:** Python (`module:function`) or installed Lua filters, chosen per
|
|
30
|
+
document with `filters: [name, -name]`.
|
|
31
|
+
- **Media:** copied by reference (`[media.folders]`): only what pages use. After the
|
|
32
|
+
build, lychee checks every link offline, and the build fails on broken ones.
|
|
33
|
+
- **Search:** Pagefind (`pandoc-para[search]`), indexing the records in the site's
|
|
34
|
+
language, with tags and categories as filters, deterministic from build to build.
|
|
35
|
+
- **Post graph:** `graph.json`, a local graph on each page, and `/graph/` (needs
|
|
36
|
+
`pandoc-para[graph]`, paragraphic ≥ 0.2).
|
|
37
|
+
- **Listings:** `description` instead of teasers, falling back to `subtitle`. The front
|
|
38
|
+
page shows the newest posts, with an archive by year. Categories form a tree, and
|
|
39
|
+
feeds carry the newest posts. Copyright years come from the pages' own dates.
|
|
40
|
+
- **Removed:** parsl (now a thread pool, `--jobs`), urlpath, tipuesearch,
|
|
41
|
+
previous/next links, and the retired front-matter keys (`status`, `previewimage`,
|
|
42
|
+
`slug`, …; para.site warns).
|
|
43
|
+
- **Output:** well-formed XHTML; pandoc ≥ 3.11's `--math-method`.
|
|
44
|
+
- **Requirements:** Python ≥ 3.12 and pandoc ≥ 3.1.
|
|
45
|
+
|
|
46
|
+
## v0.1.0
|
|
47
|
+
|
|
48
|
+
First release and proof of concept.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021, Kolen Cheung
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: pandoc-para
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: para.site: a pandoc-first static site generator
|
|
5
|
+
Project-URL: Homepage, https://github.com/ickc/parasite
|
|
6
|
+
Project-URL: Repository, https://github.com/ickc/parasite
|
|
7
|
+
Author-email: Kolen Cheung <christian.kolen@gmail.com>
|
|
8
|
+
License-Expression: BSD-3-Clause
|
|
9
|
+
License-File: AUTHORS.rst
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: pandoc,static site generator
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
21
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
22
|
+
Requires-Python: >=3.12
|
|
23
|
+
Requires-Dist: custom-inherit>=2.4
|
|
24
|
+
Requires-Dist: defopt>=7
|
|
25
|
+
Requires-Dist: feedgen>=1
|
|
26
|
+
Requires-Dist: panflute<2.4,>=2.3.1
|
|
27
|
+
Provides-Extra: extras
|
|
28
|
+
Requires-Dist: coloredlogs>=14; extra == 'extras'
|
|
29
|
+
Requires-Dist: livereload>=2; extra == 'extras'
|
|
30
|
+
Requires-Dist: watchdog>=2; extra == 'extras'
|
|
31
|
+
Provides-Extra: graph
|
|
32
|
+
Requires-Dist: paragraphic<0.3,>=0.2; extra == 'graph'
|
|
33
|
+
Provides-Extra: opencc
|
|
34
|
+
Requires-Dist: opencc>=1.1; extra == 'opencc'
|
|
35
|
+
Provides-Extra: search
|
|
36
|
+
Requires-Dist: pagefind[bin]>=1.5; extra == 'search'
|
|
37
|
+
Provides-Extra: tests
|
|
38
|
+
Requires-Dist: coverage; extra == 'tests'
|
|
39
|
+
Requires-Dist: pytest; extra == 'tests'
|
|
40
|
+
Requires-Dist: pytest-cov; extra == 'tests'
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
|
|
43
|
+
# para.site
|
|
44
|
+
|
|
45
|
+
A pandoc-first static site generator: websites from documents pandoc can read, with
|
|
46
|
+
listings, categories and tags, feeds, a sitemap, search, a graph of how the pages link,
|
|
47
|
+
and builds that redo only what changed. A site is configured by one file,
|
|
48
|
+
`parasite.toml`.
|
|
49
|
+
|
|
50
|
+
The Python package is `para` (on PyPI as `pandoc-para` for now: `pip install
|
|
51
|
+
pandoc-para`), the site generator its module `para.site`, and the command `parasite`:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from para import site
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Documentation: <https://ickc.github.io/parasite/> (its source is `docs/`, built with
|
|
58
|
+
para.site).
|
|
59
|
+
|
|
60
|
+
## Develop
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
pixi run test
|
|
64
|
+
make docs
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Licence
|
|
68
|
+
|
|
69
|
+
BSD-3-Clause.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# para.site
|
|
2
|
+
|
|
3
|
+
A pandoc-first static site generator: websites from documents pandoc can read, with
|
|
4
|
+
listings, categories and tags, feeds, a sitemap, search, a graph of how the pages link,
|
|
5
|
+
and builds that redo only what changed. A site is configured by one file,
|
|
6
|
+
`parasite.toml`.
|
|
7
|
+
|
|
8
|
+
The Python package is `para` (on PyPI as `pandoc-para` for now: `pip install
|
|
9
|
+
pandoc-para`), the site generator its module `para.site`, and the command `parasite`:
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
from para import site
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Documentation: <https://ickc.github.io/parasite/> (its source is `docs/`, built with
|
|
16
|
+
para.site).
|
|
17
|
+
|
|
18
|
+
## Develop
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
pixi run test
|
|
22
|
+
make docs
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Licence
|
|
26
|
+
|
|
27
|
+
BSD-3-Clause.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# para.site's documentation, built with para.site (pandoc, and para with its search extra)
|
|
2
|
+
|
|
3
|
+
.PHONY: docs serve clean
|
|
4
|
+
docs: pages/reference.md
|
|
5
|
+
parasite
|
|
6
|
+
|
|
7
|
+
# every key, from para.site's own defaults
|
|
8
|
+
pages/reference.md: ../src/para/defaults.toml
|
|
9
|
+
python -c 'import sys; src = open(sys.argv[1]).read(); open(sys.argv[2], "w").write("---\ntitle: Every key\ndescription: para.site\x27s defaults.toml, which a site\x27s parasite.toml is merged over.\n---\n\n<!-- written by docs/makefile from src/para/defaults.toml: do not edit -->\n\nA site\x27s `parasite.toml` is merged over this file (see [parasite.toml](../configuration/)).\n\n```toml\n" + src + "```\n")' $< $@
|
|
10
|
+
|
|
11
|
+
serve: docs
|
|
12
|
+
python -m http.server --directory output 8000
|
|
13
|
+
|
|
14
|
+
clean:
|
|
15
|
+
rm -rf output .para
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: How it builds
|
|
3
|
+
description: Read, record, derive, render, write; and only what changed.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# The steps
|
|
7
|
+
|
|
8
|
+
1. **Discover** the sources of each collection.
|
|
9
|
+
2. **Read** each into a pandoc document, with the read filters.
|
|
10
|
+
3. **Record** it: a small summary of the page (URL, title, dates, category, tags,
|
|
11
|
+
description, search text, links, citations, its outputs, the media it uses).
|
|
12
|
+
4. **Derive** what crosses pages from the records alone: listings, categories, tags,
|
|
13
|
+
the archive, feeds, the sitemap, search, the graph, the site's copyright years.
|
|
14
|
+
5. **Render** each page in each of its profiles, and the derived pages. A page's
|
|
15
|
+
document is dropped once rendered.
|
|
16
|
+
6. **Write**: every file through one output tree.
|
|
17
|
+
|
|
18
|
+
Pages are read and rendered in a thread pool: most of the work is pandoc, in its own
|
|
19
|
+
processes.
|
|
20
|
+
|
|
21
|
+
# Only what changed
|
|
22
|
+
|
|
23
|
+
The records are kept in `.para/store.sqlite` (ignore it in git). A build reads a source
|
|
24
|
+
again only when its **read key** changed, and renders a page again only when its
|
|
25
|
+
**render key** changed or a file it produced is gone:
|
|
26
|
+
|
|
27
|
+
- the **site key**: the code (the Python modules loaded, the installed packages,
|
|
28
|
+
para's own files), pandoc and its data folder, the configuration, and the files
|
|
29
|
+
the configuration names for every page (`[read]`'s `--metadata-file` and the like,
|
|
30
|
+
the profiles' own templates, `pandoc-crossref.yaml`). Any change here reads everything
|
|
31
|
+
again;
|
|
32
|
+
- a **read key**: the site key and the source's bytes. And a record is used only while
|
|
33
|
+
the files its read touched are unchanged: its links' and images' files (or that they
|
|
34
|
+
were missing), the media it references and what those reference, its bibliography and
|
|
35
|
+
style if it cites, a translation's primary, and the files and folders its text names
|
|
36
|
+
(a table's CSV, a gallery's folder). So a bibliography edit reads again the pages that
|
|
37
|
+
cite, and a new photo the page whose gallery has it. A filter that reads a file the
|
|
38
|
+
document does not name can say so with `para.deps.touch(path)`;
|
|
39
|
+
- a **render key**: the read key, the page's copyright years, its link to a report and
|
|
40
|
+
its translations.
|
|
41
|
+
|
|
42
|
+
A derived page is rendered again when its document changed. `parasite --full` ignores
|
|
43
|
+
the store. A rebuild with nothing changed takes about a third of a second for a site of a
|
|
44
|
+
hundred pages.
|
|
45
|
+
|
|
46
|
+
# The output tree
|
|
47
|
+
|
|
48
|
+
Every file has one producer: a page, a derived page, a copied folder, a minified bundle,
|
|
49
|
+
a medium, a site-wide file. Two producers of one path is an error. A file is written
|
|
50
|
+
only when its bytes change, so an unchanged page keeps its modification time. Files in
|
|
51
|
+
the output folder that no step produced (a deleted page's) are reported, and removed
|
|
52
|
+
with `parasite --prune`.
|
|
53
|
+
|
|
54
|
+
# Media
|
|
55
|
+
|
|
56
|
+
`[media.folders]` are copied **by reference**: only the files the pages use, from their
|
|
57
|
+
images and links, raw HTML (`src`, `href`, `data`, `poster`, `url(…)`), their `image`,
|
|
58
|
+
and what those files use in turn (an HTML plot's scripts, an SVG's images, a style
|
|
59
|
+
sheet's). `[files]` are copied whole.
|
|
60
|
+
|
|
61
|
+
Media in a source itself (a notebook's outputs) are written next to the page; a PDF
|
|
62
|
+
image becomes SVG, which a browser can show.
|
|
63
|
+
|
|
64
|
+
# Search
|
|
65
|
+
|
|
66
|
+
With `[search] enabled` and `pandoc-para[search]` installed, para.site indexes the
|
|
67
|
+
records with [Pagefind](https://pagefind.app/) and makes the search page (`[search]
|
|
68
|
+
page`). The index is sharded: one more page changes a few of its files. The search box
|
|
69
|
+
in the navigation sends `?q=` to it. Every page is indexed in the site's language
|
|
70
|
+
(Pagefind searches the index of the search page's language only). Tags and categories
|
|
71
|
+
are its filters, and a page's tags are searched as its words.
|
|
72
|
+
|
|
73
|
+
# Links
|
|
74
|
+
|
|
75
|
+
With [lychee](https://lychee.cli.rs) installed, para.site checks the output's links when
|
|
76
|
+
the build is done, offline: every link and media reference from the site's files to its
|
|
77
|
+
files must resolve, or the build fails (the output is written either way; a build that
|
|
78
|
+
serves or watches only logs them). This guards the media copied by reference: a
|
|
79
|
+
reference para.site did not see would be a broken link here. lychee reads the HTML, raw
|
|
80
|
+
HTML and `<style>` elements included, but not `style` attributes or CSS files.
|
|
81
|
+
|
|
82
|
+
Links known to be broken are excluded by `[check] exclude`, regular expressions of
|
|
83
|
+
URLs (a site's file is a `file://` URL); `[check] links = false` turns the check off.
|
|
84
|
+
|
|
85
|
+
# The post graph
|
|
86
|
+
|
|
87
|
+
With `[graph] enabled` and `pandoc-para[graph]` installed, para.site writes `graph.json`
|
|
88
|
+
from the records (links, citations, external links, a page's other outputs) and the
|
|
89
|
+
`/graph/` page; every page gets a graph of its neighbours.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: parasite.toml
|
|
3
|
+
description: A site's configuration, as data.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
A site is a folder with a `parasite.toml`. `parasite` builds the site in the working
|
|
7
|
+
directory from it.
|
|
8
|
+
|
|
9
|
+
# Merged over the defaults
|
|
10
|
+
|
|
11
|
+
para.site has a `defaults.toml`, which documents every key: see [every key](../reference/).
|
|
12
|
+
A site's `parasite.toml` is merged over it:
|
|
13
|
+
|
|
14
|
+
- tables, key by key: a site writes only what differs;
|
|
15
|
+
- anything else (strings, numbers, lists) replaced whole;
|
|
16
|
+
- `[files]`, `[media.folders]`, `[minify.css]` and `[minify.js]` replaced whole too, as
|
|
17
|
+
they list a site's own entries;
|
|
18
|
+
- `[filters]` in the site's order: its filters first, then the defaults it does not
|
|
19
|
+
mention.
|
|
20
|
+
|
|
21
|
+
# The parts
|
|
22
|
+
|
|
23
|
+
| table | what |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `[site]` | URL, title, description, author, language, time zone, logo, copyright, output folder, drafts |
|
|
26
|
+
| `[listing]` | the front page, categories, tags and the archive, or none |
|
|
27
|
+
| `[feeds]`, `[sitemap]`, `[search]`, `[graph]` | what else is written |
|
|
28
|
+
| `[[sources]]` | collections: folders of sources, their extensions, whether they are listed posts, their output profiles |
|
|
29
|
+
| `[read]`, `[read.EXT]` | pandoc's options for reading, for every source and per input format |
|
|
30
|
+
| `[filters.NAME]` | the filters a site may use (see [filters](../filters/)) |
|
|
31
|
+
| `[profiles.NAME]` | output profiles: writer, template, URL rule, options, filters, the page's parts (see [output profiles](../profiles/)) |
|
|
32
|
+
| `[files]` | folders of site files, copied whole |
|
|
33
|
+
| `[media.folders]` | folders of media, copied by reference: only what pages use |
|
|
34
|
+
| `[minify.css]`, `[minify.js]` | style sheets and scripts bundled and minified |
|
|
35
|
+
| `[mathjax]` | MathJax's configuration, as a table |
|
|
36
|
+
|
|
37
|
+
# In strings
|
|
38
|
+
|
|
39
|
+
`{root}` becomes the relative path from the page to the site's root (`..`, `../..`, or `.`
|
|
40
|
+
at the top), and `{years}` the copyright years (a post's own, from its `date` to its
|
|
41
|
+
`date-modified`; a page without dates has the site's). The footer also has `{author}`
|
|
42
|
+
and `{email}`. No other braces are touched, so scripts need no escaping.
|
|
43
|
+
|
|
44
|
+
# By language
|
|
45
|
+
|
|
46
|
+
A string can instead be a table by language, used for the page's `lang`:
|
|
47
|
+
|
|
48
|
+
```toml
|
|
49
|
+
[site]
|
|
50
|
+
lang = "zh_tw"
|
|
51
|
+
title = { en = "KcIc", zh_tw = "祺" }
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
# On the command line
|
|
55
|
+
|
|
56
|
+
The settings that are fields of the build (`parasite --help`) can be overridden there,
|
|
57
|
+
for one build: `parasite --include-draft`, `parasite --full`, `parasite --prune`.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Filters
|
|
3
|
+
description: The code a site runs, named in its parasite.toml.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
A site lists the filters it may use in `[filters.NAME]`, in the order they run. A filter
|
|
7
|
+
is code from something you installed, never a path in the site: Python, a function
|
|
8
|
+
taking and returning a panflute document named as an importable `module:function`; or
|
|
9
|
+
Lua, by name, found where packages install Lua filters (the environment's
|
|
10
|
+
`share/pandoc/filters/`, as pandoc-forge's packages do) or in pandoc's user data
|
|
11
|
+
directory.
|
|
12
|
+
|
|
13
|
+
```toml
|
|
14
|
+
[filters.amsthm]
|
|
15
|
+
lua = "amsthm"
|
|
16
|
+
default = true
|
|
17
|
+
|
|
18
|
+
[filters.pannb]
|
|
19
|
+
python = "pannb:main"
|
|
20
|
+
inputs = ["ipynb"]
|
|
21
|
+
default = true
|
|
22
|
+
|
|
23
|
+
[filters.texp]
|
|
24
|
+
python = "texp.panflute_filter:main"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| key | meaning |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `python` | the function, `module:function` |
|
|
30
|
+
| `lua` | the Lua filter's name (`amsthm` is `amsthm.lua`) |
|
|
31
|
+
| `at` | `"read"` (the default): after reading, for every output; `"render"`: for an output whose profile names it in its `filters`, or of a document that names it |
|
|
32
|
+
| `inputs` | a read filter for these input formats only (extensions without the dot) |
|
|
33
|
+
| `default` | a read filter runs on every document |
|
|
34
|
+
|
|
35
|
+
A document chooses among them with Quarto's key, by name:
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
filters: [texp, -pantable]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
turns `texp` on and `pantable` (a default) off. A name the site does not list fails that
|
|
42
|
+
page, with a message saying where to add it; a path is refused. The filters run in the
|
|
43
|
+
site's order, not the document's, so two documents with the same filters run them the
|
|
44
|
+
same way.
|
|
45
|
+
|
|
46
|
+
Read filters run after pandoc's own (the `--filter` and `--citeproc` of
|
|
47
|
+
`[read] options`), Lua ones in a pandoc call of their own. A Lua render filter runs in
|
|
48
|
+
the call that writes the output, after the Python ones, so that `FORMAT` is the
|
|
49
|
+
output's.
|
|
50
|
+
|
|
51
|
+
para.site's own: `lightgallery-from-dir` (read: a gallery from a folder of photos),
|
|
52
|
+
`lightgallery` and `mathjax-bold-ell` (render: MathJax has no bold ℓ, so
|
|
53
|
+
`\mathbf{\ell}` is written `\pmb{\ell}` in HTML).
|
|
54
|
+
|
|
55
|
+
pandoc's JSON filters (pandoc-crossref) and citeproc are pandoc options: put them in
|
|
56
|
+
`[read] options`. WebAssembly filters are planned.
|
|
57
|
+
|
|
58
|
+
# From other tools
|
|
59
|
+
|
|
60
|
+
Each has its own key for a document's filters; para.site reads none of them yet:
|
|
61
|
+
|
|
62
|
+
| tool | key |
|
|
63
|
+
|---|---|
|
|
64
|
+
| Quarto | `filters:`, names or paths, with `at:` for the stage |
|
|
65
|
+
| panflute | `panflute-filters:`, with `panflute-path:` |
|
|
66
|
+
| panzer | `style:`, naming a set of filters defined elsewhere |
|
|
67
|
+
| pandocomatic | `pandocomatic_:` |
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Front matter
|
|
3
|
+
description: The keys para.site reads from a document's metadata.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
A document's metadata is pandoc's: YAML front matter in Markdown, the first raw cell of a
|
|
7
|
+
notebook. pandoc's own keys keep pandoc's meaning; where Quarto has the same idea,
|
|
8
|
+
para.site uses Quarto's name.
|
|
9
|
+
|
|
10
|
+
| key | meaning |
|
|
11
|
+
|---|---|
|
|
12
|
+
| `title`, `subtitle`, `author`, `abstract` | pandoc's |
|
|
13
|
+
| `lang` | the page's language, a BCP 47 tag (see [languages](../languages/)); a translation's comes from its file name |
|
|
14
|
+
| `date` | when it was first published; a post needs one. An ISO 8601 date or date-time, in the site's time zone unless it says otherwise |
|
|
15
|
+
| `date-modified` | when its content last changed, by hand. A post's copyright runs from `date` to `date-modified` |
|
|
16
|
+
| `description` | one or two plain sentences, for listings, `<meta name="description">` and search; shown under the title. Without one, the `subtitle` is used |
|
|
17
|
+
| `category` | one per post, a path (`so-uk/meetings`). It defaults to the source's folder, so it is rarely written; a category lists its subcategories' posts too |
|
|
18
|
+
| `tags` | a list; each tag has a page |
|
|
19
|
+
| `draft: true` | built only with `--include-draft`, and never listed |
|
|
20
|
+
| `image`, `image-alt` | its thumbnail in listings, from the site's root, and the thumbnail's text (else the title) |
|
|
21
|
+
| `format` | its output profiles (see [output profiles](../profiles/)) |
|
|
22
|
+
| `format-links` | which of its other outputs an output links to, by each profile's `label`: `true` all, `false` none, or a list of profile names. Without it, slides link to the page beside them (Report) |
|
|
23
|
+
| `output-file` | an output's file name, in its folder, as an exception to the URL rules: at the top level the first output's, under `format: NAME:` that output's |
|
|
24
|
+
|
|
25
|
+
# Keys from parasite ≤ 0.1
|
|
26
|
+
|
|
27
|
+
para.site warns about these and otherwise ignores them:
|
|
28
|
+
|
|
29
|
+
| key | instead |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `<!-- more -->` (a teaser) | `description` |
|
|
32
|
+
| `status: draft` | `draft: true` |
|
|
33
|
+
| `status: featured` | nothing: the front page shows the newest posts |
|
|
34
|
+
| `previewimage` | `image` |
|
|
35
|
+
| `slug`, `pretty_url`, `url_type` | the source's path |
|
|
36
|
+
| `type` | nothing |
|
|
37
|
+
| `sidebar_toc` | `toc` |
|
|
38
|
+
| `temp` | nothing |
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: para.site
|
|
3
|
+
subtitle: A pandoc-first static site generator
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
para.site builds websites from documents pandoc can read: Markdown, Jupyter notebooks,
|
|
7
|
+
and anything else pandoc has a reader for. Its documents, metadata and templates are
|
|
8
|
+
pandoc's own. It adds what a site needs around them: listings, categories and tags, an
|
|
9
|
+
archive, feeds, a sitemap, search, a graph of how the pages link, and builds that redo
|
|
10
|
+
only what changed.
|
|
11
|
+
|
|
12
|
+
The Python package is `para` (on PyPI as `pandoc-para` for now), the site generator is
|
|
13
|
+
its module `para.site`, and the command is `parasite`:
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from para import site
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
# Why
|
|
20
|
+
|
|
21
|
+
- **pandoc first.** No syntax of its own: no shortcodes, no extensions to Markdown.
|
|
22
|
+
A source is a pandoc document; its options are pandoc's options.
|
|
23
|
+
- **Configured as data.** A site is described by one file, `parasite.toml`. Code runs
|
|
24
|
+
only as filters you named, from packages you installed.
|
|
25
|
+
- **One source, several outputs.** A talk can be a page and its slides, from one file
|
|
26
|
+
(see [output profiles](profiles/)).
|
|
27
|
+
- **Incremental.** A build reads and renders only what changed; a rebuild with nothing
|
|
28
|
+
changed takes a fraction of a second (see [how it builds](builds/)).
|
|
29
|
+
- **Valid XHTML.** Every page is well-formed.
|
|
30
|
+
|
|
31
|
+
# A site in a minute
|
|
32
|
+
|
|
33
|
+
A folder with a `parasite.toml`:
|
|
34
|
+
|
|
35
|
+
```toml
|
|
36
|
+
[site]
|
|
37
|
+
url = "https://example.org/"
|
|
38
|
+
title = "My site"
|
|
39
|
+
author = "Me"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
and Markdown files under `posts/` (dated, listed) and `pages/` (not listed):
|
|
43
|
+
|
|
44
|
+
```markdown
|
|
45
|
+
---
|
|
46
|
+
title: Hello
|
|
47
|
+
date: 2026-10-11
|
|
48
|
+
tags: [hello]
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
The first post.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Then, in that folder:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
parasite
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
writes the site to `output/`. `parasite --help` lists what the command line can
|
|
61
|
+
override.
|
|
62
|
+
|
|
63
|
+
These pages are themselves built with para.site: see `docs/` in its repository.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Install
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
::: note
|
|
6
|
+
On PyPI the distribution is `pandoc-para` for now (the name `para` is requested); it
|
|
7
|
+
installs the package `para` and the command `parasite`.
|
|
8
|
+
:::
|
|
9
|
+
|
|
10
|
+
para.site needs Python ≥ 3.12 and pandoc ≥ 3.1. pandoc is not on PyPI: install it from
|
|
11
|
+
[pandoc.org](https://pandoc.org/installing.html) or conda-forge.
|
|
12
|
+
|
|
13
|
+
# With pixi or conda
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
pixi add pandoc
|
|
17
|
+
pixi add --pypi pandoc-para
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
# With pip
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
pip install pandoc-para
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
# Optional parts
|
|
27
|
+
|
|
28
|
+
| extra | for |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `pandoc-para[search]` | search, with [Pagefind](https://pagefind.app/) (its binary comes with it) |
|
|
31
|
+
| `pandoc-para[extras]` | coloured logs; watching sources and serving the site while you write |
|
|
32
|
+
| `pandoc-para[graph]` | the post graph, with [paragraphic](https://github.com/ickc/paragraphic) |
|
|
33
|
+
|
|
34
|
+
The check of the output's links needs [lychee](https://lychee.cli.rs) (`pixi add
|
|
35
|
+
lychee`; see [builds](../builds/)).
|
|
36
|
+
|
|
37
|
+
Filters a site uses (pantable, pannb, …) are installed like any package, then named in
|
|
38
|
+
its `parasite.toml` (see [filters](../filters/)).
|
|
39
|
+
|
|
40
|
+
# From the source
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
git clone https://github.com/ickc/parasite
|
|
44
|
+
cd parasite
|
|
45
|
+
pixi run test
|
|
46
|
+
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Languages
|
|
3
|
+
description: A site's language, a page's, and translations written beside each other or made by conversion.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Language tags
|
|
7
|
+
|
|
8
|
+
Languages are [BCP 47](https://www.rfc-editor.org/info/bcp47) tags, which name the
|
|
9
|
+
written language: `en`, `zh-Hant` (Traditional Chinese), `zh-Hans` (Simplified), and if
|
|
10
|
+
needed more specific ones, such as `zh-Hant-HK`. `[site] lang` is the site's; a page sets
|
|
11
|
+
its own with `lang` in its front matter. Tags are written in any case, and `_` is read as
|
|
12
|
+
`-`: Nikola's `zh_tw` is `zh-TW`, Chinese as used in Taiwan, a region rather than a
|
|
13
|
+
script.
|
|
14
|
+
|
|
15
|
+
A value by language, such as `title = { en = "…", zh-Hant = "…" }` or a profile's `nav`,
|
|
16
|
+
is looked up from the most specific tag to the least: a page in `zh-Hant-HK` takes the
|
|
17
|
+
`zh-Hant` value, then `zh`'s, then the site language's.
|
|
18
|
+
|
|
19
|
+
# Translations
|
|
20
|
+
|
|
21
|
+
Each of the site's other languages is a table of `[translations]`:
|
|
22
|
+
|
|
23
|
+
```toml
|
|
24
|
+
[site]
|
|
25
|
+
lang = "zh-Hant"
|
|
26
|
+
|
|
27
|
+
[translations.en]
|
|
28
|
+
[translations.zh-Hans]
|
|
29
|
+
convert = "hk2s"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Written by hand.** `x.en.md` is the English translation of `x.md`, next to it. Its
|
|
33
|
+
outputs are written beside the primary's, in the same folder: `x/index.html` and
|
|
34
|
+
`x/index.en.html` (slides: `present.html` and `present.en.html`). So its relative links
|
|
35
|
+
and media work as they are written in `x.md`. Front matter it does not set (the date,
|
|
36
|
+
tags, category, image, `format`) is `x.md`'s; its title, description and body are its
|
|
37
|
+
own. `x.en.md` without an `x.md` is a page in English, at `x/`.
|
|
38
|
+
|
|
39
|
+
**Made by conversion.** With `convert`, an [OpenCC](https://github.com/BYVoid/OpenCC)
|
|
40
|
+
conversion (`hk2s`, `t2s`, `tw2s`, `s2t`, `s2hk`, `s2tw`, …), each page in the site's
|
|
41
|
+
language (or `from`) that has no written translation gets one: its text and metadata
|
|
42
|
+
converted, its code, URLs and raw HTML left as they are. It needs `pandoc-para[opencc]`. A
|
|
43
|
+
value by language the site does not give for that language (its title, the `nav`) is
|
|
44
|
+
the source language's, converted.
|
|
45
|
+
|
|
46
|
+
**Between them.** Each version of a page links to the others: `<link rel="alternate"
|
|
47
|
+
hreflang>` in its head, and a line under the byline naming each language (`name` in its
|
|
48
|
+
table, else its own name: 繁體中文, 简体中文, English, …). Listings, tag and category
|
|
49
|
+
pages, feeds and the post graph show each page once, its primary version; the sitemap
|
|
50
|
+
lists every version, and search every version but conversions (the same text in
|
|
51
|
+
another script).
|
|
52
|
+
|
|
53
|
+
Not yet: listings, feeds and search per language, as a site per language under its own
|
|
54
|
+
folder; the theme's words for more languages than English and Chinese.
|