stemma-studio 0.4.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.
- stemma_studio-0.4.0/LICENSE +21 -0
- stemma_studio-0.4.0/PKG-INFO +276 -0
- stemma_studio-0.4.0/README.md +256 -0
- stemma_studio-0.4.0/pyproject.toml +63 -0
- stemma_studio-0.4.0/setup.cfg +4 -0
- stemma_studio-0.4.0/src/stemma_studio/__init__.py +10 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/__init__.py +1 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/admin.py +1604 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/admin_frontend/admin.css +115 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/admin_frontend/admin.js +668 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/admin_frontend/buffer.js +25 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/admin_frontend/flow.js +325 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/admin_frontend/i18n.js +28 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/admin_frontend/index.html +134 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/admin_server.py +273 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/attachments.py +57 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/author_preview.py +139 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/deploy.py +305 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/footnotes.py +56 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/frontend/fonts/MaruBuri-Bold.woff2 +0 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/frontend/fonts/MaruBuri-Regular.woff2 +0 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/frontend/fonts/OFL.txt +114 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/frontend/fonts/README.md +11 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/frontend/site.css +60 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/frontend/site.js +110 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/frontend/studio-header.css +15 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/frontend/theme.css +4 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/homepage.py +344 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/input.py +139 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/local_folder.py +226 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/markdown.py +115 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/math-render.cjs +14 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/math_support.py +60 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/preview.py +153 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/render.py +449 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/sample/public-v3.json +347 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/site_settings.py +172 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/KATEX-LICENSE +21 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/MISTUNE-LICENSE +14 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/README.md +14 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/__init__.py +1 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/katex/katex.cjs +17741 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/__init__.py +81 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/__main__.py +124 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/block_parser.py +486 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/core.py +209 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/directives/__init__.py +31 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/directives/_base.py +121 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/directives/_fenced.py +142 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/directives/_rst.py +73 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/directives/admonition.py +61 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/directives/image.py +152 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/directives/include.py +65 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/directives/toc.py +105 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/helpers.py +137 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/inline_parser.py +390 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/list_parser.py +254 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/markdown.py +110 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/__init__.py +38 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/abbr.py +103 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/def_list.py +135 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/footnotes.py +153 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/formatting.py +173 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/math.py +57 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/ruby.py +100 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/speedup.py +44 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/spoiler.py +80 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/table.py +179 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/task_lists.py +67 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/plugins/url.py +23 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/renderers/__init__.py +0 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/renderers/_list.py +60 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/renderers/html.py +151 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/renderers/markdown.py +146 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/renderers/rst.py +147 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/toc.py +111 -0
- stemma_studio-0.4.0/src/stemma_studio/blog/vendor/mistune/util.py +81 -0
- stemma_studio-0.4.0/src/stemma_studio/cli.py +178 -0
- stemma_studio-0.4.0/src/stemma_studio/core/__init__.py +1 -0
- stemma_studio-0.4.0/src/stemma_studio/core/__main__.py +175 -0
- stemma_studio-0.4.0/src/stemma_studio/core/adapters.py +33 -0
- stemma_studio-0.4.0/src/stemma_studio/core/application.py +357 -0
- stemma_studio-0.4.0/src/stemma_studio/core/archive_sync.py +305 -0
- stemma_studio-0.4.0/src/stemma_studio/core/blog.py +313 -0
- stemma_studio-0.4.0/src/stemma_studio/core/containment.py +50 -0
- stemma_studio-0.4.0/src/stemma_studio/core/disclosure.py +190 -0
- stemma_studio-0.4.0/src/stemma_studio/core/domain.py +221 -0
- stemma_studio-0.4.0/src/stemma_studio/core/editing.py +65 -0
- stemma_studio-0.4.0/src/stemma_studio/core/folder_import.py +353 -0
- stemma_studio-0.4.0/src/stemma_studio/core/migrations.py +59 -0
- stemma_studio-0.4.0/src/stemma_studio/core/public_assets.py +57 -0
- stemma_studio-0.4.0/src/stemma_studio/core/publication.py +194 -0
- stemma_studio-0.4.0/src/stemma_studio/core/releases.py +168 -0
- stemma_studio-0.4.0/src/stemma_studio/core/repository.py +196 -0
- stemma_studio-0.4.0/src/stemma_studio/core/uploads.py +158 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/__init__.py +1 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/frontend/app.js +495 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/frontend/feedback.js +60 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/frontend/genealogy-layout.js +46 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/frontend/genealogy.css +3 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/frontend/genealogy.html +10 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/frontend/genealogy.js +106 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/frontend/i18n.js +28 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/frontend/index.html +18 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/frontend/style.css +19 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/frontend/work-buffer.js +42 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/server.py +221 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/service.py +424 -0
- stemma_studio-0.4.0/src/stemma_studio/editor/workspace_server.py +67 -0
- stemma_studio-0.4.0/src/stemma_studio/locale/__init__.py +159 -0
- stemma_studio-0.4.0/src/stemma_studio/locale/en.json +697 -0
- stemma_studio-0.4.0/src/stemma_studio/locale/ko.json +697 -0
- stemma_studio-0.4.0/src/stemma_studio.egg-info/PKG-INFO +276 -0
- stemma_studio-0.4.0/src/stemma_studio.egg-info/SOURCES.txt +141 -0
- stemma_studio-0.4.0/src/stemma_studio.egg-info/dependency_links.txt +1 -0
- stemma_studio-0.4.0/src/stemma_studio.egg-info/entry_points.txt +2 -0
- stemma_studio-0.4.0/src/stemma_studio.egg-info/requires.txt +4 -0
- stemma_studio-0.4.0/src/stemma_studio.egg-info/top_level.txt +1 -0
- stemma_studio-0.4.0/tests/test_archive_sync.py +330 -0
- stemma_studio-0.4.0/tests/test_archiving.py +227 -0
- stemma_studio-0.4.0/tests/test_blog_admin.py +812 -0
- stemma_studio-0.4.0/tests/test_blog_attachments.py +107 -0
- stemma_studio-0.4.0/tests/test_blog_contract.py +208 -0
- stemma_studio-0.4.0/tests/test_blog_footnotes.py +45 -0
- stemma_studio-0.4.0/tests/test_blog_model.py +356 -0
- stemma_studio-0.4.0/tests/test_blog_release.py +255 -0
- stemma_studio-0.4.0/tests/test_blog_site.py +355 -0
- stemma_studio-0.4.0/tests/test_blog_typography.py +182 -0
- stemma_studio-0.4.0/tests/test_containment.py +56 -0
- stemma_studio-0.4.0/tests/test_editor.py +418 -0
- stemma_studio-0.4.0/tests/test_folder_import.py +368 -0
- stemma_studio-0.4.0/tests/test_graph_core.py +158 -0
- stemma_studio-0.4.0/tests/test_homepage.py +154 -0
- stemma_studio-0.4.0/tests/test_interface_access.py +63 -0
- stemma_studio-0.4.0/tests/test_local_folder.py +569 -0
- stemma_studio-0.4.0/tests/test_locale.py +199 -0
- stemma_studio-0.4.0/tests/test_model.py +197 -0
- stemma_studio-0.4.0/tests/test_package_layout.py +198 -0
- stemma_studio-0.4.0/tests/test_publication_v3.py +355 -0
- stemma_studio-0.4.0/tests/test_site_settings.py +214 -0
- stemma_studio-0.4.0/tests/test_uploads.py +259 -0
- stemma_studio-0.4.0/tests/test_workspace_server.py +111 -0
- stemma_studio-0.4.0/tests/test_writing_language.py +277 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Byeongsu Yu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stemma-studio
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Writing that descends from earlier writing: a local desk, a genealogy of versions, and a bilingual static blog
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/byeongsuyu/stemma
|
|
7
|
+
Project-URL: Source, https://github.com/byeongsuyu/stemma
|
|
8
|
+
Keywords: writing,blog,static-site,genealogy,stemma,markdown
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
13
|
+
Requires-Python: >=3.12
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: stemma-graph<0.4.0,>=0.3.0
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# Stemma
|
|
22
|
+
|
|
23
|
+
**English** · [한국어](https://github.com/byeongsuyu/stemma/blob/main/README.ko.md)
|
|
24
|
+
|
|
25
|
+
A local writing desk for people who rewrite. You keep a private archive of
|
|
26
|
+
everything you have written, find an old piece, write a new one that carries it
|
|
27
|
+
forward, and publish the versions you choose as a bilingual static blog — with
|
|
28
|
+
the lineage from the old piece to the new one preserved and, if you want,
|
|
29
|
+
visible to readers.
|
|
30
|
+
|
|
31
|
+
It runs entirely on your own machine. Nothing is uploaded except the static
|
|
32
|
+
site you explicitly deploy.
|
|
33
|
+
|
|
34
|
+
> A *stemma codicum* is the diagram textual scholars draw to show which
|
|
35
|
+
> manuscript descends from which. This tool builds one for your own writing.
|
|
36
|
+
|
|
37
|
+
> The interface speaks Korean or English — switch it from the top bar. The
|
|
38
|
+
> documentation, the code and the command line are in English. Published sites
|
|
39
|
+
> are Korean/English pairs: you write in one of the two languages and translate
|
|
40
|
+
> into the other.
|
|
41
|
+
|
|
42
|
+
## What makes it different
|
|
43
|
+
|
|
44
|
+
Most blogging tools treat a post as a standalone artifact. Stemma treats it as
|
|
45
|
+
a **succession**: this piece came out of that one, in answer to a particular
|
|
46
|
+
question. That relationship is first-class data.
|
|
47
|
+
|
|
48
|
+
- **Questions** are what you are asking. A document belongs to one or more.
|
|
49
|
+
- **Succession edges** record that one document grew out of another.
|
|
50
|
+
- **Revisions** are immutable. Editing never overwrites what you wrote before.
|
|
51
|
+
- **Publication pairs** are a reviewed Korean + English version of a document:
|
|
52
|
+
the revision in the language you write in, and its translation. You publish a
|
|
53
|
+
pair, never a bare revision.
|
|
54
|
+
- **Genealogy** is the resulting graph, which readers can explore on the
|
|
55
|
+
published site.
|
|
56
|
+
|
|
57
|
+
## Requirements
|
|
58
|
+
|
|
59
|
+
- Python 3.12 or newer. The core, the editor and the blog use only the standard
|
|
60
|
+
library.
|
|
61
|
+
- Node.js, **only** if you publish posts containing mathematics. KaTeX renders
|
|
62
|
+
formulas to static MathML at build time; readers never run it. See
|
|
63
|
+
`src/stemma_studio/blog/math_support.py`.
|
|
64
|
+
- Git, only if you import from a Git archive or deploy through a pull request.
|
|
65
|
+
Publishing to a folder needs neither.
|
|
66
|
+
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
python3.12 -m venv .venv
|
|
71
|
+
.venv/bin/pip install ./packages/stemma_graph .
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
That gives you the `stemma` command. Once the packages are published, this
|
|
75
|
+
becomes `pip install stemma-studio`, which will pull in `stemma-graph` with it;
|
|
76
|
+
until then, install from a checkout as above.
|
|
77
|
+
|
|
78
|
+
To work on the code, you can run everything from a checkout with no install at
|
|
79
|
+
all:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
python3.12 -B scripts/dev.py test # the Python suite
|
|
83
|
+
python3.12 -B scripts/dev.py example # the genealogy library on its own
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Quick start
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
mkdir my-writing && cd my-writing
|
|
90
|
+
stemma init # creates data/studio.json here
|
|
91
|
+
stemma editor # http://127.0.0.1:8787
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`init` creates an empty data root in the current folder. Every command takes
|
|
95
|
+
`--root` if you want to keep your data somewhere else; without it, the current
|
|
96
|
+
working directory is the root.
|
|
97
|
+
|
|
98
|
+
To see what a published site looks like before you have written anything, run
|
|
99
|
+
`stemma preview` and open <http://127.0.0.1:8766/blog/>. It serves a
|
|
100
|
+
synthetic sample from memory and writes nothing.
|
|
101
|
+
|
|
102
|
+
## The workflow
|
|
103
|
+
|
|
104
|
+
Everything happens on one local server, in four steps:
|
|
105
|
+
|
|
106
|
+
| | Step | Where |
|
|
107
|
+
|---|---|---|
|
|
108
|
+
| 1 | **Set up your blog** — its name, byline, the language you write in and the licence on your writing | Settings screen at `/publish/?view=settings` |
|
|
109
|
+
| 2 | **Import** what you have already written, then **write** | Import, then the editor at `/` |
|
|
110
|
+
| 3 | **Publish** — add the translation, review the pair, confirm it | Publication screen at `/publish/` |
|
|
111
|
+
| 4 | **Deploy** — write the site to a folder, or open one pull request | Site screen at `/publish/?view=site` |
|
|
112
|
+
|
|
113
|
+
Then read it on your own site. Step 1 is worth doing first: until you do, pages
|
|
114
|
+
publish under placeholder names, your writing reserves all rights by default,
|
|
115
|
+
and a new data root cannot publish at all until you have said which language
|
|
116
|
+
you write in.
|
|
117
|
+
|
|
118
|
+
## Setting up your blog
|
|
119
|
+
|
|
120
|
+
Your blog's name, byline and tagline, the language you write in, and the
|
|
121
|
+
licence your writing carries, are configuration rather than code — one installed
|
|
122
|
+
copy can publish anybody's blog. Set them on the **Settings** screen under
|
|
123
|
+
**Blog settings**, which writes `data/blog/site.json`.
|
|
124
|
+
|
|
125
|
+
The language you write in decides which side of each pair is the original. Write
|
|
126
|
+
in Korean and you add an English translation; write in English and you add a
|
|
127
|
+
Korean one. A post keeps the side it was first published or translated from, so
|
|
128
|
+
changing this later never turns round a post you have already started. That screen holds what you decide once — the blog's
|
|
129
|
+
identity and where it deploys to — apart from the site screen, which is what you
|
|
130
|
+
check each time you publish.
|
|
131
|
+
|
|
132
|
+
Note that two different licences meet on a published page:
|
|
133
|
+
|
|
134
|
+
- **This tool is MIT.** See [LICENSE](https://github.com/byeongsuyu/stemma/blob/main/LICENSE). That covers the software.
|
|
135
|
+
- **Your writing is yours.** Its terms are a setting, defaulting to reserving
|
|
136
|
+
all rights. Presets for the Creative Commons licences and CC0 are offered,
|
|
137
|
+
or you can write your own wording. Nothing gives your readers rights you did
|
|
138
|
+
not choose.
|
|
139
|
+
|
|
140
|
+
See [docs/site-settings.md](https://github.com/byeongsuyu/stemma/blob/main/docs/site-settings.md).
|
|
141
|
+
|
|
142
|
+
## Writing
|
|
143
|
+
|
|
144
|
+
The editor at <http://127.0.0.1:8787> has three panes: search your archive,
|
|
145
|
+
read the sources you picked, and write. When you save, Stemma stores an
|
|
146
|
+
immutable revision and asks which parent documents this one carries forward,
|
|
147
|
+
and under which question.
|
|
148
|
+
|
|
149
|
+
**Add pictures or files** attaches pictures — several at once — storing each under its own
|
|
150
|
+
content hash and writing the Markdown link where your cursor is.
|
|
151
|
+
|
|
152
|
+
The same server hosts the publication screens at `/publish/`, where you add the
|
|
153
|
+
translation of a post, review the pair, and confirm it for publication. The
|
|
154
|
+
`/publish/?view=site` screen shows everything that would change on the live
|
|
155
|
+
site and deploys it.
|
|
156
|
+
|
|
157
|
+
The model's own workflow is available on the command line:
|
|
158
|
+
|
|
159
|
+
| Command | What it does |
|
|
160
|
+
|---|---|
|
|
161
|
+
| `create` | Start a draft, with repeated `--parent` and `--question` |
|
|
162
|
+
| `revise` | Store an input file as a new immutable revision |
|
|
163
|
+
| `confirm` | Confirm a document and its proposed successions |
|
|
164
|
+
| `archive` / `restore` | Retire a document from future use, or bring it back |
|
|
165
|
+
| `represent` | Choose which documents represent a question |
|
|
166
|
+
| `publish --pair` | Select a reviewed Korean/English pair locally |
|
|
167
|
+
| `unpublish` | Clear that selection |
|
|
168
|
+
| `export-public --planned-at` | Print the prospective public payload as JSON |
|
|
169
|
+
| `validate` | Check metadata and content hashes |
|
|
170
|
+
|
|
171
|
+
Run `stemma <command> --help` for the arguments. `publish` records a
|
|
172
|
+
local choice; it never uploads anything. Deployment is a separate, explicit
|
|
173
|
+
step. Global options come before the subcommand: `stemma --root . validate`.
|
|
174
|
+
|
|
175
|
+
Some work happens only in the editor and publication screens: writing a
|
|
176
|
+
question, preparing and reviewing a translation pair, attaching a file, and
|
|
177
|
+
importing a folder. `create` needs a question that already exists, so a fresh
|
|
178
|
+
data root is set up through the editor rather than the command line alone.
|
|
179
|
+
|
|
180
|
+
## Importing your existing writing
|
|
181
|
+
|
|
182
|
+
Open **Import** and give it the folder your writing lives in. It reads the
|
|
183
|
+
folder — never modifies it — and shows exactly what it would import before
|
|
184
|
+
anything is saved.
|
|
185
|
+
|
|
186
|
+
**Picture links are not rewritten.** A picture is recorded at the path it
|
|
187
|
+
occupies relative to the post that references it, so `` and
|
|
188
|
+
`` keep working as written. That is why it takes a
|
|
189
|
+
folder: the folder's shape is what makes the links resolve.
|
|
190
|
+
|
|
191
|
+
If your writing lives in a Git repository you keep updating, a second route
|
|
192
|
+
tracks it by commit:
|
|
193
|
+
|
|
194
|
+
```sh
|
|
195
|
+
stemma sync-archive --archive /absolute/path/to/your-archive
|
|
196
|
+
stemma sync-archive --dry-run # later runs remember the path
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Both are read-only and append-only. See [docs/importing.md](https://github.com/byeongsuyu/stemma/blob/main/docs/importing.md).
|
|
200
|
+
|
|
201
|
+
Already have writing in a Stemma data root? Do not import it — point the tool
|
|
202
|
+
at it: `stemma --root /path/containing/data editor`. See
|
|
203
|
+
[docs/moving-in.md](https://github.com/byeongsuyu/stemma/blob/main/docs/moving-in.md).
|
|
204
|
+
|
|
205
|
+
## Publishing
|
|
206
|
+
|
|
207
|
+
Deployment builds the static site and sends it to one destination, chosen on
|
|
208
|
+
the site screen:
|
|
209
|
+
|
|
210
|
+
- **A local folder** (default) — writes the finished site to a folder you name.
|
|
211
|
+
No account and nothing to wait for. Move that folder wherever you like: any
|
|
212
|
+
static host, `rsync`, an object store, a USB stick. Files this tool did not
|
|
213
|
+
write are never touched.
|
|
214
|
+
- **A GitHub Pages pull request** — opens a PR against a Pages repository you
|
|
215
|
+
control, so you see the diff before it goes live. Needs the `gh` CLI.
|
|
216
|
+
|
|
217
|
+
The folder is the general case and the reason the tool is not tied to one
|
|
218
|
+
service. See [docs/publishing.md](https://github.com/byeongsuyu/stemma/blob/main/docs/publishing.md).
|
|
219
|
+
|
|
220
|
+
## Layout
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
packages/stemma_graph/ pip: stemma-graph the genealogy graph, stdlib only
|
|
224
|
+
examples/ a runnable demo of the graph on its own
|
|
225
|
+
src/stemma_studio/ pip: stemma-studio installs the `stemma` command
|
|
226
|
+
core/ the model, storage, archive sync and publication rules
|
|
227
|
+
blog/ Markdown rendering, the reader's site, publication admin, deploy
|
|
228
|
+
editor/ the writing desk, which mounts the blog's publication screens
|
|
229
|
+
cli.py the stemma command
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The dependency direction runs one way — `core` imports neither sibling, and
|
|
233
|
+
`blog` never imports `editor`. A test enforces it. `stemma-graph` is a
|
|
234
|
+
separate package because it is useful on its own and depends on nothing; you
|
|
235
|
+
can install it alone if all you want is the graph.
|
|
236
|
+
|
|
237
|
+
Neither distribution needs a third-party package installed alongside it, beyond
|
|
238
|
+
Studio's dependency on `stemma-graph`. Studio is not pure standard library
|
|
239
|
+
though: it ships vendored copies of mistune and KaTeX inside the wheel, under
|
|
240
|
+
their own licences.
|
|
241
|
+
|
|
242
|
+
Your writing lives in the data root, never in the package: `data/studio.json`
|
|
243
|
+
holds the metadata, with preserved copies under `imports/`, `revisions/`,
|
|
244
|
+
`assets/` and `translations/`. No personal data is included in either wheel.
|
|
245
|
+
|
|
246
|
+
## Documentation
|
|
247
|
+
|
|
248
|
+
| Document | Read it for |
|
|
249
|
+
|---|---|
|
|
250
|
+
| [Design](https://github.com/byeongsuyu/stemma/blob/main/docs/design.md) | The rules for documents, succession, retirement and publication, and why they hold |
|
|
251
|
+
| [Code tour](https://github.com/byeongsuyu/stemma/blob/main/docs/code-tour.md) | Where code lives, entry points, and how to run it |
|
|
252
|
+
| [Editor](https://github.com/byeongsuyu/stemma/blob/main/docs/editor.md) | The writing desk, and its save and recovery boundaries |
|
|
253
|
+
| [Publishing](https://github.com/byeongsuyu/stemma/blob/main/docs/publishing.md) | Bilingual publication, releases and deployment |
|
|
254
|
+
| [Importing](https://github.com/byeongsuyu/stemma/blob/main/docs/importing.md) | Bringing your existing writing in, by folder or from Git |
|
|
255
|
+
| [Site settings](https://github.com/byeongsuyu/stemma/blob/main/docs/site-settings.md) | Naming your blog, and licensing your writing |
|
|
256
|
+
| [Moving in](https://github.com/byeongsuyu/stemma/blob/main/docs/moving-in.md) | Bringing an existing data root into a new install |
|
|
257
|
+
| [Contributing](https://github.com/byeongsuyu/stemma/blob/main/CONTRIBUTING.md) | Tests, style and the rules a change must keep |
|
|
258
|
+
|
|
259
|
+
## Status
|
|
260
|
+
|
|
261
|
+
This is one person's tool, published in case it is useful to others. It assumes
|
|
262
|
+
a single local author and does not enforce that assumption: each running server
|
|
263
|
+
serializes its own requests, but nothing coordinates between two servers, or
|
|
264
|
+
between a server and the command line. Do not run two of them against one data
|
|
265
|
+
root.
|
|
266
|
+
|
|
267
|
+
## License
|
|
268
|
+
|
|
269
|
+
The **code** is MIT — see [LICENSE](https://github.com/byeongsuyu/stemma/blob/main/LICENSE). Bundled third-party code keeps
|
|
270
|
+
its own licence: mistune (BSD-3-Clause), KaTeX (MIT) and the MaruBuri font
|
|
271
|
+
(SIL OFL 1.1). See `src/stemma_studio/blog/vendor/README.md` and
|
|
272
|
+
`src/stemma_studio/blog/frontend/fonts/README.md`.
|
|
273
|
+
|
|
274
|
+
The **writing** you publish with it is not covered by that licence. Its terms
|
|
275
|
+
are yours to choose, in the blog settings; see
|
|
276
|
+
[docs/site-settings.md](https://github.com/byeongsuyu/stemma/blob/main/docs/site-settings.md).
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# Stemma
|
|
2
|
+
|
|
3
|
+
**English** · [한국어](https://github.com/byeongsuyu/stemma/blob/main/README.ko.md)
|
|
4
|
+
|
|
5
|
+
A local writing desk for people who rewrite. You keep a private archive of
|
|
6
|
+
everything you have written, find an old piece, write a new one that carries it
|
|
7
|
+
forward, and publish the versions you choose as a bilingual static blog — with
|
|
8
|
+
the lineage from the old piece to the new one preserved and, if you want,
|
|
9
|
+
visible to readers.
|
|
10
|
+
|
|
11
|
+
It runs entirely on your own machine. Nothing is uploaded except the static
|
|
12
|
+
site you explicitly deploy.
|
|
13
|
+
|
|
14
|
+
> A *stemma codicum* is the diagram textual scholars draw to show which
|
|
15
|
+
> manuscript descends from which. This tool builds one for your own writing.
|
|
16
|
+
|
|
17
|
+
> The interface speaks Korean or English — switch it from the top bar. The
|
|
18
|
+
> documentation, the code and the command line are in English. Published sites
|
|
19
|
+
> are Korean/English pairs: you write in one of the two languages and translate
|
|
20
|
+
> into the other.
|
|
21
|
+
|
|
22
|
+
## What makes it different
|
|
23
|
+
|
|
24
|
+
Most blogging tools treat a post as a standalone artifact. Stemma treats it as
|
|
25
|
+
a **succession**: this piece came out of that one, in answer to a particular
|
|
26
|
+
question. That relationship is first-class data.
|
|
27
|
+
|
|
28
|
+
- **Questions** are what you are asking. A document belongs to one or more.
|
|
29
|
+
- **Succession edges** record that one document grew out of another.
|
|
30
|
+
- **Revisions** are immutable. Editing never overwrites what you wrote before.
|
|
31
|
+
- **Publication pairs** are a reviewed Korean + English version of a document:
|
|
32
|
+
the revision in the language you write in, and its translation. You publish a
|
|
33
|
+
pair, never a bare revision.
|
|
34
|
+
- **Genealogy** is the resulting graph, which readers can explore on the
|
|
35
|
+
published site.
|
|
36
|
+
|
|
37
|
+
## Requirements
|
|
38
|
+
|
|
39
|
+
- Python 3.12 or newer. The core, the editor and the blog use only the standard
|
|
40
|
+
library.
|
|
41
|
+
- Node.js, **only** if you publish posts containing mathematics. KaTeX renders
|
|
42
|
+
formulas to static MathML at build time; readers never run it. See
|
|
43
|
+
`src/stemma_studio/blog/math_support.py`.
|
|
44
|
+
- Git, only if you import from a Git archive or deploy through a pull request.
|
|
45
|
+
Publishing to a folder needs neither.
|
|
46
|
+
|
|
47
|
+
## Install
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
python3.12 -m venv .venv
|
|
51
|
+
.venv/bin/pip install ./packages/stemma_graph .
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
That gives you the `stemma` command. Once the packages are published, this
|
|
55
|
+
becomes `pip install stemma-studio`, which will pull in `stemma-graph` with it;
|
|
56
|
+
until then, install from a checkout as above.
|
|
57
|
+
|
|
58
|
+
To work on the code, you can run everything from a checkout with no install at
|
|
59
|
+
all:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
python3.12 -B scripts/dev.py test # the Python suite
|
|
63
|
+
python3.12 -B scripts/dev.py example # the genealogy library on its own
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Quick start
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
mkdir my-writing && cd my-writing
|
|
70
|
+
stemma init # creates data/studio.json here
|
|
71
|
+
stemma editor # http://127.0.0.1:8787
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`init` creates an empty data root in the current folder. Every command takes
|
|
75
|
+
`--root` if you want to keep your data somewhere else; without it, the current
|
|
76
|
+
working directory is the root.
|
|
77
|
+
|
|
78
|
+
To see what a published site looks like before you have written anything, run
|
|
79
|
+
`stemma preview` and open <http://127.0.0.1:8766/blog/>. It serves a
|
|
80
|
+
synthetic sample from memory and writes nothing.
|
|
81
|
+
|
|
82
|
+
## The workflow
|
|
83
|
+
|
|
84
|
+
Everything happens on one local server, in four steps:
|
|
85
|
+
|
|
86
|
+
| | Step | Where |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| 1 | **Set up your blog** — its name, byline, the language you write in and the licence on your writing | Settings screen at `/publish/?view=settings` |
|
|
89
|
+
| 2 | **Import** what you have already written, then **write** | Import, then the editor at `/` |
|
|
90
|
+
| 3 | **Publish** — add the translation, review the pair, confirm it | Publication screen at `/publish/` |
|
|
91
|
+
| 4 | **Deploy** — write the site to a folder, or open one pull request | Site screen at `/publish/?view=site` |
|
|
92
|
+
|
|
93
|
+
Then read it on your own site. Step 1 is worth doing first: until you do, pages
|
|
94
|
+
publish under placeholder names, your writing reserves all rights by default,
|
|
95
|
+
and a new data root cannot publish at all until you have said which language
|
|
96
|
+
you write in.
|
|
97
|
+
|
|
98
|
+
## Setting up your blog
|
|
99
|
+
|
|
100
|
+
Your blog's name, byline and tagline, the language you write in, and the
|
|
101
|
+
licence your writing carries, are configuration rather than code — one installed
|
|
102
|
+
copy can publish anybody's blog. Set them on the **Settings** screen under
|
|
103
|
+
**Blog settings**, which writes `data/blog/site.json`.
|
|
104
|
+
|
|
105
|
+
The language you write in decides which side of each pair is the original. Write
|
|
106
|
+
in Korean and you add an English translation; write in English and you add a
|
|
107
|
+
Korean one. A post keeps the side it was first published or translated from, so
|
|
108
|
+
changing this later never turns round a post you have already started. That screen holds what you decide once — the blog's
|
|
109
|
+
identity and where it deploys to — apart from the site screen, which is what you
|
|
110
|
+
check each time you publish.
|
|
111
|
+
|
|
112
|
+
Note that two different licences meet on a published page:
|
|
113
|
+
|
|
114
|
+
- **This tool is MIT.** See [LICENSE](https://github.com/byeongsuyu/stemma/blob/main/LICENSE). That covers the software.
|
|
115
|
+
- **Your writing is yours.** Its terms are a setting, defaulting to reserving
|
|
116
|
+
all rights. Presets for the Creative Commons licences and CC0 are offered,
|
|
117
|
+
or you can write your own wording. Nothing gives your readers rights you did
|
|
118
|
+
not choose.
|
|
119
|
+
|
|
120
|
+
See [docs/site-settings.md](https://github.com/byeongsuyu/stemma/blob/main/docs/site-settings.md).
|
|
121
|
+
|
|
122
|
+
## Writing
|
|
123
|
+
|
|
124
|
+
The editor at <http://127.0.0.1:8787> has three panes: search your archive,
|
|
125
|
+
read the sources you picked, and write. When you save, Stemma stores an
|
|
126
|
+
immutable revision and asks which parent documents this one carries forward,
|
|
127
|
+
and under which question.
|
|
128
|
+
|
|
129
|
+
**Add pictures or files** attaches pictures — several at once — storing each under its own
|
|
130
|
+
content hash and writing the Markdown link where your cursor is.
|
|
131
|
+
|
|
132
|
+
The same server hosts the publication screens at `/publish/`, where you add the
|
|
133
|
+
translation of a post, review the pair, and confirm it for publication. The
|
|
134
|
+
`/publish/?view=site` screen shows everything that would change on the live
|
|
135
|
+
site and deploys it.
|
|
136
|
+
|
|
137
|
+
The model's own workflow is available on the command line:
|
|
138
|
+
|
|
139
|
+
| Command | What it does |
|
|
140
|
+
|---|---|
|
|
141
|
+
| `create` | Start a draft, with repeated `--parent` and `--question` |
|
|
142
|
+
| `revise` | Store an input file as a new immutable revision |
|
|
143
|
+
| `confirm` | Confirm a document and its proposed successions |
|
|
144
|
+
| `archive` / `restore` | Retire a document from future use, or bring it back |
|
|
145
|
+
| `represent` | Choose which documents represent a question |
|
|
146
|
+
| `publish --pair` | Select a reviewed Korean/English pair locally |
|
|
147
|
+
| `unpublish` | Clear that selection |
|
|
148
|
+
| `export-public --planned-at` | Print the prospective public payload as JSON |
|
|
149
|
+
| `validate` | Check metadata and content hashes |
|
|
150
|
+
|
|
151
|
+
Run `stemma <command> --help` for the arguments. `publish` records a
|
|
152
|
+
local choice; it never uploads anything. Deployment is a separate, explicit
|
|
153
|
+
step. Global options come before the subcommand: `stemma --root . validate`.
|
|
154
|
+
|
|
155
|
+
Some work happens only in the editor and publication screens: writing a
|
|
156
|
+
question, preparing and reviewing a translation pair, attaching a file, and
|
|
157
|
+
importing a folder. `create` needs a question that already exists, so a fresh
|
|
158
|
+
data root is set up through the editor rather than the command line alone.
|
|
159
|
+
|
|
160
|
+
## Importing your existing writing
|
|
161
|
+
|
|
162
|
+
Open **Import** and give it the folder your writing lives in. It reads the
|
|
163
|
+
folder — never modifies it — and shows exactly what it would import before
|
|
164
|
+
anything is saved.
|
|
165
|
+
|
|
166
|
+
**Picture links are not rewritten.** A picture is recorded at the path it
|
|
167
|
+
occupies relative to the post that references it, so `` and
|
|
168
|
+
`` keep working as written. That is why it takes a
|
|
169
|
+
folder: the folder's shape is what makes the links resolve.
|
|
170
|
+
|
|
171
|
+
If your writing lives in a Git repository you keep updating, a second route
|
|
172
|
+
tracks it by commit:
|
|
173
|
+
|
|
174
|
+
```sh
|
|
175
|
+
stemma sync-archive --archive /absolute/path/to/your-archive
|
|
176
|
+
stemma sync-archive --dry-run # later runs remember the path
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Both are read-only and append-only. See [docs/importing.md](https://github.com/byeongsuyu/stemma/blob/main/docs/importing.md).
|
|
180
|
+
|
|
181
|
+
Already have writing in a Stemma data root? Do not import it — point the tool
|
|
182
|
+
at it: `stemma --root /path/containing/data editor`. See
|
|
183
|
+
[docs/moving-in.md](https://github.com/byeongsuyu/stemma/blob/main/docs/moving-in.md).
|
|
184
|
+
|
|
185
|
+
## Publishing
|
|
186
|
+
|
|
187
|
+
Deployment builds the static site and sends it to one destination, chosen on
|
|
188
|
+
the site screen:
|
|
189
|
+
|
|
190
|
+
- **A local folder** (default) — writes the finished site to a folder you name.
|
|
191
|
+
No account and nothing to wait for. Move that folder wherever you like: any
|
|
192
|
+
static host, `rsync`, an object store, a USB stick. Files this tool did not
|
|
193
|
+
write are never touched.
|
|
194
|
+
- **A GitHub Pages pull request** — opens a PR against a Pages repository you
|
|
195
|
+
control, so you see the diff before it goes live. Needs the `gh` CLI.
|
|
196
|
+
|
|
197
|
+
The folder is the general case and the reason the tool is not tied to one
|
|
198
|
+
service. See [docs/publishing.md](https://github.com/byeongsuyu/stemma/blob/main/docs/publishing.md).
|
|
199
|
+
|
|
200
|
+
## Layout
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
packages/stemma_graph/ pip: stemma-graph the genealogy graph, stdlib only
|
|
204
|
+
examples/ a runnable demo of the graph on its own
|
|
205
|
+
src/stemma_studio/ pip: stemma-studio installs the `stemma` command
|
|
206
|
+
core/ the model, storage, archive sync and publication rules
|
|
207
|
+
blog/ Markdown rendering, the reader's site, publication admin, deploy
|
|
208
|
+
editor/ the writing desk, which mounts the blog's publication screens
|
|
209
|
+
cli.py the stemma command
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
The dependency direction runs one way — `core` imports neither sibling, and
|
|
213
|
+
`blog` never imports `editor`. A test enforces it. `stemma-graph` is a
|
|
214
|
+
separate package because it is useful on its own and depends on nothing; you
|
|
215
|
+
can install it alone if all you want is the graph.
|
|
216
|
+
|
|
217
|
+
Neither distribution needs a third-party package installed alongside it, beyond
|
|
218
|
+
Studio's dependency on `stemma-graph`. Studio is not pure standard library
|
|
219
|
+
though: it ships vendored copies of mistune and KaTeX inside the wheel, under
|
|
220
|
+
their own licences.
|
|
221
|
+
|
|
222
|
+
Your writing lives in the data root, never in the package: `data/studio.json`
|
|
223
|
+
holds the metadata, with preserved copies under `imports/`, `revisions/`,
|
|
224
|
+
`assets/` and `translations/`. No personal data is included in either wheel.
|
|
225
|
+
|
|
226
|
+
## Documentation
|
|
227
|
+
|
|
228
|
+
| Document | Read it for |
|
|
229
|
+
|---|---|
|
|
230
|
+
| [Design](https://github.com/byeongsuyu/stemma/blob/main/docs/design.md) | The rules for documents, succession, retirement and publication, and why they hold |
|
|
231
|
+
| [Code tour](https://github.com/byeongsuyu/stemma/blob/main/docs/code-tour.md) | Where code lives, entry points, and how to run it |
|
|
232
|
+
| [Editor](https://github.com/byeongsuyu/stemma/blob/main/docs/editor.md) | The writing desk, and its save and recovery boundaries |
|
|
233
|
+
| [Publishing](https://github.com/byeongsuyu/stemma/blob/main/docs/publishing.md) | Bilingual publication, releases and deployment |
|
|
234
|
+
| [Importing](https://github.com/byeongsuyu/stemma/blob/main/docs/importing.md) | Bringing your existing writing in, by folder or from Git |
|
|
235
|
+
| [Site settings](https://github.com/byeongsuyu/stemma/blob/main/docs/site-settings.md) | Naming your blog, and licensing your writing |
|
|
236
|
+
| [Moving in](https://github.com/byeongsuyu/stemma/blob/main/docs/moving-in.md) | Bringing an existing data root into a new install |
|
|
237
|
+
| [Contributing](https://github.com/byeongsuyu/stemma/blob/main/CONTRIBUTING.md) | Tests, style and the rules a change must keep |
|
|
238
|
+
|
|
239
|
+
## Status
|
|
240
|
+
|
|
241
|
+
This is one person's tool, published in case it is useful to others. It assumes
|
|
242
|
+
a single local author and does not enforce that assumption: each running server
|
|
243
|
+
serializes its own requests, but nothing coordinates between two servers, or
|
|
244
|
+
between a server and the command line. Do not run two of them against one data
|
|
245
|
+
root.
|
|
246
|
+
|
|
247
|
+
## License
|
|
248
|
+
|
|
249
|
+
The **code** is MIT — see [LICENSE](https://github.com/byeongsuyu/stemma/blob/main/LICENSE). Bundled third-party code keeps
|
|
250
|
+
its own licence: mistune (BSD-3-Clause), KaTeX (MIT) and the MaruBuri font
|
|
251
|
+
(SIL OFL 1.1). See `src/stemma_studio/blog/vendor/README.md` and
|
|
252
|
+
`src/stemma_studio/blog/frontend/fonts/README.md`.
|
|
253
|
+
|
|
254
|
+
The **writing** you publish with it is not covered by that licence. Its terms
|
|
255
|
+
are yours to choose, in the blog settings; see
|
|
256
|
+
[docs/site-settings.md](https://github.com/byeongsuyu/stemma/blob/main/docs/site-settings.md).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77.0.3", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
# The distribution is stemma-studio; the command it installs is `stemma`.
|
|
7
|
+
name = "stemma-studio"
|
|
8
|
+
version = "0.4.0"
|
|
9
|
+
description = "Writing that descends from earlier writing: a local desk, a genealogy of versions, and a bilingual static blog"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.12"
|
|
12
|
+
license = "MIT"
|
|
13
|
+
license-files = ["LICENSE"]
|
|
14
|
+
keywords = ["writing", "blog", "static-site", "genealogy", "stemma", "markdown"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Intended Audience :: End Users/Desktop",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Topic :: Text Processing :: Markup :: Markdown",
|
|
20
|
+
]
|
|
21
|
+
dependencies = ["stemma-graph>=0.3.0,<0.4.0"]
|
|
22
|
+
|
|
23
|
+
[project.optional-dependencies]
|
|
24
|
+
dev = ["ruff>=0.6"]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/byeongsuyu/stemma"
|
|
28
|
+
Source = "https://github.com/byeongsuyu/stemma"
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
stemma = "stemma_studio.cli:main"
|
|
32
|
+
|
|
33
|
+
[tool.setuptools.packages.find]
|
|
34
|
+
where = ["src"]
|
|
35
|
+
|
|
36
|
+
[tool.setuptools.package-data]
|
|
37
|
+
"stemma_studio.blog" = [
|
|
38
|
+
"frontend/*.css", "frontend/*.js", "frontend/fonts/*.woff2", "frontend/fonts/*.txt",
|
|
39
|
+
"frontend/fonts/README.md", "admin_frontend/*.css", "admin_frontend/*.js",
|
|
40
|
+
"admin_frontend/*.html", "sample/*.json", "math-render.cjs",
|
|
41
|
+
"vendor/katex/*.cjs", "vendor/*LICENSE", "vendor/README.md",
|
|
42
|
+
]
|
|
43
|
+
"stemma_studio.editor" = ["frontend/*.css", "frontend/*.js", "frontend/*.html"]
|
|
44
|
+
"stemma_studio.locale" = ["*.json"]
|
|
45
|
+
|
|
46
|
+
[tool.ruff]
|
|
47
|
+
line-length = 120
|
|
48
|
+
target-version = "py312"
|
|
49
|
+
src = ["src", "tests"]
|
|
50
|
+
extend-exclude = ["src/stemma_studio/blog/vendor"]
|
|
51
|
+
|
|
52
|
+
[tool.ruff.lint]
|
|
53
|
+
select = ["E", "F", "W", "I", "UP", "B"]
|
|
54
|
+
ignore = [
|
|
55
|
+
"E501", # the formatter decides where lines wrap
|
|
56
|
+
"B023", # render_site's page helpers are called inside the same loop iteration
|
|
57
|
+
"B905", # adding strict= to zip would change behaviour, not just style
|
|
58
|
+
"E731", # the short assigned lambdas in the renderers read better than defs
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[tool.ruff.lint.per-file-ignores]
|
|
62
|
+
# This guard has to keep working on the older interpreter it warns about.
|
|
63
|
+
"scripts/dev.py" = ["UP036"]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Stemma: a local writing desk, genealogy model and bilingual blog publisher.
|
|
2
|
+
|
|
3
|
+
The three subpackages depend in one direction only. ``core`` holds the model,
|
|
4
|
+
persistence and publication rules and imports neither sibling. ``blog`` renders
|
|
5
|
+
and deploys the public site on top of ``core``. ``editor`` serves the writing
|
|
6
|
+
desk and mounts the blog's publication screens. ``tests/test_package_layout.py``
|
|
7
|
+
enforces that direction.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
__version__ = "0.4.0"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Bilingual static blog: Markdown rendering, preview, publication admin and deploy."""
|