ofplang-export 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.
- ofplang_export-0.1.0/.gitattributes +4 -0
- ofplang_export-0.1.0/.gitignore +32 -0
- ofplang_export-0.1.0/.gitmodules +3 -0
- ofplang_export-0.1.0/LICENSE +21 -0
- ofplang_export-0.1.0/MANIFEST.in +9 -0
- ofplang_export-0.1.0/PKG-INFO +179 -0
- ofplang_export-0.1.0/README.md +145 -0
- ofplang_export-0.1.0/ofplang/export/__init__.py +13 -0
- ofplang_export-0.1.0/ofplang/export/__main__.py +5 -0
- ofplang_export-0.1.0/ofplang/export/_template/viewer.html +269 -0
- ofplang_export-0.1.0/ofplang/export/cli.py +171 -0
- ofplang_export-0.1.0/ofplang/export/documents.py +237 -0
- ofplang_export-0.1.0/ofplang/export/py.typed +0 -0
- ofplang_export-0.1.0/ofplang/export/template.py +72 -0
- ofplang_export-0.1.0/ofplang_export.egg-info/PKG-INFO +179 -0
- ofplang_export-0.1.0/ofplang_export.egg-info/SOURCES.txt +23 -0
- ofplang_export-0.1.0/ofplang_export.egg-info/dependency_links.txt +1 -0
- ofplang_export-0.1.0/ofplang_export.egg-info/entry_points.txt +2 -0
- ofplang_export-0.1.0/ofplang_export.egg-info/requires.txt +10 -0
- ofplang_export-0.1.0/ofplang_export.egg-info/scm_file_list.json +514 -0
- ofplang_export-0.1.0/ofplang_export.egg-info/scm_version.json +8 -0
- ofplang_export-0.1.0/ofplang_export.egg-info/top_level.txt +1 -0
- ofplang_export-0.1.0/pyproject.toml +76 -0
- ofplang_export-0.1.0/setup.cfg +4 -0
- ofplang_export-0.1.0/tests/test_view.py +213 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Working notes — not published (same convention as the sibling ofplang repos).
|
|
2
|
+
/dev-notes/
|
|
3
|
+
|
|
4
|
+
# Node / Vite
|
|
5
|
+
node_modules/
|
|
6
|
+
dist/
|
|
7
|
+
dist-single/
|
|
8
|
+
*.tsbuildinfo
|
|
9
|
+
|
|
10
|
+
# Datasets are generated from external/ at build time (design.md D9 ①).
|
|
11
|
+
/web/public/datasets/
|
|
12
|
+
|
|
13
|
+
# Python
|
|
14
|
+
__pycache__/
|
|
15
|
+
*.egg-info/
|
|
16
|
+
/build/
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.ruff_cache/
|
|
19
|
+
.mypy_cache/
|
|
20
|
+
# Built from web/ by `npm run build:single`; the wheel carries it (design.md D50).
|
|
21
|
+
/ofplang/export/_template/
|
|
22
|
+
|
|
23
|
+
# Editor / OS
|
|
24
|
+
.DS_Store
|
|
25
|
+
Thumbs.db
|
|
26
|
+
*.local
|
|
27
|
+
|
|
28
|
+
# Playwright
|
|
29
|
+
/web/shots/
|
|
30
|
+
/web/test-results/
|
|
31
|
+
/web/playwright-report/
|
|
32
|
+
/web/blob-report/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kazunari Kaizu
|
|
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,9 @@
|
|
|
1
|
+
# setuptools-scm puts every tracked file in the sdist. The viewer template is
|
|
2
|
+
# built, not tracked, so it is named here; the web sources it is built from are
|
|
3
|
+
# not Python and stay out.
|
|
4
|
+
include ofplang/export/_template/viewer.html
|
|
5
|
+
prune web
|
|
6
|
+
prune prototype
|
|
7
|
+
prune external
|
|
8
|
+
prune .github
|
|
9
|
+
prune skills
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ofplang-export
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Write Object-flow Programming Language documents out in a form people read.
|
|
5
|
+
Author-email: Kazunari Kaizu <kwaizu@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ofplang/export
|
|
8
|
+
Project-URL: Repository, https://github.com/ofplang/export
|
|
9
|
+
Project-URL: Viewer, https://ofplang.github.io/export/
|
|
10
|
+
Keywords: ofplang,dataflow,workflow,schedule,viewer,html
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: PyYAML>=6.0
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest>=7.0; extra == "test"
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff>=0.16; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy>=1.11; extra == "dev"
|
|
32
|
+
Requires-Dist: types-PyYAML; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# ofplang export
|
|
36
|
+
|
|
37
|
+
[](https://github.com/ofplang/export/actions/workflows/ci.yml)
|
|
38
|
+
|
|
39
|
+
Readable views of [ofplang](https://github.com/ofplang/spec) documents: a
|
|
40
|
+
workflow as its dataflow graph, and the execution plans
|
|
41
|
+
[`ofp-schedule`](https://github.com/ofplang/schedule) produces from it, shown
|
|
42
|
+
side by side and linked — as a web site, and as one self-contained HTML file.
|
|
43
|
+
|
|
44
|
+
It reads the documents the ofplang specifications define and nothing more, so
|
|
45
|
+
it does not depend on any dialect built on top of them.
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
pip install ofplang-export
|
|
49
|
+
ofp-export view plan.yaml -o plan.html # a plan; its workflow and environment come from its meta
|
|
50
|
+
ofp-export view workflow.yaml -o wf.html # a workflow on its own
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`ofp-export view` writes the viewer as **one HTML file with the documents in
|
|
54
|
+
it**, to open from disk or send to someone. It is also meant to be reachable as
|
|
55
|
+
`ofp export view` and, under labcode, `lc export view`.
|
|
56
|
+
|
|
57
|
+
**→ [ofplang.github.io/export](https://ofplang.github.io/export/)**
|
|
58
|
+
— ten plans are bundled; `?doc=plate_batch` opens one directly. Drop your own
|
|
59
|
+
YAML on the window to read that instead: a plan, a workflow, an environment, or
|
|
60
|
+
all three at once. A workflow on its own is fine — the graph does not need a
|
|
61
|
+
plan to be read. Either pane can take the whole window: *Both / Workflow / Plan*
|
|
62
|
+
in the top bar, or `&layout=workflow` / `&layout=plan` in the address.
|
|
63
|
+
|
|
64
|
+
The point is to be able to hand someone a URL. They open it and see the
|
|
65
|
+
dataflow graph and the Gantt chart of a plan side by side, linked: pick a bar
|
|
66
|
+
and the workflow node it came from lights up, pick a node and every bar under
|
|
67
|
+
it lights up. No install, no server, no Python.
|
|
68
|
+
|
|
69
|
+
> **Status: early but usable.** Both panes work and are linked: pick a bar and
|
|
70
|
+
> the workflow box it came from lights up, pick a box and everything under it
|
|
71
|
+
> lights up in the plan. Plans can be exported as SVG or put in a link.
|
|
72
|
+
> `prototype/` holds the single-file look-and-feel study the visual decisions
|
|
73
|
+
> were made against.
|
|
74
|
+
|
|
75
|
+
## The command
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
ofp-export view <file>... [-o OUT] [--layout split|workflow|plan] [--gantt device|flow|activity]
|
|
79
|
+
[--name NAME] [--no-follow] [--json]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- Files are a plan, a workflow and/or an environment, in any order; which is
|
|
83
|
+
which is read from the file. A plan's `meta` supplies the workflow and the
|
|
84
|
+
environment unless they are given (`--no-follow` turns that off).
|
|
85
|
+
- Without `-o` the HTML goes to standard output, as `ofp-schedule` does with a
|
|
86
|
+
plan. With `-o` the path written is printed; `--json` prints a summary instead.
|
|
87
|
+
- Exit codes: **0** written (warnings, if any, on stderr — parts of a workflow
|
|
88
|
+
the viewer shows only as source structure), **2** bad input, **3** refused
|
|
89
|
+
and nothing written — a joint plan (several workflows scheduled together as
|
|
90
|
+
jobs), which this viewer does not draw.
|
|
91
|
+
|
|
92
|
+
[`skills/ofp-export/SKILL.md`](skills/ofp-export/SKILL.md) says the same for an
|
|
93
|
+
agent calling the command, as a skill to install where the agent looks for them.
|
|
94
|
+
|
|
95
|
+
## A single file
|
|
96
|
+
|
|
97
|
+
The same viewer also builds as **one self-contained HTML file** that carries
|
|
98
|
+
its documents inside it: open it from disk, no server, nothing beside it.
|
|
99
|
+
`npm run build:single` writes the empty template, `web/dist-single/viewer.html`
|
|
100
|
+
(also kept as the `viewer-template` artifact of every CI run), and
|
|
101
|
+
`web/scripts/embed.mjs` puts documents into it:
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
node scripts/embed.mjs dist-single/viewer.html out.html plan.yaml --workflow w.yaml --env e.yaml
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The documents go in as the YAML text as written, in one element —
|
|
108
|
+
`<script type="application/json" id="ofp-documents" data-contract="1">` — and
|
|
109
|
+
the page reads them with the same reader it uses for a dropped file. An empty
|
|
110
|
+
template (`null` in that element) is an offline viewer to drop files on. The
|
|
111
|
+
web fonts stay a link, so offline the page falls back to system fonts; *Copy
|
|
112
|
+
link* is hidden, since a link made from a file on disk would point at the disk.
|
|
113
|
+
|
|
114
|
+
## Layout
|
|
115
|
+
|
|
116
|
+
| Path | What it is |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `web/` | the application — Vite + TypeScript, no runtime dependency beyond `yaml` |
|
|
119
|
+
| `web/src/model/` | types for the workflow, the environment and the execution document |
|
|
120
|
+
| `web/src/read/` | YAML → those types; the only part that tracks the specifications |
|
|
121
|
+
| `web/src/model/scene.ts` | the indices every view is built on — by node, by arc, by machine |
|
|
122
|
+
| `web/src/layout/` | lanes, bars and the time scale; pure functions, no DOM |
|
|
123
|
+
| `web/src/view/` | SVG rendering, the inspector, and the SVG export |
|
|
124
|
+
| `web/scripts/collect-datasets.mjs` | turns the submodule's examples into the bundled datasets |
|
|
125
|
+
| `web/scripts/build-single.mjs` | folds the build into the one-file viewer template |
|
|
126
|
+
| `web/scripts/embed.mjs` | puts documents into that template — the contract, in one place |
|
|
127
|
+
| `ofplang/export/` | the `ofp-export` Python package; `template.py` is the same contract in Python |
|
|
128
|
+
| `tests/` | its tests (pytest), against the pinned submodule's examples |
|
|
129
|
+
| `web/tests/golden/` | every example the pinned submodule ships must read |
|
|
130
|
+
| `external/ofplang-schedule` | submodule, pinned by tag — specifications and examples |
|
|
131
|
+
| `prototype/` | a single-file look-and-feel study; not the codebase |
|
|
132
|
+
|
|
133
|
+
## Why a TypeScript reader instead of reusing the Python one
|
|
134
|
+
|
|
135
|
+
The sibling repositories own the specifications and the semantics, and this one
|
|
136
|
+
does not modify them. It also has to run with nothing installed on the viewer's
|
|
137
|
+
machine, which rules out a Python pre-processing step. So the document readers
|
|
138
|
+
here are a deliberate, bounded re-implementation of two stable schemas —
|
|
139
|
+
`SPECIFICATIONS.md` §5 (environment) and §6 (execution document) — kept honest
|
|
140
|
+
by the golden test against the pinned submodule's own examples.
|
|
141
|
+
|
|
142
|
+
Anything outside that subset — `$import`, generics, structured nodes, and
|
|
143
|
+
joint plans that schedule several workflows together as jobs — is refused
|
|
144
|
+
rather than guessed at.
|
|
145
|
+
|
|
146
|
+
## Working on it
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
git clone --recurse-submodules git@github.com:ofplang/export.git
|
|
150
|
+
cd web
|
|
151
|
+
npm install
|
|
152
|
+
|
|
153
|
+
npm run dev # development server (collects the datasets first)
|
|
154
|
+
npm run datasets # rebuild public/datasets/ from external/
|
|
155
|
+
npm run typecheck # tsc --noEmit
|
|
156
|
+
npm test # golden tests against external/ofplang-schedule
|
|
157
|
+
npm run build # typecheck + production build into web/dist
|
|
158
|
+
npm run build:single # …and the one-file template into web/dist-single
|
|
159
|
+
npm run test:e2e # the browser tests (builds the template first)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The Python package, from the repository root (after `npm run build:single`,
|
|
163
|
+
which also puts the template into `ofplang/export/_template/`):
|
|
164
|
+
|
|
165
|
+
```sh
|
|
166
|
+
pip install -e ".[dev]"
|
|
167
|
+
pytest
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
A release is a `v*` tag: `publish.yml` builds the template and the wheel from
|
|
171
|
+
the same commit and publishes through PyPI trusted publishing (an `rc` tag goes
|
|
172
|
+
to TestPyPI). Installing straight from git gives no template — it is built, not
|
|
173
|
+
committed — and the command says so.
|
|
174
|
+
|
|
175
|
+
Already cloned without `--recurse-submodules`? `git submodule update --init`.
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# ofplang export
|
|
2
|
+
|
|
3
|
+
[](https://github.com/ofplang/export/actions/workflows/ci.yml)
|
|
4
|
+
|
|
5
|
+
Readable views of [ofplang](https://github.com/ofplang/spec) documents: a
|
|
6
|
+
workflow as its dataflow graph, and the execution plans
|
|
7
|
+
[`ofp-schedule`](https://github.com/ofplang/schedule) produces from it, shown
|
|
8
|
+
side by side and linked — as a web site, and as one self-contained HTML file.
|
|
9
|
+
|
|
10
|
+
It reads the documents the ofplang specifications define and nothing more, so
|
|
11
|
+
it does not depend on any dialect built on top of them.
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pip install ofplang-export
|
|
15
|
+
ofp-export view plan.yaml -o plan.html # a plan; its workflow and environment come from its meta
|
|
16
|
+
ofp-export view workflow.yaml -o wf.html # a workflow on its own
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`ofp-export view` writes the viewer as **one HTML file with the documents in
|
|
20
|
+
it**, to open from disk or send to someone. It is also meant to be reachable as
|
|
21
|
+
`ofp export view` and, under labcode, `lc export view`.
|
|
22
|
+
|
|
23
|
+
**→ [ofplang.github.io/export](https://ofplang.github.io/export/)**
|
|
24
|
+
— ten plans are bundled; `?doc=plate_batch` opens one directly. Drop your own
|
|
25
|
+
YAML on the window to read that instead: a plan, a workflow, an environment, or
|
|
26
|
+
all three at once. A workflow on its own is fine — the graph does not need a
|
|
27
|
+
plan to be read. Either pane can take the whole window: *Both / Workflow / Plan*
|
|
28
|
+
in the top bar, or `&layout=workflow` / `&layout=plan` in the address.
|
|
29
|
+
|
|
30
|
+
The point is to be able to hand someone a URL. They open it and see the
|
|
31
|
+
dataflow graph and the Gantt chart of a plan side by side, linked: pick a bar
|
|
32
|
+
and the workflow node it came from lights up, pick a node and every bar under
|
|
33
|
+
it lights up. No install, no server, no Python.
|
|
34
|
+
|
|
35
|
+
> **Status: early but usable.** Both panes work and are linked: pick a bar and
|
|
36
|
+
> the workflow box it came from lights up, pick a box and everything under it
|
|
37
|
+
> lights up in the plan. Plans can be exported as SVG or put in a link.
|
|
38
|
+
> `prototype/` holds the single-file look-and-feel study the visual decisions
|
|
39
|
+
> were made against.
|
|
40
|
+
|
|
41
|
+
## The command
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
ofp-export view <file>... [-o OUT] [--layout split|workflow|plan] [--gantt device|flow|activity]
|
|
45
|
+
[--name NAME] [--no-follow] [--json]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- Files are a plan, a workflow and/or an environment, in any order; which is
|
|
49
|
+
which is read from the file. A plan's `meta` supplies the workflow and the
|
|
50
|
+
environment unless they are given (`--no-follow` turns that off).
|
|
51
|
+
- Without `-o` the HTML goes to standard output, as `ofp-schedule` does with a
|
|
52
|
+
plan. With `-o` the path written is printed; `--json` prints a summary instead.
|
|
53
|
+
- Exit codes: **0** written (warnings, if any, on stderr — parts of a workflow
|
|
54
|
+
the viewer shows only as source structure), **2** bad input, **3** refused
|
|
55
|
+
and nothing written — a joint plan (several workflows scheduled together as
|
|
56
|
+
jobs), which this viewer does not draw.
|
|
57
|
+
|
|
58
|
+
[`skills/ofp-export/SKILL.md`](skills/ofp-export/SKILL.md) says the same for an
|
|
59
|
+
agent calling the command, as a skill to install where the agent looks for them.
|
|
60
|
+
|
|
61
|
+
## A single file
|
|
62
|
+
|
|
63
|
+
The same viewer also builds as **one self-contained HTML file** that carries
|
|
64
|
+
its documents inside it: open it from disk, no server, nothing beside it.
|
|
65
|
+
`npm run build:single` writes the empty template, `web/dist-single/viewer.html`
|
|
66
|
+
(also kept as the `viewer-template` artifact of every CI run), and
|
|
67
|
+
`web/scripts/embed.mjs` puts documents into it:
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
node scripts/embed.mjs dist-single/viewer.html out.html plan.yaml --workflow w.yaml --env e.yaml
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The documents go in as the YAML text as written, in one element —
|
|
74
|
+
`<script type="application/json" id="ofp-documents" data-contract="1">` — and
|
|
75
|
+
the page reads them with the same reader it uses for a dropped file. An empty
|
|
76
|
+
template (`null` in that element) is an offline viewer to drop files on. The
|
|
77
|
+
web fonts stay a link, so offline the page falls back to system fonts; *Copy
|
|
78
|
+
link* is hidden, since a link made from a file on disk would point at the disk.
|
|
79
|
+
|
|
80
|
+
## Layout
|
|
81
|
+
|
|
82
|
+
| Path | What it is |
|
|
83
|
+
|---|---|
|
|
84
|
+
| `web/` | the application — Vite + TypeScript, no runtime dependency beyond `yaml` |
|
|
85
|
+
| `web/src/model/` | types for the workflow, the environment and the execution document |
|
|
86
|
+
| `web/src/read/` | YAML → those types; the only part that tracks the specifications |
|
|
87
|
+
| `web/src/model/scene.ts` | the indices every view is built on — by node, by arc, by machine |
|
|
88
|
+
| `web/src/layout/` | lanes, bars and the time scale; pure functions, no DOM |
|
|
89
|
+
| `web/src/view/` | SVG rendering, the inspector, and the SVG export |
|
|
90
|
+
| `web/scripts/collect-datasets.mjs` | turns the submodule's examples into the bundled datasets |
|
|
91
|
+
| `web/scripts/build-single.mjs` | folds the build into the one-file viewer template |
|
|
92
|
+
| `web/scripts/embed.mjs` | puts documents into that template — the contract, in one place |
|
|
93
|
+
| `ofplang/export/` | the `ofp-export` Python package; `template.py` is the same contract in Python |
|
|
94
|
+
| `tests/` | its tests (pytest), against the pinned submodule's examples |
|
|
95
|
+
| `web/tests/golden/` | every example the pinned submodule ships must read |
|
|
96
|
+
| `external/ofplang-schedule` | submodule, pinned by tag — specifications and examples |
|
|
97
|
+
| `prototype/` | a single-file look-and-feel study; not the codebase |
|
|
98
|
+
|
|
99
|
+
## Why a TypeScript reader instead of reusing the Python one
|
|
100
|
+
|
|
101
|
+
The sibling repositories own the specifications and the semantics, and this one
|
|
102
|
+
does not modify them. It also has to run with nothing installed on the viewer's
|
|
103
|
+
machine, which rules out a Python pre-processing step. So the document readers
|
|
104
|
+
here are a deliberate, bounded re-implementation of two stable schemas —
|
|
105
|
+
`SPECIFICATIONS.md` §5 (environment) and §6 (execution document) — kept honest
|
|
106
|
+
by the golden test against the pinned submodule's own examples.
|
|
107
|
+
|
|
108
|
+
Anything outside that subset — `$import`, generics, structured nodes, and
|
|
109
|
+
joint plans that schedule several workflows together as jobs — is refused
|
|
110
|
+
rather than guessed at.
|
|
111
|
+
|
|
112
|
+
## Working on it
|
|
113
|
+
|
|
114
|
+
```sh
|
|
115
|
+
git clone --recurse-submodules git@github.com:ofplang/export.git
|
|
116
|
+
cd web
|
|
117
|
+
npm install
|
|
118
|
+
|
|
119
|
+
npm run dev # development server (collects the datasets first)
|
|
120
|
+
npm run datasets # rebuild public/datasets/ from external/
|
|
121
|
+
npm run typecheck # tsc --noEmit
|
|
122
|
+
npm test # golden tests against external/ofplang-schedule
|
|
123
|
+
npm run build # typecheck + production build into web/dist
|
|
124
|
+
npm run build:single # …and the one-file template into web/dist-single
|
|
125
|
+
npm run test:e2e # the browser tests (builds the template first)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The Python package, from the repository root (after `npm run build:single`,
|
|
129
|
+
which also puts the template into `ofplang/export/_template/`):
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
pip install -e ".[dev]"
|
|
133
|
+
pytest
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
A release is a `v*` tag: `publish.yml` builds the template and the wheel from
|
|
137
|
+
the same commit and publishes through PyPI trusted publishing (an `rc` tag goes
|
|
138
|
+
to TestPyPI). Installing straight from git gives no template — it is built, not
|
|
139
|
+
committed — and the command says so.
|
|
140
|
+
|
|
141
|
+
Already cloned without `--recurse-submodules`? `git submodule update --init`.
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""ofplang export: write ofplang documents out in a form people read.
|
|
2
|
+
|
|
3
|
+
The one target so far is `view` — the interactive viewer as a single HTML
|
|
4
|
+
file. See `ofplang.export.cli` for the command, `ofplang.export.template` for
|
|
5
|
+
the contract between this package and the page it fills.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
__version__ = version("ofplang-export")
|
|
12
|
+
except PackageNotFoundError: # a source tree without installed metadata
|
|
13
|
+
__version__ = "0+unknown"
|