ikat 0.2.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.
- ikat-0.2.1/.github/workflows/ci.yml +78 -0
- ikat-0.2.1/.github/workflows/pages.yml +96 -0
- ikat-0.2.1/.github/workflows/release.yml +73 -0
- ikat-0.2.1/.gitignore +26 -0
- ikat-0.2.1/Cargo.lock +4479 -0
- ikat-0.2.1/Cargo.toml +28 -0
- ikat-0.2.1/DESIGN.md +181 -0
- ikat-0.2.1/LICENSE-APACHE +176 -0
- ikat-0.2.1/LICENSE-MIT +25 -0
- ikat-0.2.1/PKG-INFO +329 -0
- ikat-0.2.1/README.md +310 -0
- ikat-0.2.1/docs/ARCHITECTURE.md +302 -0
- ikat-0.2.1/docs/FORMAT-DRAFT.md +223 -0
- ikat-0.2.1/docs/QUICKREF.md +126 -0
- ikat-0.2.1/docs/RESEARCH.md +193 -0
- ikat-0.2.1/docs/ROADMAP.md +233 -0
- ikat-0.2.1/examples/demo.py +46 -0
- ikat-0.2.1/examples/headsproof.py +88 -0
- ikat-0.2.1/examples/ikat-paper/README.md +36 -0
- ikat-0.2.1/examples/ikat-paper/build.py +170 -0
- ikat-0.2.1/examples/ikat-paper/ikat-paper.md +197 -0
- ikat-0.2.1/examples/ikat-paper/ikat.toml +16 -0
- ikat-0.2.1/examples/ikat-paper/refs.bib +24 -0
- ikat-0.2.1/examples/ikat-paper/skel.tex +32 -0
- ikat-0.2.1/examples/ikat.toml +11 -0
- ikat-0.2.1/examples/mini.md +15 -0
- ikat-0.2.1/examples/plotproof.py +22 -0
- ikat-0.2.1/pyproject.toml +30 -0
- ikat-0.2.1/python/ikat/__init__.py +74 -0
- ikat-0.2.1/python/ikat/cli.py +293 -0
- ikat-0.2.1/python/ikat/compile.py +116 -0
- ikat-0.2.1/python/ikat/document.py +197 -0
- ikat-0.2.1/python/ikat/mcp_server.py +151 -0
- ikat-0.2.1/python/ikat/pipeline.py +159 -0
- ikat-0.2.1/python/ikat/templates/acm-sigconf-head.tex +32 -0
- ikat-0.2.1/python/ikat/templates/aps-head.tex +29 -0
- ikat-0.2.1/python/ikat/templates/article-1col-head.tex +23 -0
- ikat-0.2.1/python/ikat/templates/article-2col-head.tex +23 -0
- ikat-0.2.1/python/ikat/templates/article-3col-head.tex +33 -0
- ikat-0.2.1/python/ikat/templates/arxiv-head.tex +25 -0
- ikat-0.2.1/python/ikat/templates/elsevier-head.tex +34 -0
- ikat-0.2.1/python/ikat/templates/ieee-conference-head.tex +21 -0
- ikat-0.2.1/python/ikat/templates/skeleton-plain.tex +32 -0
- ikat-0.2.1/python/ikat/templates/springer-llncs-head.tex +23 -0
- ikat-0.2.1/python/ikat/texenv.py +92 -0
- ikat-0.2.1/site/assets/fonts/README.md +9 -0
- ikat-0.2.1/site/assets/fonts/barlow-condensed-600.woff2 +0 -0
- ikat-0.2.1/site/assets/fonts/barlow-condensed-700.woff2 +0 -0
- ikat-0.2.1/site/assets/fonts/barlowcondensed-OFL.txt +93 -0
- ikat-0.2.1/site/assets/fonts/ibm-plex-mono-400.woff2 +0 -0
- ikat-0.2.1/site/assets/fonts/ibmplexmono-OFL.txt +93 -0
- ikat-0.2.1/site/assets/fonts/source-sans-3-variable.woff2 +0 -0
- ikat-0.2.1/site/assets/fonts/sourcesans3-OFL.txt +93 -0
- ikat-0.2.1/site/assets/ikat-paper.pdf +0 -0
- ikat-0.2.1/site/hello-paper.md +9 -0
- ikat-0.2.1/site/index.html +259 -0
- ikat-0.2.1/site/script.js +57 -0
- ikat-0.2.1/site/styles.css +1296 -0
- ikat-0.2.1/skills/ikat/SKILL.md +30 -0
- ikat-0.2.1/skills/ikat-api/SKILL.md +59 -0
- ikat-0.2.1/skills/ikat-cli/SKILL.md +50 -0
- ikat-0.2.1/skills/ikat-mcp/SKILL.md +48 -0
- ikat-0.2.1/src/config.rs +473 -0
- ikat-0.2.1/src/doc.rs +1065 -0
- ikat-0.2.1/src/esc.rs +281 -0
- ikat-0.2.1/src/lib.rs +227 -0
- ikat-0.2.1/src/md_spike.rs +225 -0
- ikat-0.2.1/src/mermaid.rs +450 -0
- ikat-0.2.1/src/plot.rs +562 -0
- ikat-0.2.1/src/table.rs +213 -0
- ikat-0.2.1/src/tectonic.rs +43 -0
- ikat-0.2.1/src/texenv.rs +253 -0
- ikat-0.2.1/tests/test_core.py +123 -0
- ikat-0.2.1/tests/test_floats.py +58 -0
- ikat-0.2.1/tests/test_paper.py +79 -0
- ikat-0.2.1/tests/test_skeleton.py +60 -0
- ikat-0.2.1/tests/test_surface.py +132 -0
- ikat-0.2.1/tests/test_template.py +94 -0
- ikat-0.2.1/tests/test_texenv.py +122 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
strategy:
|
|
10
|
+
fail-fast: false
|
|
11
|
+
matrix:
|
|
12
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
13
|
+
runs-on: ${{ matrix.os }}
|
|
14
|
+
defaults:
|
|
15
|
+
run:
|
|
16
|
+
shell: bash
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
23
|
+
- name: Venv + build deps
|
|
24
|
+
# maturin develop refuses a bare runner python: it wants a
|
|
25
|
+
# virtualenv. We make one and address it explicitly — no
|
|
26
|
+
# activation, so this works identically on all three shells.
|
|
27
|
+
run: |
|
|
28
|
+
python -m venv .venv
|
|
29
|
+
if [ -d .venv/Scripts ]; then VENV_BIN="$PWD/.venv/Scripts";
|
|
30
|
+
else VENV_BIN="$PWD/.venv/bin"; fi
|
|
31
|
+
echo "VENV_BIN=$VENV_BIN" >> "$GITHUB_ENV"
|
|
32
|
+
"$VENV_BIN"/python -m pip install -q "maturin>=1.15,<2" "pytest>=8" "mcp>=1,<2"
|
|
33
|
+
- name: Rust tests
|
|
34
|
+
run: cargo test --locked
|
|
35
|
+
- name: Build module
|
|
36
|
+
run: '"$VENV_BIN"/python -m maturin develop'
|
|
37
|
+
- name: Python tests
|
|
38
|
+
run: '"$VENV_BIN"/python -m pytest tests/'
|
|
39
|
+
|
|
40
|
+
tex:
|
|
41
|
+
# Compile check on real TeX Live (Ubuntu apt packages):
|
|
42
|
+
# the demo and the showcase paper must build with
|
|
43
|
+
# zero undefined citations.
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
defaults:
|
|
46
|
+
run:
|
|
47
|
+
shell: bash
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@v4
|
|
50
|
+
- uses: actions/setup-python@v5
|
|
51
|
+
with:
|
|
52
|
+
python-version: "3.12"
|
|
53
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
54
|
+
- name: Install TeX Live
|
|
55
|
+
run: >
|
|
56
|
+
sudo apt-get update -q &&
|
|
57
|
+
sudo apt-get install -y -q
|
|
58
|
+
texlive-latex-base texlive-latex-recommended
|
|
59
|
+
texlive-pictures texlive-publishers
|
|
60
|
+
- name: Venv + build deps
|
|
61
|
+
run: |
|
|
62
|
+
python -m venv .venv
|
|
63
|
+
if [ -d .venv/Scripts ]; then VENV_BIN="$PWD/.venv/Scripts";
|
|
64
|
+
else VENV_BIN="$PWD/.venv/bin"; fi
|
|
65
|
+
echo "VENV_BIN=$VENV_BIN" >> "$GITHUB_ENV"
|
|
66
|
+
"$VENV_BIN"/python -m pip install -q "maturin>=1.15,<2" "mcp>=1,<2"
|
|
67
|
+
- name: Build module
|
|
68
|
+
run: '"$VENV_BIN"/python -m maturin develop'
|
|
69
|
+
- name: Build demo
|
|
70
|
+
run: '"$VENV_BIN"/python examples/demo.py'
|
|
71
|
+
- name: Build showcase paper
|
|
72
|
+
run: '"$VENV_BIN"/python examples/ikat-paper/build.py'
|
|
73
|
+
- name: No undefined citations
|
|
74
|
+
run: |
|
|
75
|
+
if grep -rE "There were undefined references|Citation .* undefined|Undefined control sequence" \
|
|
76
|
+
examples/demo-out examples/ikat-paper/out --include="*.log"; then
|
|
77
|
+
echo "::error::TeX errors in build logs"; exit 1;
|
|
78
|
+
fi
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
name: GitHub Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pages: write
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: github-pages
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
deploy:
|
|
19
|
+
environment:
|
|
20
|
+
name: github-pages
|
|
21
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- name: Check out source
|
|
25
|
+
uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Configure Pages
|
|
28
|
+
uses: actions/configure-pages@v5
|
|
29
|
+
|
|
30
|
+
- name: Validate static site and local references
|
|
31
|
+
shell: bash
|
|
32
|
+
run: |
|
|
33
|
+
test -s site/index.html
|
|
34
|
+
test -s site/styles.css
|
|
35
|
+
test -s site/script.js
|
|
36
|
+
python - <<'PY'
|
|
37
|
+
from html.parser import HTMLParser
|
|
38
|
+
from pathlib import Path
|
|
39
|
+
from urllib.parse import unquote, urlsplit
|
|
40
|
+
import re
|
|
41
|
+
|
|
42
|
+
root = Path("site")
|
|
43
|
+
html = (root / "index.html").read_text(encoding="utf-8")
|
|
44
|
+
|
|
45
|
+
class PageParser(HTMLParser):
|
|
46
|
+
def __init__(self):
|
|
47
|
+
super().__init__()
|
|
48
|
+
self.ids = set()
|
|
49
|
+
self.refs = []
|
|
50
|
+
def handle_starttag(self, tag, attrs):
|
|
51
|
+
attrs = dict(attrs)
|
|
52
|
+
if "id" in attrs:
|
|
53
|
+
self.ids.add(attrs["id"])
|
|
54
|
+
for key in ("href", "src"):
|
|
55
|
+
value = attrs.get(key, "")
|
|
56
|
+
if value:
|
|
57
|
+
self.refs.append(value)
|
|
58
|
+
|
|
59
|
+
page = PageParser()
|
|
60
|
+
page.feed(html)
|
|
61
|
+
errors = []
|
|
62
|
+
for ref in page.refs:
|
|
63
|
+
url = urlsplit(ref)
|
|
64
|
+
if url.scheme or url.netloc:
|
|
65
|
+
continue
|
|
66
|
+
if url.fragment and not url.path and url.fragment not in page.ids:
|
|
67
|
+
errors.append(f"missing in-page target #{url.fragment}")
|
|
68
|
+
continue
|
|
69
|
+
if not url.path:
|
|
70
|
+
continue
|
|
71
|
+
target = root / unquote(url.path)
|
|
72
|
+
if not target.is_file():
|
|
73
|
+
errors.append(f"missing local file for {ref}")
|
|
74
|
+
|
|
75
|
+
css = (root / "styles.css").read_text(encoding="utf-8")
|
|
76
|
+
for raw in re.findall(r"url\([\"']?([^\)\"']+)", css):
|
|
77
|
+
if raw.startswith(("http:", "https:", "data:")):
|
|
78
|
+
continue
|
|
79
|
+
if not (root / unquote(raw)).is_file():
|
|
80
|
+
errors.append(f"missing CSS asset {raw}")
|
|
81
|
+
|
|
82
|
+
if "<title>ikat" not in html:
|
|
83
|
+
errors.append("page title is missing")
|
|
84
|
+
if errors:
|
|
85
|
+
raise SystemExit("\n".join(errors))
|
|
86
|
+
print(f"Static site OK: {len(page.ids)} ids, {len(page.refs)} HTML references, CSS assets present")
|
|
87
|
+
PY
|
|
88
|
+
|
|
89
|
+
- name: Upload Pages artifact
|
|
90
|
+
uses: actions/upload-pages-artifact@v3
|
|
91
|
+
with:
|
|
92
|
+
path: site
|
|
93
|
+
|
|
94
|
+
- name: Deploy to GitHub Pages
|
|
95
|
+
id: deployment
|
|
96
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# Ship a version: push tag vX.Y.Z (must match Cargo.toml + pyproject).
|
|
4
|
+
# PyPI wheels and the crates.io publish run in parallel.
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
tags: ["v*"]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
check-tag:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- name: Tag matches package versions
|
|
17
|
+
run: |
|
|
18
|
+
test "v$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml)" = "${{ github.ref_name }}" \
|
|
19
|
+
|| { echo "::error::tag does not match Cargo.toml"; exit 1; }
|
|
20
|
+
test "v$(sed -n 's/^version = "\(.*\)"/\1/p' pyproject.toml)" = "${{ github.ref_name }}" \
|
|
21
|
+
|| { echo "::error::tag does not match pyproject.toml"; exit 1; }
|
|
22
|
+
|
|
23
|
+
pypi-wheels:
|
|
24
|
+
needs: check-tag
|
|
25
|
+
strategy:
|
|
26
|
+
fail-fast: false
|
|
27
|
+
matrix:
|
|
28
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
29
|
+
runs-on: ${{ matrix.os }}
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
- name: Build wheels
|
|
33
|
+
uses: PyO3/maturin-action@v1
|
|
34
|
+
with:
|
|
35
|
+
command: build
|
|
36
|
+
args: --release --out dist --find-interpreter
|
|
37
|
+
manylinux: auto
|
|
38
|
+
- name: Build sdist (linux only)
|
|
39
|
+
if: matrix.os == 'ubuntu-latest'
|
|
40
|
+
uses: PyO3/maturin-action@v1
|
|
41
|
+
with:
|
|
42
|
+
command: sdist
|
|
43
|
+
args: --out dist
|
|
44
|
+
- uses: actions/upload-artifact@v4
|
|
45
|
+
with:
|
|
46
|
+
name: dist-${{ matrix.os }}
|
|
47
|
+
path: dist/
|
|
48
|
+
|
|
49
|
+
pypi-publish:
|
|
50
|
+
needs: pypi-wheels
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
permissions:
|
|
53
|
+
id-token: write # trusted publishing (OIDC): no API token
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/download-artifact@v4
|
|
56
|
+
with:
|
|
57
|
+
pattern: dist-*
|
|
58
|
+
path: dist
|
|
59
|
+
merge-multiple: true
|
|
60
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
61
|
+
# Trusted publishing: the ikat PyPI project needs this repo +
|
|
62
|
+
# workflow registered as a (pending) publisher. No password.
|
|
63
|
+
|
|
64
|
+
crates-publish:
|
|
65
|
+
needs: check-tag
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@v4
|
|
69
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
70
|
+
- name: Publish to crates.io
|
|
71
|
+
run: cargo publish --locked
|
|
72
|
+
env:
|
|
73
|
+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
ikat-0.2.1/.gitignore
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/target/
|
|
2
|
+
.venv/
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.pyc
|
|
5
|
+
*.pyo
|
|
6
|
+
*.pyd
|
|
7
|
+
*.pdb
|
|
8
|
+
*.so
|
|
9
|
+
*.egg-info/
|
|
10
|
+
dist/
|
|
11
|
+
.pytest_cache/
|
|
12
|
+
examples/demo-out/
|
|
13
|
+
examples/ikat-paper/out/
|
|
14
|
+
*.aux
|
|
15
|
+
*.log
|
|
16
|
+
*.out
|
|
17
|
+
*.toc
|
|
18
|
+
*.bbl
|
|
19
|
+
*.blg
|
|
20
|
+
*.pdf
|
|
21
|
+
!examples/*.pdf
|
|
22
|
+
!site/assets/ikat-paper.pdf
|
|
23
|
+
|
|
24
|
+
# Another agent/design round scratch space (impeccable) — not part of ikat
|
|
25
|
+
PRODUCT.md
|
|
26
|
+
.impeccable/
|