check-gemtext (3876B)
1 #!/usr/bin/env python3 2 """Exercise the Gemini converter with Hugo, without the dither server.""" 3 4 from pathlib import Path 5 import shutil 6 import subprocess 7 import tempfile 8 9 10 repo = Path(__file__).resolve().parent.parent 11 with tempfile.TemporaryDirectory(prefix="gemtext-check-") as directory: 12 root = Path(directory) 13 (root / "layouts/partials").mkdir(parents=True) 14 (root / "layouts/shortcodes").mkdir() 15 (root / "content").mkdir() 16 for name in ("gemtext.gmi", "gemtext-links.gmi"): 17 shutil.copy(repo / "themes/v2/layouts/partials" / name, root / "layouts/partials" / name) 18 (root / "hugo.toml").write_text('baseURL = "https://example.org/"\ndisableKinds = ["home", "taxonomy", "term", "RSS", "sitemap"]\n') 19 (root / "layouts/single.html").write_text('{{ partial "gemtext.gmi" (dict "content" .RawContent "page" .) }}') 20 # Match the image shortcodes' HTML without fetching or resizing images. 21 (root / "layouts/shortcodes/dither.html").write_text('<img src="/{{ .Get 0 }}" {{ with .Inner }}alt="{{ . }}"{{ end }}>') 22 (root / "layouts/shortcodes/thumbnail.html").write_text('<img src="/{{ .Get 0 }}">{{ with .Inner }}<figcaption>{{ . }}</figcaption>{{ end }}') 23 (root / "content/check.md").write_text('''--- 24 title: Check 25 references: 26 - url: https://example.org/guide 27 title: A useful guide 28 --- 29 [First $1][1] and [again][1] start a paragraph 30 that continues with [second][2]. 31 32 Another paragraph uses [first again][1] ([via][3]). 33 34 * [First $1][1] ([via][3]) 35 36 > Quoted text. 37 38 * [First $1][1] 39 40 * [First $1][1] with commentary 41 * Read [this article][4] 42 43 > A quote containing [second][2]. 44 45 Read [inline](https://example.org/inline) too. 46 47 ```markdown 48 Literal [first][1]. 49 50 [99]: https://example.org/code-only 51 ``` 52 53 An [unresolved][98] reference. 54 55 [1]: https://example.org/first 56 [2]: https://example.org/second 57 [3]: https://source.org/post 58 [4]: https://example.org/guide 59 60 {{<dither bare.png "782x600" />}} 61 {{<dither "photos/beach.png" "782x600">}}A "sunny" day & waves.{{</dither>}} 62 63 {{<dither garden.png "782x600">}}A garden 64 with flowers.{{</dither>}} 65 66 {{<thumbnail thumb.png "782x600">}}A caption & a view.{{</thumbnail>}} 67 {{<thumbnail "photos/uncaptioned.png" "782x600" />}} 68 69 Last paragraph with [_a book_][2].''') 70 subprocess.run(["hugo", "build", "--source", str(root)], check=True) 71 result = (root / "public/check/index.html").read_text() 72 expected = [ 73 "First $1 and again start a paragraph\nthat continues with second.\n\n" 74 "=> https://example.org/first First $1\n=> https://example.org/second second", 75 "Another paragraph uses first again.\n\n=> https://example.org/first first again\n" 76 "=> https://source.org/post via source.org", 77 "=> https://example.org/first First $1\n=> https://source.org/post via source.org\n\n> Quoted text.", 78 "* First $1 with commentary\n* Read this article\n\n" 79 "=> https://example.org/first First $1\n=> https://example.org/guide A useful guide", 80 "> A quote containing second.\n\n=> https://example.org/second second", 81 "Read inline too.\n\n=> https://example.org/inline inline", 82 "```markdown\nLiteral [first][1].\n\n[99]: https://example.org/code-only\n```", 83 "An [unresolved][98] reference.", 84 '=> /bare.png\n=> /photos/beach.png Image: A "sunny" day & waves.', 85 "=> /garden.png Image: A garden with flowers.", 86 "=> /thumb.png Image: A caption & a view.\n=> /photos/uncaptioned.png", 87 "Last paragraph with _a book_.\n\n=> https://example.org/second a book", 88 ] 89 for fragment in expected: 90 assert fragment in result, f"Missing expected output:\n{fragment}\n\nActual:\n{result}" 91 assert result.count("=> https://example.org/first ") == 5, result 92 assert "[1]:" not in result, result 93 assert "(via)" not in result, result 94 print("Gemtext conversion checks passed.")