source
table of contents
this page contains the Pyra0 code that's used to generate this website . the full source repository is on SourceHut .
design philosophy
- HTML is the best format for pages , now that i've solved the readability problem . it has the most comprehensive set of semantic elements , is natively supported by the browser , and there are many high-quality libraries for modifying its structure , such as Nokogiri , Floki , or Lambda Soup . formats like Markdown aren't worth the additional complexity of converting them
- write the generator from scratch . frameworks are too cumbersome to work around if you want highly customized page generation
- creating new pages should be easy . automatically insert the title from the filename so you don't need to write any HTML except for the content
- structure content as a wiki instead of a blog . wikis are expected to be timeless and highly edited , and have a freer organizational structure . placing every page at the root of the site allows restructuring without breaking URLs
- don't use too many navigation features . this site used to have series , footnotes , and tags , in addition to the table of contents and backlinks that remain , but it felt too cluttered . too many features will burden the mind more than it aids navigation
- fast build process . under a second , ideally
- achieve accessibility through simplicity
generator.nv
~ include file:
../pyra0/libraries/case.nv
../pyra0/libraries/ruby.nv
../pyra0/libraries/inline.nv
../pyra0/libraries/nokogiri.nv
- get html for each page
- collect backlinks
- render backlinks
- insert table of contents
- insert source code
- wrap each page
- output the website
- copy the static assets
- generate source code graph
- create tar archive
* get html for each page
- get files in pages folder
- get page data
| get page data * got files: File
- get base name of File -> name
- read html fragment from File -> html
~ pages = @ name @ html ~
* get page data
| collect backlinks * pages: Page Html
- find elements with tag ba in Html
- collect backlinks for Page
- seen: Page Html
| collect backlinks
* backlink: Page Source URL Anchor Content
- backlink on Page: Source URL Anchor Content
* collect backlinks - move seen to pages
| collect backlinks for URL * found elements: Link
- get content of Link -> content
- get attribute href of Link -> page
- replace [-] with [ ] in URL -> source
~ [] = replace [ ] with [-] in $ content ~-> anchor
~ backlink = @ page @ source URL @ anchor @ content ~
- switch tag of Link to a
- append .html to Link href
- set id to content of Link
* collect backlinks for Page
| render backlinks * pages: Page Html
- create element ul in Html -> list
- render backlinks for Page Html
- seen: Page Html
* render backlinks - move seen to pages
| render backlinks for Page Html | list: List
* backlink on Page: Source URL Anchor Content
~ join! [<li>] Source [: ]
[<a href='/] URL [.html#] Anchor ['>]
Content
[</a>]
[</li>] ~
~ [] = append element @ result to List ~
- found backlink on Page:
* render backlinks for Page Html * list: List
* found backlink on Page:
~ join! [<div class='backlinks'>]
[<h2>backlinks</h2>]
List
[</div>] ~
~ [] = append element @ result to Html ~
* render backlinks for Page Html * list: List
~ no toc: index wiki projects about
| insert table of contents
| no toc; Page * pages: Page Html
- seen: Page Html
| insert table of contents * pages: Page Html
- seen: Page Html
- last level: 2 - html: Html
- create element ul in Html -> toc and position
- find elements with tag h2,h3,h4,h5,h6 in Html
- process headings
- insert toc element
* insert table of contents - move seen to pages
| process headings * found elements: Heading
- heading: Heading
- update level
- move to new level
- process heading
- add heading to list
* process headings
* update level * last level: Last | heading: Heading
- get level of heading Heading -> level
~ [last level] = $ level ~
~ change = ( Last @ level sub ) ~
* move to new level * change: Change
- compare Change and 0
- case less - move down
- case more - repeat Change times - move up
- end
* move down | html: Html * position: Position
- create element ul in Html -> list and position
~ [] = append element @ list to Position ~
* move up * position: Position
- get parent of Position -> parent
~ position = @ parent ~
* process heading * heading: Heading
- set id to content of Heading
- get content of Heading -> content
~ [] = replace [ ] with [-] in $ content ~-> anchor
* add heading to list | position: Position
* anchor: Anchor * content: Content
~ join! [<li>]
[<a href='#] Anchor ['>] Content [</a>]
[</li>] ~
~ [] = append element @ result to Position ~
* insert toc element | toc: List
- get amount of children of List -> count
~ [] = compare @ count and 2 ~
- case more - insert toc
- end
* insert toc * toc: List * html: Html
~ join! [<details class='toc'>]
[<summary>table of contents</summary>]
List
[</details>] ~
~ [] = insert @ result before children of Html ~
* insert source code | pages; source Html
- find element with id
[#generator] in Html -> container
- get file content of generator.nv -> content
~ [] = set content of @ container to @ content ~
| wrap each page * pages: Page Html
- read html from wrapper.html -> wrapper
~ [] = find element with tag main in $ wrapper ~-> main
~ [] = find element with tag title in $ wrapper ~-> title
- replace [-] with [ ] in Page -> heading
- attach heading
- set page title
~ [] = append element Html to @ main ~
~ seen = Page @ wrapper ~
* wrap each page - move seen to pages
* attach heading | heading: index
* attach heading | heading: Heading | main: Main
~ join! [<h1>] Heading [</h1>] ~
~ [] = append element @ result to Main ~
* set page title * heading: Heading * title: Title
~ join! [eevie nebulæ: ] Heading ~
~ [] = set content of Title to @ result ~
* output the website
- ensure site directory exists
- output each page
| output each page * pages: Page Html
~ join! [site/] Page [.html] ~-> path
~ [] = write file @ path with content Html ~
* output each page
* copy the static assets
- copy files static/. to site
- copy files /home/eevie/files/srht/yarnstar/dist/. to site/yarnstar
- copy files /home/eevie/files/srht/miraquad/artifact/web/. to site/miraquad
- copy files /home/eevie/files/srht/pyra0/examples/axowotw/. to site/axowotw
* generate source code graph
^ `lua ../pyra0/pyra.lua graph generator.nv | dot -Tsvg > site/img/source_graph.svg`
* create tar archive
^ `cd site && tar -czvf eevie.dev.tar.gz *`
graph visualization
the following graph shows the relation between rules in the above program . click here to view it larger .backlinks
- about: source page
- projects: created using Pyra0