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