parch 0.1.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.
- parch-0.1.0/.github/dependabot.yml +22 -0
- parch-0.1.0/.github/workflows/ci.yml +21 -0
- parch-0.1.0/.github/workflows/publish.yml +68 -0
- parch-0.1.0/.github/workflows/readme-previews.yml +54 -0
- parch-0.1.0/.gitignore +10 -0
- parch-0.1.0/LICENSE +25 -0
- parch-0.1.0/PKG-INFO +199 -0
- parch-0.1.0/README.md +151 -0
- parch-0.1.0/docs/samples/158x210-mos-left/annual.svg +1 -0
- parch-0.1.0/docs/samples/158x210-mos-left/colophon.svg +1 -0
- parch-0.1.0/docs/samples/158x210-mos-left/contents.svg +1 -0
- parch-0.1.0/docs/samples/158x210-mos-left/cover.svg +1 -0
- parch-0.1.0/docs/samples/158x210-mos-left/daily-jan1.svg +1 -0
- parch-0.1.0/docs/samples/158x210-mos-left/monthly-jan.svg +1 -0
- parch-0.1.0/docs/samples/158x210-mos-left/notes-jan1.svg +1 -0
- parch-0.1.0/docs/samples/158x210-mos-left/quarterly-q1.svg +1 -0
- parch-0.1.0/docs/samples/158x210-mos-left/weekly-w01.svg +1 -0
- parch-0.1.0/pyproject.toml +55 -0
- parch-0.1.0/src/parch/__init__.py +17 -0
- parch-0.1.0/src/parch/__main__.py +4 -0
- parch-0.1.0/src/parch/calendar/__init__.py +39 -0
- parch-0.1.0/src/parch/calendar/dated_note.py +34 -0
- parch-0.1.0/src/parch/calendar/day.py +181 -0
- parch-0.1.0/src/parch/calendar/month.py +83 -0
- parch-0.1.0/src/parch/calendar/quarter.py +67 -0
- parch-0.1.0/src/parch/calendar/week.py +71 -0
- parch-0.1.0/src/parch/cli.py +285 -0
- parch-0.1.0/src/parch/config.py +125 -0
- parch-0.1.0/src/parch/data/__init__.py +1 -0
- parch-0.1.0/src/parch/data/configs/158x210-mos-left-lined.toml +103 -0
- parch-0.1.0/src/parch/data/configs/158x210-mos-left.toml +99 -0
- parch-0.1.0/src/parch/data/configs/158x210-mos-right.toml +102 -0
- parch-0.1.0/src/parch/data/configs/kindle-scribe.toml +97 -0
- parch-0.1.0/src/parch/data/configs/supernote-nomad-mos-right.toml +116 -0
- parch-0.1.0/src/parch/data/configs/supernote-nomad.toml +113 -0
- parch-0.1.0/src/parch/data/locales/en.toml +84 -0
- parch-0.1.0/src/parch/devices.py +76 -0
- parch-0.1.0/src/parch/i18n.py +83 -0
- parch-0.1.0/src/parch/models/__init__.py +22 -0
- parch-0.1.0/src/parch/models/base.py +35 -0
- parch-0.1.0/src/parch/models/device.py +400 -0
- parch-0.1.0/src/parch/models/locale.py +94 -0
- parch-0.1.0/src/parch/mos/__init__.py +19 -0
- parch-0.1.0/src/parch/mos/builder.py +120 -0
- parch-0.1.0/src/parch/mos/components/__init__.py +15 -0
- parch-0.1.0/src/parch/mos/components/daily_notes.py +49 -0
- parch-0.1.0/src/parch/mos/components/daily_priorities.py +27 -0
- parch-0.1.0/src/parch/mos/components/daily_schedule.py +58 -0
- parch-0.1.0/src/parch/mos/components/little_calendar.py +138 -0
- parch-0.1.0/src/parch/mos/components/months_menu.py +53 -0
- parch-0.1.0/src/parch/mos/components/quarters_menu.py +43 -0
- parch-0.1.0/src/parch/mos/configurator.py +74 -0
- parch-0.1.0/src/parch/mos/contents_mark.py +107 -0
- parch-0.1.0/src/parch/mos/coordinator.py +94 -0
- parch-0.1.0/src/parch/mos/manifest.py +37 -0
- parch-0.1.0/src/parch/mos/navigation.py +161 -0
- parch-0.1.0/src/parch/mos/page_data.py +24 -0
- parch-0.1.0/src/parch/mos/pages/__init__.py +6 -0
- parch-0.1.0/src/parch/mos/pages/daily.py +112 -0
- parch-0.1.0/src/parch/mos/pages/monthly.py +126 -0
- parch-0.1.0/src/parch/mos/pages/quarterly.py +69 -0
- parch-0.1.0/src/parch/mos/pages/weekly.py +60 -0
- parch-0.1.0/src/parch/mos/preamble.py +129 -0
- parch-0.1.0/src/parch/mos/sections/__init__.py +29 -0
- parch-0.1.0/src/parch/mos/sections/_shared.py +33 -0
- parch-0.1.0/src/parch/mos/sections/annual.py +85 -0
- parch-0.1.0/src/parch/mos/sections/cover_plain.py +50 -0
- parch-0.1.0/src/parch/mos/sections/daily.py +58 -0
- parch-0.1.0/src/parch/mos/sections/daily_notes.py +108 -0
- parch-0.1.0/src/parch/mos/sections/habits.py +221 -0
- parch-0.1.0/src/parch/mos/sections/index.py +126 -0
- parch-0.1.0/src/parch/mos/sections/meetings.py +216 -0
- parch-0.1.0/src/parch/mos/sections/monthly.py +77 -0
- parch-0.1.0/src/parch/mos/sections/projects.py +225 -0
- parch-0.1.0/src/parch/mos/sections/quarterly.py +86 -0
- parch-0.1.0/src/parch/mos/sections/review.py +274 -0
- parch-0.1.0/src/parch/mos/sections/tasks.py +272 -0
- parch-0.1.0/src/parch/mos/sections/weekly.py +86 -0
- parch-0.1.0/src/parch/provenance.py +209 -0
- parch-0.1.0/src/parch/sections/__init__.py +3 -0
- parch-0.1.0/src/parch/sections/colophon.py +333 -0
- parch-0.1.0/src/parch/services/__init__.py +4 -0
- parch-0.1.0/src/parch/services/compile.py +314 -0
- parch-0.1.0/src/parch/services/config_file.py +356 -0
- parch-0.1.0/src/parch/services/generate.py +25 -0
- parch-0.1.0/src/parch/services/preview_svg.py +244 -0
- parch-0.1.0/src/parch/toml_config.py +545 -0
- parch-0.1.0/tests/__init__.py +0 -0
- parch-0.1.0/tests/calendar/__init__.py +0 -0
- parch-0.1.0/tests/calendar/test_day.py +78 -0
- parch-0.1.0/tests/calendar/test_month.py +41 -0
- parch-0.1.0/tests/calendar/test_quarter.py +49 -0
- parch-0.1.0/tests/calendar/test_week.py +49 -0
- parch-0.1.0/tests/conftest.py +2 -0
- parch-0.1.0/tests/helpers.py +84 -0
- parch-0.1.0/tests/mos/__init__.py +0 -0
- parch-0.1.0/tests/mos/test_annual.py +103 -0
- parch-0.1.0/tests/mos/test_daily.py +256 -0
- parch-0.1.0/tests/mos/test_daily_notes.py +225 -0
- parch-0.1.0/tests/mos/test_little_calendar.py +125 -0
- parch-0.1.0/tests/mos/test_manifest.py +9 -0
- parch-0.1.0/tests/mos/test_monthly.py +212 -0
- parch-0.1.0/tests/mos/test_navigation.py +134 -0
- parch-0.1.0/tests/mos/test_quarterly.py +205 -0
- parch-0.1.0/tests/mos/test_weekly.py +198 -0
- parch-0.1.0/tests/test_colophon.py +674 -0
- parch-0.1.0/tests/test_config.py +50 -0
- parch-0.1.0/tests/test_cover.py +37 -0
- parch-0.1.0/tests/test_cover_visual.py +38 -0
- parch-0.1.0/tests/test_habits.py +702 -0
- parch-0.1.0/tests/test_habits_visual.py +36 -0
- parch-0.1.0/tests/test_i18n.py +104 -0
- parch-0.1.0/tests/test_index.py +267 -0
- parch-0.1.0/tests/test_meetings.py +336 -0
- parch-0.1.0/tests/test_meetings_visual.py +110 -0
- parch-0.1.0/tests/test_models.py +209 -0
- parch-0.1.0/tests/test_mos_handedness.py +252 -0
- parch-0.1.0/tests/test_new.py +296 -0
- parch-0.1.0/tests/test_open_resolved_zip.py +40 -0
- parch-0.1.0/tests/test_preview_svg.py +184 -0
- parch-0.1.0/tests/test_projects.py +449 -0
- parch-0.1.0/tests/test_projects_visual.py +84 -0
- parch-0.1.0/tests/test_provenance.py +129 -0
- parch-0.1.0/tests/test_review.py +540 -0
- parch-0.1.0/tests/test_scratch_pad.py +269 -0
- parch-0.1.0/tests/test_tasks.py +464 -0
- parch-0.1.0/tests/test_toml_config.py +538 -0
- parch-0.1.0/tests/test_toml_omit_sections.py +217 -0
- parch-0.1.0/tests/test_typst_asset.py +173 -0
- parch-0.1.0/tests/toml_fixtures.py +162 -0
- parch-0.1.0/tests/visual.py +152 -0
- parch-0.1.0/uv.lock +322 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Dependabot: GitHub Actions and uv (pyproject.toml + uv.lock)
|
|
2
|
+
version: 2
|
|
3
|
+
updates:
|
|
4
|
+
- package-ecosystem: github-actions
|
|
5
|
+
directory: /
|
|
6
|
+
schedule:
|
|
7
|
+
interval: weekly
|
|
8
|
+
day: monday
|
|
9
|
+
groups:
|
|
10
|
+
github-actions:
|
|
11
|
+
patterns:
|
|
12
|
+
- "*"
|
|
13
|
+
|
|
14
|
+
- package-ecosystem: uv
|
|
15
|
+
directory: /
|
|
16
|
+
schedule:
|
|
17
|
+
interval: weekly
|
|
18
|
+
day: monday
|
|
19
|
+
groups:
|
|
20
|
+
python:
|
|
21
|
+
patterns:
|
|
22
|
+
- "*"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v7
|
|
13
|
+
- uses: astral-sh/setup-uv@v7
|
|
14
|
+
- name: Install poppler-utils
|
|
15
|
+
run: sudo apt-get update && sudo apt-get install -y poppler-utils
|
|
16
|
+
- run: uv sync --group dev
|
|
17
|
+
- run: uv run pytest
|
|
18
|
+
- name: Generate Nomad PDF
|
|
19
|
+
run: |
|
|
20
|
+
uv run parch generate supernote-nomad -w out/nomad
|
|
21
|
+
test -s out/nomad/index.pdf
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
target:
|
|
10
|
+
description: "Publish target"
|
|
11
|
+
required: true
|
|
12
|
+
type: choice
|
|
13
|
+
options:
|
|
14
|
+
- testpypi
|
|
15
|
+
- pypi
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
build:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
25
|
+
with:
|
|
26
|
+
persist-credentials: false
|
|
27
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
28
|
+
with:
|
|
29
|
+
enable-cache: false
|
|
30
|
+
- run: uv build
|
|
31
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
32
|
+
with:
|
|
33
|
+
name: dist
|
|
34
|
+
path: dist/
|
|
35
|
+
|
|
36
|
+
pypi:
|
|
37
|
+
needs: build
|
|
38
|
+
if: github.event_name == 'push' || inputs.target == 'pypi'
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
environment:
|
|
41
|
+
name: pypi
|
|
42
|
+
url: https://pypi.org/p/parch
|
|
43
|
+
permissions:
|
|
44
|
+
id-token: write
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
|
|
47
|
+
with:
|
|
48
|
+
name: dist
|
|
49
|
+
path: dist
|
|
50
|
+
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
51
|
+
|
|
52
|
+
testpypi:
|
|
53
|
+
needs: build
|
|
54
|
+
if: github.event_name == 'workflow_dispatch' && inputs.target == 'testpypi'
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
environment:
|
|
57
|
+
name: testpypi
|
|
58
|
+
url: https://test.pypi.org/p/parch
|
|
59
|
+
permissions:
|
|
60
|
+
id-token: write
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
|
|
63
|
+
with:
|
|
64
|
+
name: dist
|
|
65
|
+
path: dist
|
|
66
|
+
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
67
|
+
with:
|
|
68
|
+
repository-url: https://test.pypi.org/legacy/
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: README preview SVGs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
paths:
|
|
7
|
+
- "src/**"
|
|
8
|
+
- "src/parch/data/configs/158x210-mos-left.toml"
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: readme-previews
|
|
12
|
+
cancel-in-progress: false
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
pull-requests: write
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
regen:
|
|
20
|
+
if: github.actor != 'github-actions[bot]'
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v7
|
|
24
|
+
- uses: astral-sh/setup-uv@v7
|
|
25
|
+
- run: uv sync --group dev
|
|
26
|
+
- name: Regenerate 158×210 sample SVGs
|
|
27
|
+
run: uv run parch preview-svg 158x210-mos-left --samples
|
|
28
|
+
- name: Open a PR when SVGs changed
|
|
29
|
+
env:
|
|
30
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
31
|
+
run: |
|
|
32
|
+
git add docs/samples/158x210-mos-left
|
|
33
|
+
if git diff --cached --quiet; then
|
|
34
|
+
echo "preview SVGs unchanged"
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
git config user.name "github-actions[bot]"
|
|
38
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
39
|
+
git switch -C chore/readme-preview-svgs
|
|
40
|
+
git commit -m "Regenerate 158×210 README preview SVGs."
|
|
41
|
+
git push --force-with-lease origin chore/readme-preview-svgs
|
|
42
|
+
existing="$(gh pr list --head chore/readme-preview-svgs --state open --json number --jq '.[0].number // empty')"
|
|
43
|
+
if [ -n "$existing" ]; then
|
|
44
|
+
echo "updated PR #$existing"
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
47
|
+
gh pr create --base master --head chore/readme-preview-svgs \
|
|
48
|
+
--title "Regenerate 158×210 README preview SVGs" \
|
|
49
|
+
--body "$(cat <<'EOF'
|
|
50
|
+
Bot-generated Typst preview SVGs for the README. Merge after CI passes.
|
|
51
|
+
|
|
52
|
+
This PR is opened instead of pushing to master so the required \`test\` check can run.
|
|
53
|
+
EOF
|
|
54
|
+
)"
|
parch-0.1.0/.gitignore
ADDED
parch-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PDF Planner Project
|
|
4
|
+
Copyright (c) 2026 Vitaliy Kudryk (original LYP)
|
|
5
|
+
|
|
6
|
+
This software is a Python port of Vitaliy Kudryk's LYP (latex yearly planner),
|
|
7
|
+
originally licensed under the MIT License (2026).
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in
|
|
17
|
+
all copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
25
|
+
THE SOFTWARE.
|
parch-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: parch
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: parch -- pages for e-ink.
|
|
5
|
+
Project-URL: Homepage, https://github.com/yyolk/parch
|
|
6
|
+
Project-URL: Repository, https://github.com/yyolk/parch
|
|
7
|
+
Project-URL: Issues, https://github.com/yyolk/parch/issues
|
|
8
|
+
Author-email: Joseph Chiocchi <joe@yolk.cc>
|
|
9
|
+
License: The MIT License (MIT)
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2026 PDF Planner Project
|
|
12
|
+
Copyright (c) 2026 Vitaliy Kudryk (original LYP)
|
|
13
|
+
|
|
14
|
+
This software is a Python port of Vitaliy Kudryk's LYP (latex yearly planner),
|
|
15
|
+
originally licensed under the MIT License (2026).
|
|
16
|
+
|
|
17
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
18
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
19
|
+
in the Software without restriction, including without limitation the rights
|
|
20
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
21
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
22
|
+
furnished to do so, subject to the following conditions:
|
|
23
|
+
|
|
24
|
+
The above copyright notice and this permission notice shall be included in
|
|
25
|
+
all copies or substantial portions of the Software.
|
|
26
|
+
|
|
27
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
28
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
29
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
30
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
31
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
32
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
33
|
+
THE SOFTWARE.
|
|
34
|
+
License-File: LICENSE
|
|
35
|
+
Keywords: e-ink,planner,supernote,typst
|
|
36
|
+
Classifier: Development Status :: 4 - Beta
|
|
37
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
38
|
+
Classifier: Programming Language :: Python
|
|
39
|
+
Classifier: Programming Language :: Python :: 3
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
41
|
+
Classifier: Topic :: Printing
|
|
42
|
+
Requires-Python: >=3.12
|
|
43
|
+
Requires-Dist: pydantic>=2.13.4
|
|
44
|
+
Requires-Dist: questionary
|
|
45
|
+
Provides-Extra: dev
|
|
46
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
# parch
|
|
50
|
+
|
|
51
|
+
**Parch** generates yearly planner PDFs for e-ink devices. Python port of Vitaliy Kudryk’s LYP: read a device profile, emit Typst, compile to PDF.
|
|
52
|
+
|
|
53
|
+
Formerly eink-planner.
|
|
54
|
+
|
|
55
|
+
This is a port of [Vitaliy Kudryk's LYP (latex-yearly-planner)](https://github.com/kudrykv/latex-yearly-planner/tree/alpha) ([fork point commit](https://github.com/kudrykv/latex-yearly-planner/commit/a59229770cfbf4a05b68a656dd70c02913a7df49), MIT, 2026). LYP generates a yearly planner by emitting **Typst**, then compiling that to **PDF**. This package keeps that architecture: Python reads a **TOML** device profile, walks calendar entities, and writes `index.typst` + `index.pdf`. It does **not** draw PDFs with reportlab/fpdf.
|
|
56
|
+
|
|
57
|
+
Default device is the **SuperNote Nomad** (A6 X2), MOS strip on the left. A Nomad MOS-right sibling, Kindle Scribe, and 158×210 MOS-left/MOS-right profiles are also shipped.
|
|
58
|
+
|
|
59
|
+
## Install
|
|
60
|
+
|
|
61
|
+
Needs [uv](https://docs.astral.sh/uv/) and Python 3.12+.
|
|
62
|
+
|
|
63
|
+
```shell
|
|
64
|
+
uv tool install parch
|
|
65
|
+
parch generate supernote-nomad
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`typst` is used to compile the PDF. If it is not on `PATH`, the compile step downloads the official Typst v0.15.1 binary for the current OS/arch into `.tools/typst` (`.tools/typst.exe` on Windows).
|
|
69
|
+
|
|
70
|
+
## Generate
|
|
71
|
+
|
|
72
|
+
```shell
|
|
73
|
+
# SuperNote Nomad 2026 (default profile, MOS-left) → ./out/index.pdf
|
|
74
|
+
uv run parch generate supernote-nomad
|
|
75
|
+
|
|
76
|
+
# SuperNote Nomad 2027 from the shipped 2026 profile (CLI overlay)
|
|
77
|
+
uv run parch generate supernote-nomad --year 2027
|
|
78
|
+
|
|
79
|
+
# SuperNote Nomad MOS-right → ./out/nomad-mos-right/index.pdf
|
|
80
|
+
uv run parch generate supernote-nomad-mos-right -w out/nomad-mos-right
|
|
81
|
+
|
|
82
|
+
# 158×210 MOS-left → ./out/mos-left/index.pdf
|
|
83
|
+
uv run parch generate 158x210-mos-left -w out/mos-left
|
|
84
|
+
|
|
85
|
+
# 158×210 MOS-left lined → ./out/mos-left-lined/index.pdf
|
|
86
|
+
uv run parch generate 158x210-mos-left-lined -w out/mos-left-lined
|
|
87
|
+
|
|
88
|
+
# 158×210 MOS-right → ./out/mos-right/index.pdf
|
|
89
|
+
uv run parch generate 158x210-mos-right -w out/mos-right
|
|
90
|
+
|
|
91
|
+
# Kindle Scribe → ./out/scribe/index.pdf
|
|
92
|
+
uv run parch generate kindle-scribe -w out/scribe
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Flags:
|
|
96
|
+
|
|
97
|
+
| Flag | Default | Meaning |
|
|
98
|
+
| --- | --- | --- |
|
|
99
|
+
| `-w` / `--workdir` | `./out` | Where `index.typst` and `index.pdf` are written |
|
|
100
|
+
| `-l` / `--locale` | `en` | Locale code |
|
|
101
|
+
| `-g` / `--with-ghostscript` | off | Optional PDF shrink via `gs` |
|
|
102
|
+
| `--debug` | off | Draw MOS debug strokes (not a config key) |
|
|
103
|
+
| `--year` | file year | Overlay planner year (dates and cover title; not a config key) |
|
|
104
|
+
|
|
105
|
+
`--year` also rewrites the cover title year when the old year is in the title.
|
|
106
|
+
|
|
107
|
+
Copy a shipped profile to start a new year or trim sections:
|
|
108
|
+
|
|
109
|
+
```shell
|
|
110
|
+
uv run parch new --from supernote-nomad --year 2027 --yes -o mine.toml
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`parch new` without `--yes` asks for starting profile, year, sections, and output path. Locale stays `parch generate -l`.
|
|
114
|
+
|
|
115
|
+
A name in the top-level `sections = ["cover", …]` list is enabled, in that order. Comment a name out of `sections` to disable it. Details live under `[section.<name>]`. There is no `enabled = true` flag, and `debug` does not belong in the profile — use `parch generate --debug`. At least one section must remain.
|
|
116
|
+
|
|
117
|
+
## Sample pages
|
|
118
|
+
|
|
119
|
+
2026 from [`158x210-mos-left`](src/parch/data/configs/158x210-mos-left.toml). MOS strip on the left. This profile ships cover, Contents, the calendar sections, and the colophon (no projects, habits, review, tasks, or meetings). Previews are Typst SVGs at half scale. Regenerate with:
|
|
120
|
+
|
|
121
|
+
```shell
|
|
122
|
+
uv run parch preview-svg 158x210-mos-left --samples
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
| Section | Page |
|
|
126
|
+
| --- | --- |
|
|
127
|
+
| Cover | <img src="docs/samples/158x210-mos-left/cover.svg" alt="Cover" width="224" /> |
|
|
128
|
+
| Contents | <img src="docs/samples/158x210-mos-left/contents.svg" alt="Contents" width="224" /> |
|
|
129
|
+
| Annual | <img src="docs/samples/158x210-mos-left/annual.svg" alt="Annual" width="224" /> |
|
|
130
|
+
| Quarterly | <img src="docs/samples/158x210-mos-left/quarterly-q1.svg" alt="Quarterly" width="224" /> |
|
|
131
|
+
| Monthly | <img src="docs/samples/158x210-mos-left/monthly-jan.svg" alt="Monthly" width="224" /> |
|
|
132
|
+
| Weekly | <img src="docs/samples/158x210-mos-left/weekly-w01.svg" alt="Weekly" width="224" /> |
|
|
133
|
+
| Daily | <img src="docs/samples/158x210-mos-left/daily-jan1.svg" alt="Daily" width="224" /> |
|
|
134
|
+
| Daily notes | <img src="docs/samples/158x210-mos-left/notes-jan1.svg" alt="Daily notes" width="224" /> |
|
|
135
|
+
| Colophon | <img src="docs/samples/158x210-mos-left/colophon.svg" alt="Colophon" width="224" /> |
|
|
136
|
+
|
|
137
|
+
## Device profiles
|
|
138
|
+
|
|
139
|
+
Sizes are 1:1 on glass at 300 PPI.
|
|
140
|
+
|
|
141
|
+
| Device | Pixels | Page (pt) | Page (mm) | Config |
|
|
142
|
+
| --- | --- | --- | --- | --- |
|
|
143
|
+
| SuperNote Nomad (A6 X2) | 1404×1872 | 336.96×449.28 | 118.87×158.5 | `supernote-nomad` |
|
|
144
|
+
| SuperNote Nomad MOS-right | 1404×1872 | 336.96×449.28 | 118.87×158.5 | `supernote-nomad-mos-right` |
|
|
145
|
+
| 158×210 MOS-left | — | 447.87×595.28 | 158×210 | `158x210-mos-left` |
|
|
146
|
+
| 158×210 MOS-left lined | — | 447.87×595.28 | 158×210 | `158x210-mos-left-lined` |
|
|
147
|
+
| 158×210 MOS-right | — | 447.87×595.28 | 158×210 | `158x210-mos-right` |
|
|
148
|
+
| Kindle Scribe | 1860×2480 | 446.4×595.2 | 157.48×209.97 | `kindle-scribe` |
|
|
149
|
+
|
|
150
|
+
Presets also live in `parch.devices`. The Nomad profile scales strokes, type, and gutters down slightly from the original 158×210 MOS-left gist so the MOS layout still fits the smaller page.
|
|
151
|
+
|
|
152
|
+
**MOS** is Months on the Side — the navigation style that places a vertical month menu on the side of the page (as opposed to a top breadcrumb trail).
|
|
153
|
+
|
|
154
|
+
Shipped configs keep the **MOS** (Months on the Side) layout: side menu on the physical left except 158×210 MOS-right and SuperNote Nomad MOS-right (physical right), reversed months/quarters, Monday week start, daily schedule 8–20, 5 priorities, 2 extra daily note pages, dotted scratch pad on most shipped configs (the 158×210 MOS-left lined sibling uses `scratch_pad = "lined"` under `[style]` with daily on-page notes still dotted). `pattern` is per notes area (dotted default; `lined` is the other option). MOS-left/MOS-right names are the physical MOS strip side (nav left / nav right), not which hand you write with. MOS-left is the right-handed writing layout (nav opposite the writing hand); MOS-right is the left-handed writing layout.
|
|
155
|
+
|
|
156
|
+
Device profiles and locale files are TOML. Config keys use underscores (`week_starts`, `side_menu`, `daily_notes`); filenames may still use hyphens (`supernote-nomad.toml`).
|
|
157
|
+
|
|
158
|
+
## Development
|
|
159
|
+
|
|
160
|
+
```shell
|
|
161
|
+
cd parch
|
|
162
|
+
uv sync
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Tests
|
|
166
|
+
|
|
167
|
+
```shell
|
|
168
|
+
uv run pytest
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
CI runs pytest and a Nomad `parch generate`. Visual design checks live in `tests/visual.py` and can be dropped with the tests that import them.
|
|
172
|
+
|
|
173
|
+
## Layout of a generated planner
|
|
174
|
+
|
|
175
|
+
Enabled MOS (Months on the Side) sections, in order:
|
|
176
|
+
|
|
177
|
+
1. Cover
|
|
178
|
+
2. Annual (12 little calendars)
|
|
179
|
+
3. Quarterly
|
|
180
|
+
4. Monthly
|
|
181
|
+
5. Weekly
|
|
182
|
+
6. Daily (schedule + little calendar + priorities + notes)
|
|
183
|
+
7. Daily notes (extra dotted pages)
|
|
184
|
+
8. Projects (index of write-in names + one kanban board per project)
|
|
185
|
+
9. Habits (index of 12 months + one habit-tracker grid per month)
|
|
186
|
+
10. Review (index of weeks + one lined leftover-notes page per week; no MOS)
|
|
187
|
+
11. Meetings (index of write-in names + one lined page per meeting)
|
|
188
|
+
12. Colophon (quiet About page)
|
|
189
|
+
|
|
190
|
+
`[section.projects]` takes optional `pages` (default 16) and `card_rows` (default 5). Only Nomad ships projects enabled.
|
|
191
|
+
`[section.habits]` takes optional `habit_columns` (default 6) and `names` (default `[]`; first N header slots are typeset, the rest stay write-in). Enabled on both Nomad profiles.
|
|
192
|
+
`[section.review]` takes optional `weeks_per_page` (default 13). The week field is lined by default and can be `pattern = "dotted"`. Listing `review` without a table uses those defaults. Enabled on both Nomad profiles after Habits.
|
|
193
|
+
`[section.meetings]` takes optional `index_pages` (default 1). Enabled on Nomad after Review.
|
|
194
|
+
|
|
195
|
+
Internal PDF links use Typst `#padded_link` / `<label>` the same way LYP does. A link is only emitted when the target page exists; otherwise the cell stays plain text.
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
MIT. This is a port of Vitaliy Kudryk's LYP (MIT 2026). See `LICENSE`.
|
parch-0.1.0/README.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# parch
|
|
2
|
+
|
|
3
|
+
**Parch** generates yearly planner PDFs for e-ink devices. Python port of Vitaliy Kudryk’s LYP: read a device profile, emit Typst, compile to PDF.
|
|
4
|
+
|
|
5
|
+
Formerly eink-planner.
|
|
6
|
+
|
|
7
|
+
This is a port of [Vitaliy Kudryk's LYP (latex-yearly-planner)](https://github.com/kudrykv/latex-yearly-planner/tree/alpha) ([fork point commit](https://github.com/kudrykv/latex-yearly-planner/commit/a59229770cfbf4a05b68a656dd70c02913a7df49), MIT, 2026). LYP generates a yearly planner by emitting **Typst**, then compiling that to **PDF**. This package keeps that architecture: Python reads a **TOML** device profile, walks calendar entities, and writes `index.typst` + `index.pdf`. It does **not** draw PDFs with reportlab/fpdf.
|
|
8
|
+
|
|
9
|
+
Default device is the **SuperNote Nomad** (A6 X2), MOS strip on the left. A Nomad MOS-right sibling, Kindle Scribe, and 158×210 MOS-left/MOS-right profiles are also shipped.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
Needs [uv](https://docs.astral.sh/uv/) and Python 3.12+.
|
|
14
|
+
|
|
15
|
+
```shell
|
|
16
|
+
uv tool install parch
|
|
17
|
+
parch generate supernote-nomad
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`typst` is used to compile the PDF. If it is not on `PATH`, the compile step downloads the official Typst v0.15.1 binary for the current OS/arch into `.tools/typst` (`.tools/typst.exe` on Windows).
|
|
21
|
+
|
|
22
|
+
## Generate
|
|
23
|
+
|
|
24
|
+
```shell
|
|
25
|
+
# SuperNote Nomad 2026 (default profile, MOS-left) → ./out/index.pdf
|
|
26
|
+
uv run parch generate supernote-nomad
|
|
27
|
+
|
|
28
|
+
# SuperNote Nomad 2027 from the shipped 2026 profile (CLI overlay)
|
|
29
|
+
uv run parch generate supernote-nomad --year 2027
|
|
30
|
+
|
|
31
|
+
# SuperNote Nomad MOS-right → ./out/nomad-mos-right/index.pdf
|
|
32
|
+
uv run parch generate supernote-nomad-mos-right -w out/nomad-mos-right
|
|
33
|
+
|
|
34
|
+
# 158×210 MOS-left → ./out/mos-left/index.pdf
|
|
35
|
+
uv run parch generate 158x210-mos-left -w out/mos-left
|
|
36
|
+
|
|
37
|
+
# 158×210 MOS-left lined → ./out/mos-left-lined/index.pdf
|
|
38
|
+
uv run parch generate 158x210-mos-left-lined -w out/mos-left-lined
|
|
39
|
+
|
|
40
|
+
# 158×210 MOS-right → ./out/mos-right/index.pdf
|
|
41
|
+
uv run parch generate 158x210-mos-right -w out/mos-right
|
|
42
|
+
|
|
43
|
+
# Kindle Scribe → ./out/scribe/index.pdf
|
|
44
|
+
uv run parch generate kindle-scribe -w out/scribe
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Flags:
|
|
48
|
+
|
|
49
|
+
| Flag | Default | Meaning |
|
|
50
|
+
| --- | --- | --- |
|
|
51
|
+
| `-w` / `--workdir` | `./out` | Where `index.typst` and `index.pdf` are written |
|
|
52
|
+
| `-l` / `--locale` | `en` | Locale code |
|
|
53
|
+
| `-g` / `--with-ghostscript` | off | Optional PDF shrink via `gs` |
|
|
54
|
+
| `--debug` | off | Draw MOS debug strokes (not a config key) |
|
|
55
|
+
| `--year` | file year | Overlay planner year (dates and cover title; not a config key) |
|
|
56
|
+
|
|
57
|
+
`--year` also rewrites the cover title year when the old year is in the title.
|
|
58
|
+
|
|
59
|
+
Copy a shipped profile to start a new year or trim sections:
|
|
60
|
+
|
|
61
|
+
```shell
|
|
62
|
+
uv run parch new --from supernote-nomad --year 2027 --yes -o mine.toml
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`parch new` without `--yes` asks for starting profile, year, sections, and output path. Locale stays `parch generate -l`.
|
|
66
|
+
|
|
67
|
+
A name in the top-level `sections = ["cover", …]` list is enabled, in that order. Comment a name out of `sections` to disable it. Details live under `[section.<name>]`. There is no `enabled = true` flag, and `debug` does not belong in the profile — use `parch generate --debug`. At least one section must remain.
|
|
68
|
+
|
|
69
|
+
## Sample pages
|
|
70
|
+
|
|
71
|
+
2026 from [`158x210-mos-left`](src/parch/data/configs/158x210-mos-left.toml). MOS strip on the left. This profile ships cover, Contents, the calendar sections, and the colophon (no projects, habits, review, tasks, or meetings). Previews are Typst SVGs at half scale. Regenerate with:
|
|
72
|
+
|
|
73
|
+
```shell
|
|
74
|
+
uv run parch preview-svg 158x210-mos-left --samples
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
| Section | Page |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| Cover | <img src="docs/samples/158x210-mos-left/cover.svg" alt="Cover" width="224" /> |
|
|
80
|
+
| Contents | <img src="docs/samples/158x210-mos-left/contents.svg" alt="Contents" width="224" /> |
|
|
81
|
+
| Annual | <img src="docs/samples/158x210-mos-left/annual.svg" alt="Annual" width="224" /> |
|
|
82
|
+
| Quarterly | <img src="docs/samples/158x210-mos-left/quarterly-q1.svg" alt="Quarterly" width="224" /> |
|
|
83
|
+
| Monthly | <img src="docs/samples/158x210-mos-left/monthly-jan.svg" alt="Monthly" width="224" /> |
|
|
84
|
+
| Weekly | <img src="docs/samples/158x210-mos-left/weekly-w01.svg" alt="Weekly" width="224" /> |
|
|
85
|
+
| Daily | <img src="docs/samples/158x210-mos-left/daily-jan1.svg" alt="Daily" width="224" /> |
|
|
86
|
+
| Daily notes | <img src="docs/samples/158x210-mos-left/notes-jan1.svg" alt="Daily notes" width="224" /> |
|
|
87
|
+
| Colophon | <img src="docs/samples/158x210-mos-left/colophon.svg" alt="Colophon" width="224" /> |
|
|
88
|
+
|
|
89
|
+
## Device profiles
|
|
90
|
+
|
|
91
|
+
Sizes are 1:1 on glass at 300 PPI.
|
|
92
|
+
|
|
93
|
+
| Device | Pixels | Page (pt) | Page (mm) | Config |
|
|
94
|
+
| --- | --- | --- | --- | --- |
|
|
95
|
+
| SuperNote Nomad (A6 X2) | 1404×1872 | 336.96×449.28 | 118.87×158.5 | `supernote-nomad` |
|
|
96
|
+
| SuperNote Nomad MOS-right | 1404×1872 | 336.96×449.28 | 118.87×158.5 | `supernote-nomad-mos-right` |
|
|
97
|
+
| 158×210 MOS-left | — | 447.87×595.28 | 158×210 | `158x210-mos-left` |
|
|
98
|
+
| 158×210 MOS-left lined | — | 447.87×595.28 | 158×210 | `158x210-mos-left-lined` |
|
|
99
|
+
| 158×210 MOS-right | — | 447.87×595.28 | 158×210 | `158x210-mos-right` |
|
|
100
|
+
| Kindle Scribe | 1860×2480 | 446.4×595.2 | 157.48×209.97 | `kindle-scribe` |
|
|
101
|
+
|
|
102
|
+
Presets also live in `parch.devices`. The Nomad profile scales strokes, type, and gutters down slightly from the original 158×210 MOS-left gist so the MOS layout still fits the smaller page.
|
|
103
|
+
|
|
104
|
+
**MOS** is Months on the Side — the navigation style that places a vertical month menu on the side of the page (as opposed to a top breadcrumb trail).
|
|
105
|
+
|
|
106
|
+
Shipped configs keep the **MOS** (Months on the Side) layout: side menu on the physical left except 158×210 MOS-right and SuperNote Nomad MOS-right (physical right), reversed months/quarters, Monday week start, daily schedule 8–20, 5 priorities, 2 extra daily note pages, dotted scratch pad on most shipped configs (the 158×210 MOS-left lined sibling uses `scratch_pad = "lined"` under `[style]` with daily on-page notes still dotted). `pattern` is per notes area (dotted default; `lined` is the other option). MOS-left/MOS-right names are the physical MOS strip side (nav left / nav right), not which hand you write with. MOS-left is the right-handed writing layout (nav opposite the writing hand); MOS-right is the left-handed writing layout.
|
|
107
|
+
|
|
108
|
+
Device profiles and locale files are TOML. Config keys use underscores (`week_starts`, `side_menu`, `daily_notes`); filenames may still use hyphens (`supernote-nomad.toml`).
|
|
109
|
+
|
|
110
|
+
## Development
|
|
111
|
+
|
|
112
|
+
```shell
|
|
113
|
+
cd parch
|
|
114
|
+
uv sync
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Tests
|
|
118
|
+
|
|
119
|
+
```shell
|
|
120
|
+
uv run pytest
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
CI runs pytest and a Nomad `parch generate`. Visual design checks live in `tests/visual.py` and can be dropped with the tests that import them.
|
|
124
|
+
|
|
125
|
+
## Layout of a generated planner
|
|
126
|
+
|
|
127
|
+
Enabled MOS (Months on the Side) sections, in order:
|
|
128
|
+
|
|
129
|
+
1. Cover
|
|
130
|
+
2. Annual (12 little calendars)
|
|
131
|
+
3. Quarterly
|
|
132
|
+
4. Monthly
|
|
133
|
+
5. Weekly
|
|
134
|
+
6. Daily (schedule + little calendar + priorities + notes)
|
|
135
|
+
7. Daily notes (extra dotted pages)
|
|
136
|
+
8. Projects (index of write-in names + one kanban board per project)
|
|
137
|
+
9. Habits (index of 12 months + one habit-tracker grid per month)
|
|
138
|
+
10. Review (index of weeks + one lined leftover-notes page per week; no MOS)
|
|
139
|
+
11. Meetings (index of write-in names + one lined page per meeting)
|
|
140
|
+
12. Colophon (quiet About page)
|
|
141
|
+
|
|
142
|
+
`[section.projects]` takes optional `pages` (default 16) and `card_rows` (default 5). Only Nomad ships projects enabled.
|
|
143
|
+
`[section.habits]` takes optional `habit_columns` (default 6) and `names` (default `[]`; first N header slots are typeset, the rest stay write-in). Enabled on both Nomad profiles.
|
|
144
|
+
`[section.review]` takes optional `weeks_per_page` (default 13). The week field is lined by default and can be `pattern = "dotted"`. Listing `review` without a table uses those defaults. Enabled on both Nomad profiles after Habits.
|
|
145
|
+
`[section.meetings]` takes optional `index_pages` (default 1). Enabled on Nomad after Review.
|
|
146
|
+
|
|
147
|
+
Internal PDF links use Typst `#padded_link` / `<label>` the same way LYP does. A link is only emitted when the target page exists; otherwise the cell stays plain text.
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
|
|
151
|
+
MIT. This is a port of Vitaliy Kudryk's LYP (MIT 2026). See `LICENSE`.
|