markfeyn 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.
- markfeyn-0.1.0/LICENSE +21 -0
- markfeyn-0.1.0/MANIFEST.in +12 -0
- markfeyn-0.1.0/PKG-INFO +458 -0
- markfeyn-0.1.0/README.md +427 -0
- markfeyn-0.1.0/THIRD_PARTY_NOTICES.md +15 -0
- markfeyn-0.1.0/docs/development.md +342 -0
- markfeyn-0.1.0/docs/examples/edges.md +156 -0
- markfeyn-0.1.0/docs/examples/from-the-literature.md +177 -0
- markfeyn-0.1.0/docs/examples/index.md +12 -0
- markfeyn-0.1.0/docs/examples/layout.md +274 -0
- markfeyn-0.1.0/docs/examples/loops.md +310 -0
- markfeyn-0.1.0/docs/examples/scattering-decays.md +443 -0
- markfeyn-0.1.0/docs/examples/symmetric-layout.md +274 -0
- markfeyn-0.1.0/docs/examples/vertices.md +129 -0
- markfeyn-0.1.0/docs/index.md +21 -0
- markfeyn-0.1.0/docs/installation.md +121 -0
- markfeyn-0.1.0/docs/syntax.md +656 -0
- markfeyn-0.1.0/licenses/ELKJS-EPL-2.0.md +264 -0
- markfeyn-0.1.0/mkdocs.yml +62 -0
- markfeyn-0.1.0/package-lock.json +711 -0
- markfeyn-0.1.0/package.json +31 -0
- markfeyn-0.1.0/properdocs.yml +64 -0
- markfeyn-0.1.0/pyproject.toml +72 -0
- markfeyn-0.1.0/setup.cfg +4 -0
- markfeyn-0.1.0/src/markfeyn/__init__.py +5 -0
- markfeyn-0.1.0/src/markfeyn/__main__.py +115 -0
- markfeyn-0.1.0/src/markfeyn/assets/feynman-diagrams-loader.js +55 -0
- markfeyn-0.1.0/src/markfeyn/assets/feynman-diagrams.js +216 -0
- markfeyn-0.1.0/src/markfeyn/core.py +72 -0
- markfeyn-0.1.0/src/markfeyn/mkdocs_plugin.py +21 -0
- markfeyn-0.1.0/src/markfeyn/properdocs_plugin.py +21 -0
- markfeyn-0.1.0/src/markfeyn/renderer/feynman-diagrams.js +101 -0
- markfeyn-0.1.0/src/markfeyn/renderer/geometry/metrics.js +47 -0
- markfeyn-0.1.0/src/markfeyn/renderer/geometry/paths.js +458 -0
- markfeyn-0.1.0/src/markfeyn/renderer/geometry/vertex-shapes.js +35 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/coordinates.js +413 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/crowding.js +44 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/elk-compiler.js +242 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/elk-options.js +74 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/elk-runner.js +27 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/external-order.js +189 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/fallback.js +495 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/incremental.js +157 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/labels/boxes.js +371 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/labels/geometry.js +608 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/labels/placement.js +432 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/labels/regions.js +187 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/labels/scoring.js +192 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/labels.js +11 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/layout.js +239 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/loop-candidates.js +655 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/model.js +219 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/multiloop.js +616 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/normalization.js +74 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/normalizers/alignment.js +57 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/normalizers/edge-bounds.js +80 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/normalizers/elk.js +107 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/normalizers/process.js +419 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/normalizers/spring.js +358 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/normalizers/tikz-orientation.js +247 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/options.js +80 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/orientation.js +74 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/parallel.js +36 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/score.js +1029 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/strategies.js +157 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/symmetric-unclassified.js +255 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/symmetric.js +432 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/topology/biconnected.js +136 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/topology/classification.js +120 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/topology/cycles.js +249 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/topology/fermion-flow.js +148 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/topology/graph.js +98 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/topology/parallel.js +41 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/topology/regions.js +240 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/topology.js +131 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout/validate.js +98 -0
- markfeyn-0.1.0/src/markfeyn/renderer/layout-engine.js +174 -0
- markfeyn-0.1.0/src/markfeyn/renderer/parser/braces.js +36 -0
- markfeyn-0.1.0/src/markfeyn/renderer/parser/constants.js +117 -0
- markfeyn-0.1.0/src/markfeyn/renderer/parser/directives.js +97 -0
- markfeyn-0.1.0/src/markfeyn/renderer/parser/edges.js +140 -0
- markfeyn-0.1.0/src/markfeyn/renderer/parser/feynman-parser.js +115 -0
- markfeyn-0.1.0/src/markfeyn/renderer/parser/index.js +56 -0
- markfeyn-0.1.0/src/markfeyn/renderer/parser/labels.js +125 -0
- markfeyn-0.1.0/src/markfeyn/renderer/parser/options.js +527 -0
- markfeyn-0.1.0/src/markfeyn/renderer/parser/vertices.js +293 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/braces.js +202 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/definitions.js +57 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/dom.js +15 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/edges.js +361 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/label-markup.js +423 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/labels.js +228 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/mathjax.js +201 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/paths.js +1 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/styles.js +203 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/svg-renderer.js +307 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/vertex-shapes.js +1 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/vertices.js +123 -0
- markfeyn-0.1.0/src/markfeyn/renderer/render/visual-defaults.js +60 -0
- markfeyn-0.1.0/src/markfeyn.egg-info/PKG-INFO +458 -0
- markfeyn-0.1.0/src/markfeyn.egg-info/SOURCES.txt +133 -0
- markfeyn-0.1.0/src/markfeyn.egg-info/dependency_links.txt +1 -0
- markfeyn-0.1.0/src/markfeyn.egg-info/entry_points.txt +5 -0
- markfeyn-0.1.0/src/markfeyn.egg-info/requires.txt +10 -0
- markfeyn-0.1.0/src/markfeyn.egg-info/top_level.txt +3 -0
- markfeyn-0.1.0/src/mkdocs_feynman_diagrams/__init__.py +5 -0
- markfeyn-0.1.0/src/mkdocs_feynman_diagrams/plugin.py +5 -0
- markfeyn-0.1.0/src/properdocs_feynman_diagrams/__init__.py +5 -0
- markfeyn-0.1.0/src/properdocs_feynman_diagrams/plugin.py +5 -0
- markfeyn-0.1.0/tests/canvas-scaling.test.js +94 -0
- markfeyn-0.1.0/tests/contact-star.test.js +243 -0
- markfeyn-0.1.0/tests/docs-examples.test.js +83 -0
- markfeyn-0.1.0/tests/feynman-visual-snapshots.test.js +170 -0
- markfeyn-0.1.0/tests/helpers/feynman.js +397 -0
- markfeyn-0.1.0/tests/labels.test.js +277 -0
- markfeyn-0.1.0/tests/layout-misc.test.js +170 -0
- markfeyn-0.1.0/tests/loader.test.js +92 -0
- markfeyn-0.1.0/tests/loops.test.js +375 -0
- markfeyn-0.1.0/tests/multiloop.test.js +275 -0
- markfeyn-0.1.0/tests/orientation-crossing.test.js +55 -0
- markfeyn-0.1.0/tests/orientation.test.js +510 -0
- markfeyn-0.1.0/tests/parser-core.test.js +93 -0
- markfeyn-0.1.0/tests/parser-identifiers.test.js +139 -0
- markfeyn-0.1.0/tests/render-diagnostics.test.js +373 -0
- markfeyn-0.1.0/tests/render-dom.test.js +473 -0
- markfeyn-0.1.0/tests/symmetric-refinement.test.js +505 -0
- markfeyn-0.1.0/tests/test_cli.py +114 -0
- markfeyn-0.1.0/tests/test_docs_config.py +20 -0
- markfeyn-0.1.0/tests/test_docs_language.py +34 -0
- markfeyn-0.1.0/tests/test_lazy_load.py +85 -0
- markfeyn-0.1.0/tests/test_mkdocs_integration.py +93 -0
- markfeyn-0.1.0/tests/test_plugin.py +142 -0
- markfeyn-0.1.0/tests/test_properdocs_integration.py +91 -0
- markfeyn-0.1.0/tests/test_version.py +15 -0
- markfeyn-0.1.0/tests/topology-performance.test.js +89 -0
markfeyn-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MarkFeyn contributors
|
|
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,12 @@
|
|
|
1
|
+
include README.md
|
|
2
|
+
include LICENSE
|
|
3
|
+
include THIRD_PARTY_NOTICES.md
|
|
4
|
+
include package.json
|
|
5
|
+
include package-lock.json
|
|
6
|
+
include mkdocs.yml
|
|
7
|
+
include properdocs.yml
|
|
8
|
+
recursive-include licenses *.md
|
|
9
|
+
recursive-include src/markfeyn/renderer *.js
|
|
10
|
+
recursive-include src/markfeyn/assets *.js
|
|
11
|
+
recursive-include docs *.md
|
|
12
|
+
recursive-include tests *.py *.js
|
markfeyn-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: markfeyn
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Render simple Feynman diagram code blocks as native SVG in MkDocs and ProperDocs.
|
|
5
|
+
Author: MarkFeyn contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Documentation, https://lalmei.github.io/markfeyn/
|
|
8
|
+
Project-URL: Repository, https://github.com/lalmei/markfeyn
|
|
9
|
+
Keywords: mkdocs,properdocs,markdown,feynman,physics,svg
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: JavaScript
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Topic :: Documentation
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
License-File: THIRD_PARTY_NOTICES.md
|
|
22
|
+
License-File: licenses/ELKJS-EPL-2.0.md
|
|
23
|
+
Provides-Extra: mkdocs
|
|
24
|
+
Requires-Dist: mkdocs>=1.5; extra == "mkdocs"
|
|
25
|
+
Provides-Extra: properdocs
|
|
26
|
+
Requires-Dist: properdocs>=1.6.7; extra == "properdocs"
|
|
27
|
+
Provides-Extra: all
|
|
28
|
+
Requires-Dist: mkdocs>=1.5; extra == "all"
|
|
29
|
+
Requires-Dist: properdocs>=1.6.7; extra == "all"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# MarkFeyn
|
|
33
|
+
|
|
34
|
+
[](https://github.com/lalmei/markfeyn/actions/workflows/ci.yml)
|
|
35
|
+
[](https://lalmei.github.io/markfeyn/)
|
|
36
|
+
|
|
37
|
+
📖 **Documentation:** https://lalmei.github.io/markfeyn/
|
|
38
|
+
|
|
39
|
+
MarkFeyn renders fenced `feynman` code blocks as native SVG diagrams in MkDocs and ProperDocs.
|
|
40
|
+
|
|
41
|
+
## Examples
|
|
42
|
+
|
|
43
|
+
A short text-based syntax produces publication-style diagrams, from simple
|
|
44
|
+
tree-level scattering to loops and QCD vertices. More examples live in
|
|
45
|
+
[`docs/examples/`](docs/examples/).
|
|
46
|
+
|
|
47
|
+
<table>
|
|
48
|
+
<tr>
|
|
49
|
+
<th>Source</th>
|
|
50
|
+
<th>Rendered</th>
|
|
51
|
+
</tr>
|
|
52
|
+
<tr>
|
|
53
|
+
<td>
|
|
54
|
+
|
|
55
|
+
```feynman
|
|
56
|
+
incoming e_minus e_plus
|
|
57
|
+
outgoing mu_plus mu_minus
|
|
58
|
+
fermion e_minus->ann
|
|
59
|
+
anti fermion e_plus->ann
|
|
60
|
+
photon ann->prod[momentum'=k]
|
|
61
|
+
anti fermion prod->mu_plus
|
|
62
|
+
fermion prod->mu_minus
|
|
63
|
+
label e_minus:e^- e_plus:e^+ mu_plus:\mu^+ mu_minus:\mu^- ann->prod:\gamma
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
</td>
|
|
67
|
+
<td><img src="docs/assets/readme/ee-to-mumu.svg" alt="e+ e- to mu+ mu- s-channel annihilation diagram" width="360"></td>
|
|
68
|
+
</tr>
|
|
69
|
+
<tr>
|
|
70
|
+
<td>
|
|
71
|
+
|
|
72
|
+
```feynman
|
|
73
|
+
incoming e_minus e_plus
|
|
74
|
+
outgoing e_plus_out e_minus_out
|
|
75
|
+
fermion e_minus->upper upper->e_minus_out
|
|
76
|
+
photon upper->lower[edge label=\gamma]
|
|
77
|
+
anti fermion e_plus->lower lower->e_plus_out
|
|
78
|
+
label e_minus:e^- e_plus:e^+ e_minus_out:e^- e_plus_out:e^+
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
</td>
|
|
82
|
+
<td><img src="docs/assets/readme/bhabha-scattering.svg" alt="Bhabha scattering t-channel photon exchange diagram" width="300"></td>
|
|
83
|
+
</tr>
|
|
84
|
+
<tr>
|
|
85
|
+
<td>
|
|
86
|
+
|
|
87
|
+
```feynman
|
|
88
|
+
incoming q
|
|
89
|
+
outgoing q2 g
|
|
90
|
+
fermion q->v1 v1->q2
|
|
91
|
+
gluon v1->g
|
|
92
|
+
label q:q q2:q g:g
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
</td>
|
|
96
|
+
<td><img src="docs/assets/readme/gluon-emission.svg" alt="Quark radiating a gluon" width="280"></td>
|
|
97
|
+
</tr>
|
|
98
|
+
<tr>
|
|
99
|
+
<td>
|
|
100
|
+
|
|
101
|
+
```feynman
|
|
102
|
+
incoming mu
|
|
103
|
+
outgoing numu e nue
|
|
104
|
+
fermion mu->v v->numu
|
|
105
|
+
boson v->w
|
|
106
|
+
fermion w->e
|
|
107
|
+
anti fermion w->nue
|
|
108
|
+
label mu:\mu^- numu:\nu_\mu e:e^- nue:\overline{\nu}_e v->w:W^-
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
</td>
|
|
112
|
+
<td><img src="docs/assets/readme/muon-decay.svg" alt="Muon decay via a virtual W boson" width="320"></td>
|
|
113
|
+
</tr>
|
|
114
|
+
<tr>
|
|
115
|
+
<td>
|
|
116
|
+
|
|
117
|
+
```feynman
|
|
118
|
+
incoming i1 i2
|
|
119
|
+
outgoing f1 f2
|
|
120
|
+
fermion i1->a b->f1 a->c[edge label'=q]
|
|
121
|
+
anti fermion i2->c d->f2 b->d[edge label=\nu_\mu]
|
|
122
|
+
photon a->b[edge label=W^-] c->d[edge label'=W^+]
|
|
123
|
+
label i1:d i2:\overline{s} f1:\mu^- f2:\mu^+
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
</td>
|
|
127
|
+
<td><img src="docs/assets/readme/w-box-diagram.svg" alt="One-loop W boson box diagram" width="400"></td>
|
|
128
|
+
</tr>
|
|
129
|
+
</table>
|
|
130
|
+
|
|
131
|
+
The exact sources used to render these images (including the layout options
|
|
132
|
+
that were trimmed above for brevity) are under
|
|
133
|
+
[`docs/assets/readme/`](docs/assets/readme/), and can be re-rendered with
|
|
134
|
+
`npm run render:readme`.
|
|
135
|
+
|
|
136
|
+
## Installation
|
|
137
|
+
|
|
138
|
+
From a checkout of this repository, install MarkFeyn into your documentation
|
|
139
|
+
project by passing the checkout path to uv. Choose the extra for your engine.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
uv add "/path/to/markfeyn[mkdocs]"
|
|
143
|
+
uv add "/path/to/markfeyn[properdocs]"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Omit the extra if the engine is already installed.
|
|
147
|
+
|
|
148
|
+
Install Material for MkDocs when using the Material theme:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
uv add mkdocs-material
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
From a source checkout:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
uv sync
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
For local development:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
uv sync --group dev
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## MkDocs Setup
|
|
167
|
+
|
|
168
|
+
Enable the plugin in `mkdocs.yml`:
|
|
169
|
+
|
|
170
|
+
```yaml
|
|
171
|
+
theme:
|
|
172
|
+
name: material
|
|
173
|
+
|
|
174
|
+
plugins:
|
|
175
|
+
- search
|
|
176
|
+
- feynman-diagrams
|
|
177
|
+
|
|
178
|
+
markdown_extensions:
|
|
179
|
+
- pymdownx.highlight:
|
|
180
|
+
anchor_linenums: true
|
|
181
|
+
pygments_lang_class: true
|
|
182
|
+
- pymdownx.superfences:
|
|
183
|
+
custom_fences:
|
|
184
|
+
- name: feynman
|
|
185
|
+
class: language-feynman
|
|
186
|
+
format: !!python/name:pymdownx.superfences.fence_code_format
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## ProperDocs Setup
|
|
190
|
+
|
|
191
|
+
Enable the same plugin in `properdocs.yml`:
|
|
192
|
+
|
|
193
|
+
```yaml
|
|
194
|
+
theme:
|
|
195
|
+
name: material
|
|
196
|
+
|
|
197
|
+
plugins:
|
|
198
|
+
- feynman-diagrams
|
|
199
|
+
|
|
200
|
+
markdown_extensions:
|
|
201
|
+
- pymdownx.highlight:
|
|
202
|
+
anchor_linenums: true
|
|
203
|
+
pygments_lang_class: true
|
|
204
|
+
- pymdownx.superfences:
|
|
205
|
+
custom_fences:
|
|
206
|
+
- name: feynman
|
|
207
|
+
class: language-feynman
|
|
208
|
+
format: !!python/name:pymdownx.superfences.fence_code_format
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
The plugin injects and copies the bundled browser renderer automatically. The Markdown parser stays lightweight because diagram parsing and SVG generation happen in the browser.
|
|
212
|
+
|
|
213
|
+
For ProperDocs with `theme: material`, do not add `search` explicitly; Material's `search` plugin is MkDocs-only.
|
|
214
|
+
|
|
215
|
+
To customize the emitted script path:
|
|
216
|
+
|
|
217
|
+
```yaml
|
|
218
|
+
plugins:
|
|
219
|
+
- feynman-diagrams:
|
|
220
|
+
script_path: assets/javascripts/feynman-diagrams.js
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
`script_path` is interpreted relative to the generated site directory. Parent-directory traversal such as `../feynman.js` is rejected.
|
|
224
|
+
|
|
225
|
+
By default the plugin loads the renderer lazily: it injects a tiny loader script (`feynman-diagrams-loader.js`, written next to `script_path`) and the full renderer is only downloaded on pages that contain a `feynman` block. Set `lazy_load: false` to load the renderer on every page instead:
|
|
226
|
+
|
|
227
|
+
```yaml
|
|
228
|
+
plugins:
|
|
229
|
+
- feynman-diagrams:
|
|
230
|
+
lazy_load: false
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Syntax
|
|
234
|
+
|
|
235
|
+
````markdown
|
|
236
|
+
```feynman
|
|
237
|
+
incoming e_minus e_plus
|
|
238
|
+
outgoing mu_plus mu_minus
|
|
239
|
+
fermion e_minus->ann
|
|
240
|
+
anti fermion e_plus->ann
|
|
241
|
+
photon ann->prod[momentum'=k]
|
|
242
|
+
anti fermion prod->mu_plus
|
|
243
|
+
fermion prod->mu_minus
|
|
244
|
+
label e_minus:e^- e_plus:e^+ mu_plus:\mu^+ mu_minus:\mu^- ann->prod:\gamma
|
|
245
|
+
```
|
|
246
|
+
````
|
|
247
|
+
|
|
248
|
+
Visible degree-1 endpoints without `incoming` or `outgoing` declarations are
|
|
249
|
+
kept as unclassified external states and laid out symmetrically when no process
|
|
250
|
+
direction is declared. Balanced two-center trees and symmetric two-point
|
|
251
|
+
self-energy loops without explicit roles receive focused reflection-symmetric
|
|
252
|
+
refinement; this is not a full automorphism engine. Add `incoming` and
|
|
253
|
+
`outgoing` for left-to-right process diagrams and explicit terminal ordering.
|
|
254
|
+
|
|
255
|
+
Supported particles:
|
|
256
|
+
|
|
257
|
+
- `plain`, `line`, or `propagator`: solid line without an arrow
|
|
258
|
+
- `fermion`: solid line with centered arrow
|
|
259
|
+
- `anti fermion` or `anti-fermion`: solid line with reversed arrow
|
|
260
|
+
- `photon`: sinusoidal wave
|
|
261
|
+
- `boson`: alias for `photon`
|
|
262
|
+
- `gluon`: looped/cycloid path
|
|
263
|
+
- `scalar`: dashed line
|
|
264
|
+
- `ghost`: dotted line
|
|
265
|
+
- `invisible` or `hidden`: layout-only edge
|
|
266
|
+
|
|
267
|
+
Labels use `node:text`. Edge labels are also accepted with `from->to:text`.
|
|
268
|
+
Labels support a small TeX-like subset for common symbols and scripts:
|
|
269
|
+
|
|
270
|
+
```feynman
|
|
271
|
+
label electron:e^- muon:\mu^- vertex:\gamma momentum:p_{T}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Per-edge options support TikZ-Feynman-style curves and inline labels:
|
|
275
|
+
|
|
276
|
+
```feynman
|
|
277
|
+
fermion b->c[half left, momentum=k] c->b[half left, momentum'=k-p]
|
|
278
|
+
boson d->e[bend left, edge label=W^+]
|
|
279
|
+
fermion f->g[out=180, in=45]
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Use `brace from->to[side]:label` for grouping braces on manually positioned
|
|
283
|
+
diagrams.
|
|
284
|
+
|
|
285
|
+
Diagram-level options can select layout algorithms, orientation, and sizing:
|
|
286
|
+
|
|
287
|
+
````markdown
|
|
288
|
+
```feynman
|
|
289
|
+
layout spring
|
|
290
|
+
orientation vertical
|
|
291
|
+
size small
|
|
292
|
+
options width=560 height=420
|
|
293
|
+
incoming mu
|
|
294
|
+
outgoing numu nue e
|
|
295
|
+
fermion mu->w w->numu
|
|
296
|
+
boson w->v
|
|
297
|
+
anti fermion v->nue
|
|
298
|
+
fermion v->e
|
|
299
|
+
invisible numu->e
|
|
300
|
+
label mu:\mu^- numu:\nu_\mu nue:\overline{\nu}_e e:e^- w->v:W^-
|
|
301
|
+
```
|
|
302
|
+
````
|
|
303
|
+
|
|
304
|
+
Supported layouts are `spring` (default), `spring-electrical`, `layered`, and
|
|
305
|
+
`tree`, all backed by bundled ELK.js graph layout. Pin nodes manually with
|
|
306
|
+
`position node x y` when an automatic layout is not enough.
|
|
307
|
+
|
|
308
|
+
Common loop topologies also get semantic candidate layouts: triangle loops, box
|
|
309
|
+
loops, tadpoles, generic polygon loops, centered vacuum one-loop diagrams, and
|
|
310
|
+
bounded two-loop nested or overlapping regions are detected and placed
|
|
311
|
+
deterministically before falling back to the general graph layout. Candidate
|
|
312
|
+
scoring includes approximate label, momentum, multiloop recognizability, and
|
|
313
|
+
previous-layout stability checks. Final layouts also run deterministic,
|
|
314
|
+
bounding-box-based label placement so node labels, edge labels, and momentum
|
|
315
|
+
labels can move away from nearby vertices, propagators, loop interiors, and
|
|
316
|
+
other labels while preserving explicit primed/right-side choices. It still does
|
|
317
|
+
not attempt arbitrary higher-order multiloop optimization or exact TeX/TikZ
|
|
318
|
+
font metrics.
|
|
319
|
+
|
|
320
|
+
TikZ-Feynman-style post-layout alignment is available with commands such as
|
|
321
|
+
`horizontal a to b`, `horizontal' a to b`, `vertical a to b`, and
|
|
322
|
+
`vertical' a to b`.
|
|
323
|
+
|
|
324
|
+
Vertex shapes can be selected with `vertex node:shape` pairs:
|
|
325
|
+
|
|
326
|
+
````markdown
|
|
327
|
+
```feynman
|
|
328
|
+
incoming a
|
|
329
|
+
outgoing b c
|
|
330
|
+
fermion a->v v->b
|
|
331
|
+
photon v->blob blob->c
|
|
332
|
+
vertex v:dot blob:blob
|
|
333
|
+
label a:e^- b:e^- c:\gamma
|
|
334
|
+
```
|
|
335
|
+
````
|
|
336
|
+
|
|
337
|
+
Internal vertices are unmarked by default; use `vertex v:dot` for a small
|
|
338
|
+
filled interaction point.
|
|
339
|
+
|
|
340
|
+
Supported shapes are `dot`, `square-dot`, `empty-dot`, `crossed-dot`, `cross`,
|
|
341
|
+
`blob`, and `disk`.
|
|
342
|
+
|
|
343
|
+
Blob and disk vertices can use optional bracketed styling:
|
|
344
|
+
|
|
345
|
+
````markdown
|
|
346
|
+
```feynman
|
|
347
|
+
incoming a
|
|
348
|
+
outgoing b
|
|
349
|
+
plain a->disk disk->b
|
|
350
|
+
vertex disk:disk[hatch=cross,width=96,height=44]
|
|
351
|
+
```
|
|
352
|
+
````
|
|
353
|
+
|
|
354
|
+
Supported hatch fills are `diagonal`, `diagonal-reverse`, `cross`,
|
|
355
|
+
`horizontal`, `vertical`, and `grid`; TikZ-style aliases such as
|
|
356
|
+
`north east lines` and `north west lines` are accepted. `size` and `radius`
|
|
357
|
+
set the circular radius in SVG pixels, and `diameter` sets the full circle
|
|
358
|
+
width. Use `width` and `height` for full elliptical extents, or `rx` and `ry`
|
|
359
|
+
for horizontal and vertical radii. Unequal horizontal and vertical radii render
|
|
360
|
+
as an SVG ellipse.
|
|
361
|
+
|
|
362
|
+
## Manual JavaScript Setup
|
|
363
|
+
|
|
364
|
+
If you do not want to use a plugin, copy the bundled renderer. Manual mode loads the full renderer directly on every page:
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
python -m markfeyn copy-asset docs/javascripts/feynman-diagrams.js
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
(Source checkouts can also copy `src/markfeyn/assets/feynman-diagrams.js` directly.)
|
|
371
|
+
|
|
372
|
+
Then configure MkDocs or ProperDocs directly:
|
|
373
|
+
|
|
374
|
+
```yaml
|
|
375
|
+
extra_javascript:
|
|
376
|
+
- javascripts/feynman-diagrams.js
|
|
377
|
+
|
|
378
|
+
markdown_extensions:
|
|
379
|
+
- pymdownx.highlight:
|
|
380
|
+
anchor_linenums: true
|
|
381
|
+
pygments_lang_class: true
|
|
382
|
+
- pymdownx.superfences:
|
|
383
|
+
custom_fences:
|
|
384
|
+
- name: feynman
|
|
385
|
+
class: language-feynman
|
|
386
|
+
format: !!python/name:pymdownx.superfences.fence_code_format
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## Package Layout
|
|
390
|
+
|
|
391
|
+
```text
|
|
392
|
+
src/markfeyn/
|
|
393
|
+
__init__.py
|
|
394
|
+
core.py
|
|
395
|
+
mkdocs_plugin.py
|
|
396
|
+
properdocs_plugin.py
|
|
397
|
+
renderer/
|
|
398
|
+
feynman-diagrams.js
|
|
399
|
+
assets/
|
|
400
|
+
feynman-diagrams.js
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
The package exposes both plugin entry points:
|
|
404
|
+
|
|
405
|
+
```toml
|
|
406
|
+
[project.entry-points."mkdocs.plugins"]
|
|
407
|
+
feynman-diagrams = "markfeyn.mkdocs_plugin:FeynmanDiagramsPlugin"
|
|
408
|
+
|
|
409
|
+
[project.entry-points."properdocs.plugins"]
|
|
410
|
+
feynman-diagrams = "markfeyn.properdocs_plugin:FeynmanDiagramsPlugin"
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## Verification
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
make test
|
|
417
|
+
make docs
|
|
418
|
+
make build
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Serve docs locally:
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
make serve-properdocs
|
|
425
|
+
make serve-mkdocs
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
The serve targets use `localhost:8001` by default. Override with `DOCS_ADDR=localhost:8010` if that port is busy.
|
|
429
|
+
|
|
430
|
+
## Publishing
|
|
431
|
+
|
|
432
|
+
Build and publish to PyPI:
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
make publish
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
The publish targets upload only `dist/markfeyn-*` artifacts.
|
|
439
|
+
|
|
440
|
+
Publish to TestPyPI first:
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
make publish-test
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
`uv publish` reads credentials from the environment. For PyPI token auth, set:
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
export UV_PUBLISH_TOKEN="pypi-..."
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## Design Choices
|
|
453
|
+
|
|
454
|
+
- Rendering happens in the browser, so MkDocs and ProperDocs builds remain static and fast.
|
|
455
|
+
- MkDocs and ProperDocs use separate adapter classes over the same core implementation.
|
|
456
|
+
- The script supports themes that expose Material-style instant loading through `document$.subscribe`.
|
|
457
|
+
- It falls back to `DOMContentLoaded` for standard static documentation themes.
|
|
458
|
+
- The browser renderer has no JavaScript runtime dependencies.
|