anthus-markus 0.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- anthus_markus-0.5.1/.gitignore +23 -0
- anthus_markus-0.5.1/CHANGELOG.md +9 -0
- anthus_markus-0.5.1/LICENSE +21 -0
- anthus_markus-0.5.1/PKG-INFO +135 -0
- anthus_markus-0.5.1/README.md +96 -0
- anthus_markus-0.5.1/behave.ini +6 -0
- anthus_markus-0.5.1/docs/LANGUAGE.md +80 -0
- anthus_markus-0.5.1/examples/getting-started.md +51 -0
- anthus_markus-0.5.1/features/cli.feature +81 -0
- anthus_markus-0.5.1/features/directives.feature +335 -0
- anthus_markus-0.5.1/features/document-ir.feature +167 -0
- anthus_markus-0.5.1/features/environment.py +33 -0
- anthus_markus-0.5.1/features/front_matter.feature +189 -0
- anthus_markus-0.5.1/features/gfm.feature +63 -0
- anthus_markus-0.5.1/features/site.feature +96 -0
- anthus_markus-0.5.1/features/steps/markus_steps.py +394 -0
- anthus_markus-0.5.1/features/themes.feature +1127 -0
- anthus_markus-0.5.1/features/validation.feature +167 -0
- anthus_markus-0.5.1/pyproject.toml +98 -0
- anthus_markus-0.5.1/site/assets/pipeline.svg +23 -0
- anthus_markus-0.5.1/site/gallery.md +189 -0
- anthus_markus-0.5.1/site/gfm.md +56 -0
- anthus_markus-0.5.1/site/index.md +202 -0
- anthus_markus-0.5.1/site/site.css +293 -0
- anthus_markus-0.5.1/src/markusmd/__init__.py +34 -0
- anthus_markus-0.5.1/src/markusmd/__main__.py +6 -0
- anthus_markus-0.5.1/src/markusmd/_frontmatter_yaml.py +98 -0
- anthus_markus-0.5.1/src/markusmd/api.py +112 -0
- anthus_markus-0.5.1/src/markusmd/ast.py +245 -0
- anthus_markus-0.5.1/src/markusmd/attributes.py +95 -0
- anthus_markus-0.5.1/src/markusmd/blocks.py +608 -0
- anthus_markus-0.5.1/src/markusmd/cli.py +149 -0
- anthus_markus-0.5.1/src/markusmd/errors.py +33 -0
- anthus_markus-0.5.1/src/markusmd/parse.py +258 -0
- anthus_markus-0.5.1/src/markusmd/preview.py +61 -0
- anthus_markus-0.5.1/src/markusmd/py.typed +0 -0
- anthus_markus-0.5.1/src/markusmd/registry.py +724 -0
- anthus_markus-0.5.1/src/markusmd/render.py +158 -0
- anthus_markus-0.5.1/src/markusmd/sitebuild.py +392 -0
- anthus_markus-0.5.1/src/markusmd/static/markus.css +1122 -0
- anthus_markus-0.5.1/src/markusmd/static/playground.html +138 -0
- anthus_markus-0.5.1/src/markusmd/static/site.css +293 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/catppuccin-latte.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/catppuccin.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/ethereal.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/everforest.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/flexoki-light.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/gruvbox.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/hackerman.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/kanagawa.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/last-horizon.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/lumon.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/lupine.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/matte-black.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/miasma.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/nord.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/osaka-jade.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/retro-82.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/ristretto.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/rose-pine.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/solitude.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/tokyo-night.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/vantablack.css +25 -0
- anthus_markus-0.5.1/src/markusmd/static/themes/white.css +25 -0
- anthus_markus-0.5.1/src/markusmd/themes.py +42 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
.env
|
|
11
|
+
.python-version
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
.mypy_cache/
|
|
15
|
+
.coverage
|
|
16
|
+
htmlcov/
|
|
17
|
+
pretty.output
|
|
18
|
+
_site/
|
|
19
|
+
site/_build/
|
|
20
|
+
*.html
|
|
21
|
+
!src/markusmd/static/*.html
|
|
22
|
+
project/.overlay/
|
|
23
|
+
project/.cache/
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
- Initial Markus language: GFM baseline, YAML front matter, and a small
|
|
6
|
+
semantic directive registry.
|
|
7
|
+
- HTML renderer with bundled CSS.
|
|
8
|
+
- `markus` CLI: `convert`, `ast`, `validate`, `preview`, `site`.
|
|
9
|
+
- GitHub Pages demo generated from Markus sources in `site/`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anthus AI Solutions
|
|
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,135 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: anthus-markus
|
|
3
|
+
Version: 0.5.1
|
|
4
|
+
Summary: Markus: GitHub-flavored Markdown with semantic layout directives.
|
|
5
|
+
Project-URL: Homepage, https://github.com/AnthusAI/Markus
|
|
6
|
+
Project-URL: Documentation, https://github.com/AnthusAI/Markus#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/AnthusAI/Markus
|
|
8
|
+
Project-URL: Issues, https://github.com/AnthusAI/Markus/issues
|
|
9
|
+
Author-email: Anthus AI Solutions <info@anthus.ai>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: commonmark,directives,gfm,layout,markdown,publishing
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: Text Processing :: Markup
|
|
25
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Requires-Dist: markdown-it-py[linkify]<5,>=3.0
|
|
29
|
+
Requires-Dist: mdit-py-plugins<1,>=0.4.0
|
|
30
|
+
Requires-Dist: pydantic<3,>=2.0
|
|
31
|
+
Requires-Dist: pyyaml<7,>=6.0
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: behave>=1.2.6; extra == 'dev'
|
|
34
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
35
|
+
Requires-Dist: pre-commit; extra == 'dev'
|
|
36
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
37
|
+
Requires-Dist: tox; extra == 'dev'
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# Markus
|
|
41
|
+
|
|
42
|
+
**GitHub-flavored Markdown with a small vocabulary for layout intent.**
|
|
43
|
+
|
|
44
|
+
Markus keeps Markdown as the content language, then adds colon-fenced
|
|
45
|
+
directives for the things GFM cannot say: *this is a pull quote*, *these
|
|
46
|
+
items are peer cards*, *these two views belong together*. Authors encode
|
|
47
|
+
meaning. The renderer turns that meaning into accessible HTML and responsive
|
|
48
|
+
CSS — or, later, print, EPUB, or email.
|
|
49
|
+
|
|
50
|
+
## Install
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install anthus-markus
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Python 3.10 or newer.
|
|
57
|
+
|
|
58
|
+
## Convert a page
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
markus convert examples/getting-started.md -o page.html
|
|
62
|
+
markus validate examples/getting-started.md
|
|
63
|
+
markus ast examples/getting-started.md
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Python API:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from markusmd import convert
|
|
70
|
+
|
|
71
|
+
html = convert(open("page.md", encoding="utf-8").read())
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Directives
|
|
75
|
+
|
|
76
|
+
```md
|
|
77
|
+
:::pull-quote{attribution="Engineering principle" tone="primary"}
|
|
78
|
+
The best system is often the one whose failure modes you can explain.
|
|
79
|
+
:::
|
|
80
|
+
|
|
81
|
+
:::feature-grid{columns=3}
|
|
82
|
+
:::feature-card{icon="bolt"}
|
|
83
|
+
## Low latency
|
|
84
|
+
Keep common interactions local.
|
|
85
|
+
:::
|
|
86
|
+
:::
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The 0.1 vocabulary:
|
|
90
|
+
|
|
91
|
+
| Directive | Intent |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| `callout` (`note`, `warning`, `tip`, `caution`) | Status or editorial note |
|
|
94
|
+
| `pull-quote` | Editorial quotation |
|
|
95
|
+
| `card-grid` / `card` | Peer items |
|
|
96
|
+
| `two-up` / `column` | A conceptual pair |
|
|
97
|
+
| `figure` | Media with caption and credit |
|
|
98
|
+
| `details` | Progressive disclosure |
|
|
99
|
+
| `aside` | Supporting, non-linear material |
|
|
100
|
+
| `metric` | A labeled fact (`::metric{...}`) |
|
|
101
|
+
|
|
102
|
+
Unknown names and unknown attributes fail validation. That is intentional:
|
|
103
|
+
Markus must not decay into an untyped CSS API. See
|
|
104
|
+
[docs/LANGUAGE.md](docs/LANGUAGE.md) for the full contract.
|
|
105
|
+
|
|
106
|
+
## Demo site
|
|
107
|
+
|
|
108
|
+
**[anthusai.github.io/Markus/](https://anthusai.github.io/Markus/)** — written in
|
|
109
|
+
Markus and built by Markus.
|
|
110
|
+
|
|
111
|
+
To run the same site locally:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pip install -e ".[dev]"
|
|
115
|
+
markus site site --out _site --serve --port 43147
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Preview locally
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
markus preview examples/getting-started.md
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Development
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pip install -e ".[dev]"
|
|
128
|
+
behave # Gherkin behavior specs
|
|
129
|
+
ruff check src features
|
|
130
|
+
python -m build
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT © Anthus AI Solutions
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Markus
|
|
2
|
+
|
|
3
|
+
**GitHub-flavored Markdown with a small vocabulary for layout intent.**
|
|
4
|
+
|
|
5
|
+
Markus keeps Markdown as the content language, then adds colon-fenced
|
|
6
|
+
directives for the things GFM cannot say: *this is a pull quote*, *these
|
|
7
|
+
items are peer cards*, *these two views belong together*. Authors encode
|
|
8
|
+
meaning. The renderer turns that meaning into accessible HTML and responsive
|
|
9
|
+
CSS — or, later, print, EPUB, or email.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install anthus-markus
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Python 3.10 or newer.
|
|
18
|
+
|
|
19
|
+
## Convert a page
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
markus convert examples/getting-started.md -o page.html
|
|
23
|
+
markus validate examples/getting-started.md
|
|
24
|
+
markus ast examples/getting-started.md
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Python API:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from markusmd import convert
|
|
31
|
+
|
|
32
|
+
html = convert(open("page.md", encoding="utf-8").read())
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Directives
|
|
36
|
+
|
|
37
|
+
```md
|
|
38
|
+
:::pull-quote{attribution="Engineering principle" tone="primary"}
|
|
39
|
+
The best system is often the one whose failure modes you can explain.
|
|
40
|
+
:::
|
|
41
|
+
|
|
42
|
+
:::feature-grid{columns=3}
|
|
43
|
+
:::feature-card{icon="bolt"}
|
|
44
|
+
## Low latency
|
|
45
|
+
Keep common interactions local.
|
|
46
|
+
:::
|
|
47
|
+
:::
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The 0.1 vocabulary:
|
|
51
|
+
|
|
52
|
+
| Directive | Intent |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| `callout` (`note`, `warning`, `tip`, `caution`) | Status or editorial note |
|
|
55
|
+
| `pull-quote` | Editorial quotation |
|
|
56
|
+
| `card-grid` / `card` | Peer items |
|
|
57
|
+
| `two-up` / `column` | A conceptual pair |
|
|
58
|
+
| `figure` | Media with caption and credit |
|
|
59
|
+
| `details` | Progressive disclosure |
|
|
60
|
+
| `aside` | Supporting, non-linear material |
|
|
61
|
+
| `metric` | A labeled fact (`::metric{...}`) |
|
|
62
|
+
|
|
63
|
+
Unknown names and unknown attributes fail validation. That is intentional:
|
|
64
|
+
Markus must not decay into an untyped CSS API. See
|
|
65
|
+
[docs/LANGUAGE.md](docs/LANGUAGE.md) for the full contract.
|
|
66
|
+
|
|
67
|
+
## Demo site
|
|
68
|
+
|
|
69
|
+
**[anthusai.github.io/Markus/](https://anthusai.github.io/Markus/)** — written in
|
|
70
|
+
Markus and built by Markus.
|
|
71
|
+
|
|
72
|
+
To run the same site locally:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pip install -e ".[dev]"
|
|
76
|
+
markus site site --out _site --serve --port 43147
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Preview locally
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
markus preview examples/getting-started.md
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Development
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pip install -e ".[dev]"
|
|
89
|
+
behave # Gherkin behavior specs
|
|
90
|
+
ruff check src features
|
|
91
|
+
python -m build
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## License
|
|
95
|
+
|
|
96
|
+
MIT © Anthus AI Solutions
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Markus language
|
|
2
|
+
|
|
3
|
+
Markus is **GitHub Flavored Markdown** plus a small registry of colon-fenced
|
|
4
|
+
semantic directives. Authors encode intent. The renderer chooses layout.
|
|
5
|
+
|
|
6
|
+
## Document metadata
|
|
7
|
+
|
|
8
|
+
Optional YAML front matter:
|
|
9
|
+
|
|
10
|
+
```md
|
|
11
|
+
---
|
|
12
|
+
title: The future of local inference
|
|
13
|
+
authors:
|
|
14
|
+
- Ada
|
|
15
|
+
date: 2026-09-04
|
|
16
|
+
---
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Container directives
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
:::name{key="value" flag other=1}
|
|
23
|
+
Markdown, including nested directives.
|
|
24
|
+
:::
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| Name | Meaning | Notable attributes |
|
|
28
|
+
| --- | --- | --- |
|
|
29
|
+
| `callout` | Note, warning, tip, or caution | `kind`, `title` |
|
|
30
|
+
| `note`, `warning`, `tip`, `caution` | Aliases for `callout` | `title` |
|
|
31
|
+
| `pull-quote` | Editorial quotation | `attribution`, `source`, `tone`, `align` |
|
|
32
|
+
| `card-grid` / `feature-grid` | Peer cards | `label`, `columns` (hint) |
|
|
33
|
+
| `card` / `feature-card` | One peer item | `icon`, `title`, `span` (`1`–`6` or `full`) |
|
|
34
|
+
| `two-up` | A conceptual pair | `ratio` (`1:1`, `2:1`, `1:2`), `align` |
|
|
35
|
+
| `column` | One side of `two-up` | — |
|
|
36
|
+
| `figure` | Media with caption | `src`, `alt`, `caption`, `credit` |
|
|
37
|
+
| `details` | Progressive disclosure | `summary`, `open` |
|
|
38
|
+
| `aside` | Supporting, non-linear material | `title` |
|
|
39
|
+
| `tabs` | Tabbed container | `label` |
|
|
40
|
+
| `tab` | One tab panel | `label` |
|
|
41
|
+
| `step-list` | Ordered sequence of steps | — |
|
|
42
|
+
| `step` | Single step | — |
|
|
43
|
+
| `timeline` | Chronological sequence | `label` |
|
|
44
|
+
| `timeline-event` | Single event in a timeline | `date`, `time`, `title`, `icon` |
|
|
45
|
+
|
|
46
|
+
A trailing kramdown-style attribute list is also accepted inside a directive:
|
|
47
|
+
|
|
48
|
+
```md
|
|
49
|
+
:::pull-quote
|
|
50
|
+
> Measure what matters.
|
|
51
|
+
{: attribution="Editorial principle" }
|
|
52
|
+
:::
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Leaf directives
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
::metric{value="12" unit="ms" label="p95 latency" delta="-8%"}
|
|
59
|
+
::video{src="screencast.mp4" title="Walkthrough"}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
| Name | Meaning | Notable attributes |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `metric` | Key metric fact | `value`, `unit`, `label`, `delta` |
|
|
65
|
+
| `video` | Video player | `src`, `title`, `poster` |
|
|
66
|
+
|
|
67
|
+
## Nesting rules
|
|
68
|
+
|
|
69
|
+
- `card-grid` may contain only `card` (or the `feature-card` alias)
|
|
70
|
+
- `two-up` must contain exactly two `column` children
|
|
71
|
+
- `tabs` may contain only `tab`
|
|
72
|
+
- `step-list` may contain only `step`
|
|
73
|
+
- `timeline` may contain only `timeline-event`
|
|
74
|
+
- Other containers may nest Markdown and further directives
|
|
75
|
+
- Fenced code blocks are not scanned for directives
|
|
76
|
+
|
|
77
|
+
## What does not belong in source
|
|
78
|
+
|
|
79
|
+
Do not add `margin`, `width`, `font-size`, or other presentation keys.
|
|
80
|
+
Unknown directive names and unknown attributes fail validation.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Getting started with Markus
|
|
2
|
+
|
|
3
|
+
Markus is GitHub Flavored Markdown plus colon-fenced directives that name
|
|
4
|
+
layout *intent* rather than CSS.
|
|
5
|
+
|
|
6
|
+
:::pull-quote{attribution="Engineering principle" tone="primary"}
|
|
7
|
+
The best system is often the one whose failure modes you can explain.
|
|
8
|
+
:::
|
|
9
|
+
|
|
10
|
+
:::feature-grid{columns=3}
|
|
11
|
+
:::feature-card{icon="bolt"}
|
|
12
|
+
## Low latency
|
|
13
|
+
|
|
14
|
+
Keep common interactions local to minimize round trips.
|
|
15
|
+
:::
|
|
16
|
+
|
|
17
|
+
:::feature-card{icon="lock"}
|
|
18
|
+
## Private by default
|
|
19
|
+
|
|
20
|
+
Do not transmit user data unless the task requires it.
|
|
21
|
+
:::
|
|
22
|
+
|
|
23
|
+
:::feature-card{icon="gauge"}
|
|
24
|
+
## Measurable cost
|
|
25
|
+
|
|
26
|
+
Track tokens, watts, requests, and time-to-result.
|
|
27
|
+
:::
|
|
28
|
+
:::
|
|
29
|
+
|
|
30
|
+
:::two-up{ratio="1:1" align="start"}
|
|
31
|
+
:::column
|
|
32
|
+
## What changes
|
|
33
|
+
|
|
34
|
+
- A local model lowers marginal request cost
|
|
35
|
+
- Deployment becomes a systems problem
|
|
36
|
+
:::
|
|
37
|
+
|
|
38
|
+
:::column
|
|
39
|
+
## What remains
|
|
40
|
+
|
|
41
|
+
- Evaluation
|
|
42
|
+
- Retrieval quality
|
|
43
|
+
- UX
|
|
44
|
+
- Observability
|
|
45
|
+
:::
|
|
46
|
+
:::
|
|
47
|
+
|
|
48
|
+
:::callout{kind="note" title="Editorial guidance"}
|
|
49
|
+
Use `two-up` to express a conceptual pairing, not merely because two
|
|
50
|
+
paragraphs happen to fit beside each other.
|
|
51
|
+
:::
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
Feature: Markus command line
|
|
2
|
+
As a writer in a terminal
|
|
3
|
+
I want to convert, validate, and inspect Markus files
|
|
4
|
+
So that I can publish HTML without embedding the library myself
|
|
5
|
+
|
|
6
|
+
Scenario: Convert a file to HTML
|
|
7
|
+
Given a Markus file "page.md" with:
|
|
8
|
+
"""
|
|
9
|
+
# Hello Markus
|
|
10
|
+
"""
|
|
11
|
+
When I run "markus convert page.md --fragment --no-css"
|
|
12
|
+
Then the command should succeed
|
|
13
|
+
And stdout should contain "<h1>Hello Markus</h1>"
|
|
14
|
+
|
|
15
|
+
Scenario: Validate a well-formed file
|
|
16
|
+
Given a Markus file "ok.md" with:
|
|
17
|
+
"""
|
|
18
|
+
:::tip
|
|
19
|
+
Ship the small vocabulary first.
|
|
20
|
+
:::
|
|
21
|
+
"""
|
|
22
|
+
When I run "markus validate ok.md"
|
|
23
|
+
Then the command should succeed
|
|
24
|
+
And stdout should contain "ok"
|
|
25
|
+
|
|
26
|
+
Scenario: Validate rejects unknown directives
|
|
27
|
+
Given a Markus file "bad.md" with:
|
|
28
|
+
"""
|
|
29
|
+
:::carousel
|
|
30
|
+
Nope.
|
|
31
|
+
:::
|
|
32
|
+
"""
|
|
33
|
+
When I run "markus validate bad.md"
|
|
34
|
+
Then the command should fail
|
|
35
|
+
And stderr should contain "Unknown directive 'carousel'"
|
|
36
|
+
|
|
37
|
+
Scenario: Print a JSON AST
|
|
38
|
+
Given a Markus file "quote.md" with:
|
|
39
|
+
"""
|
|
40
|
+
:::pull-quote{attribution="Ada"}
|
|
41
|
+
Make it matter.
|
|
42
|
+
:::
|
|
43
|
+
"""
|
|
44
|
+
When I run "markus ast quote.md"
|
|
45
|
+
Then the command should succeed
|
|
46
|
+
And stdout should contain "pull-quote"
|
|
47
|
+
And stdout should contain "Ada"
|
|
48
|
+
|
|
49
|
+
Scenario: Convert a file to HTML with minified CSS
|
|
50
|
+
Given a Markus file "styled.md" with:
|
|
51
|
+
"""
|
|
52
|
+
# Styled Page
|
|
53
|
+
"""
|
|
54
|
+
When I run "markus convert styled.md --minify-css"
|
|
55
|
+
Then the command should succeed
|
|
56
|
+
And stdout should contain "<h1>Styled Page</h1>"
|
|
57
|
+
And stdout should contain "<style>"
|
|
58
|
+
And stdout should not contain "/* Markus default presentation layer"
|
|
59
|
+
And stdout should contain ":root{"
|
|
60
|
+
|
|
61
|
+
Scenario: Convert with minified CSS and no-css omits CSS
|
|
62
|
+
Given a Markus file "plain.md" with:
|
|
63
|
+
"""
|
|
64
|
+
# Plain Page
|
|
65
|
+
"""
|
|
66
|
+
When I run "markus convert plain.md --minify-css --no-css"
|
|
67
|
+
Then the command should succeed
|
|
68
|
+
And stdout should contain "<h1>Plain Page</h1>"
|
|
69
|
+
And stdout should not contain "<style>"
|
|
70
|
+
|
|
71
|
+
Scenario: Convert fragment with minified CSS
|
|
72
|
+
Given a Markus file "frag.md" with:
|
|
73
|
+
"""
|
|
74
|
+
# Fragment
|
|
75
|
+
"""
|
|
76
|
+
When I run "markus convert frag.md --fragment --minify-css"
|
|
77
|
+
Then the command should succeed
|
|
78
|
+
And stdout should contain "<style>"
|
|
79
|
+
And stdout should not contain "/* Markus default presentation layer"
|
|
80
|
+
And stdout should contain "markus-document"
|
|
81
|
+
And stdout should contain "<h1>Fragment</h1>"
|