source
table of contents
this page contains all of 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
- 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 - create tar archive * get html for each page - get files in folder: pages * files in folder: File - get base name: File - read html fragment from file: File * got base name: Name * got html: Html - pages: Name Html * prepare link: Link - switch tag of: Link to a - append: .html to Link href - set id to content: Link | collect backlinks from: Page * got content: Title * got href attribute: Destination - backlink to Destination: from Page with Title | collect backlinks from: Page * found elements: Link - get content: Link - get attribute: href of Link - prepare link: Link * collect backlinks from: Page | collect backlinks * pages: Page Html - collect backlinks from: Page - find elements: with tag ba in Html - collected backlinks from: Page Html * collect backlinks * collected backlinks from: Page Html - pages: Page Html | render backlinks * pages: Page Html | backlink to Page: from Source with Title - render backlinks for: Page Html - create element: ul in Html | render backlinks * pages: Page Html - rendered backlinks for: Page Html | render backlinks for: Page Html * backlink to Page: from Source with Title | created ul element: Ul - append element: Item to Ul ^ item = " <li>#{source.gsub '-', ' '}: <a href='/#{source}.html##{title.gsub ' ', '-'}'> #{title} </a> </li> " * render backlinks for: Page Html * created ul element: Ul - append element: Result to Html - rendered backlinks for: Page Html ^ result = " <div class='backlinks'> <h2>backlinks</h2> #{ul} </div> " * render backlinks * rendered backlinks for: Page Html - pages: Page Html * move: up * position: Position * got parent: Parent - position: Parent | move: up | position: Position - get parent of: Position * move: down * position: Position * created ul element: List - append element: List to Position - position: List | move: down | insert toc for: Page Html - create element: ul in Html * add heading to list * found elements: Heading | position: Position - append element: Element to Position - set id to content: Heading ^ element = " <li> <a href='##{heading.content.gsub ' ', '-'}'> #{heading.content} </a> </li> " | insert toc for: Page Html * created ul element: List - toc: List - position: List | insert toc for: Page Html | found elements: Heading * last level: Last - last level: Level - add heading to list ^ level = heading.name[1,].to_i difference = level - last.to_i if difference > 0 f 'move', ['down'] elsif difference < 0 (-difference).times do f 'move', ['up'] end end * insert toc for: Page Html * toc: List - inserted toc for: Page Html ^ html.children.before " <details class='toc'> <summary>table of contents</summary> #{list} </details> " unless list.element_children.length < 3 - no toc: index - no toc: wiki - no toc: projects - no toc: about | insert table of contents | no toc; Page * pages: Page Html - inserted toc for: Page Html | insert table of contents * pages: Page Html - insert toc for: Page Html - find elements: with tag h2,h3,h4,h5,h6 in Html - create element: ul in Html - last level: 2 * insert table of contents * inserted toc for: Page Html - pages: Page Html - source file: #nokogiri nokogiri.nv - source file: #generator generator.nv - source file: #filesystem filesystem.nv * source file: ID File * ID element: Container * File content: Content - set content of: Container to Content | insert source code | pages; source Html | source file: ID File - find element: with id ID in Html - get file content: File * insert source code | wrap each page * pages: Page Html - wrapping: Page Html | wrapping: index Html * title element: Title | wrapping: Page Html * title element: Title - set content of: Title to Text ^ text = "eevie nebulæ: #{page.gsub('-', ' ')}" * wrapping: Page Html * got html: Wrapper * main element: Main - wrapped: Page Wrapper - append element: Html to Main - append element: Header to Main ^ header = "<h1>#{page.gsub '-', ' '}</h1>" | wrapping: Page Html | got html: Wrapper - find element: with tag title in Wrapper - find element: with tag main in Wrapper | wrapping: Page Html - read html from file: wrapper.html * wrap each page * wrapped: Page Html - pages: Page Html * output the website - ensure directory exists: site - output each page | output each page * pages: Page Html - write file: Path with content Html ^ path = "site/#{page}.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 * create tar archive ^ `cd site && tar -czvf eevie.dev.tar.gz *`
filesystem.nv
* ensure directory exists: Directory ^ Dir.mkdir directory unless Dir.exist? directory * write file: Path with content Content ^ File.write path, content * copy files: Files to Path ^ FileUtils.cp_r files, path * get file content: File - File content: Content ^ content = File.read file * get files in folder: Folder ^ Dir["#{folder}/*"].each do |file| f 'files in folder', [file] end * get base name: Path - got base name: Name ^ name = File.basename path, '.html'
nokogiri.nv
^ require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'nokogiri', '1.18.3' end * read html fragment from file: File - got html: Html ^ html = Nokogiri::HTML::fragment File.read(file) * read html from file: File - got html: Html ^ html = Nokogiri::HTML5 File.read(file) * find element: with Property Css in Html - Css element: Element ^ element = html.at_css(css) * find elements: with tag Tag in Html ^ html.css(tag).each do |element| f "reversed elements", [element] end * reversed elements: Element - found elements: Element * switch tag of: Element to Tag ^ element.name = tag * append: Value to Element Attribute ^ element[attribute] += value * set id to content: Element ^ element['id'] = element.content.gsub ' ', '-' * get content: Element - got content: Content ^ content = element.content * set content of: Element to Content ^ element.content = content * get attribute: Attribute of Element - got Attribute attribute: Result ^ result = element[attribute] * append element: Element to Parent ^ parent.add_child element * get parent of: Element - got parent: Parent ^ parent = element.parent * create element: Tag in Html - created Tag element: Element ^ element = Nokogiri::XML::Node.new tag, html - include file: filesystem.nv - include file: generator.nv
backlinks
- about: source page
- projects: created using Pyra0