use(require(“atomy”))
require(“set”)
data(Block(@content, @style = nil)):
Table(@rows) Itemization(@elements) NestedFlow(@blocks) Paragraph(@content, @closed? = false) MetaBlock(@action) TraverseBlock(@action) ResolveBlock(@action) List(@elements): OrderedList(@elements)
fn(style-contains-prose?(style)):
style match: .tt: false .verbatim: false .header(_): false .classed(sub, *classes): style-contains-prose?(sub) _: true
def(Block prose-content?):
style-contains-prose?(@style)
data(Element(@content, @style = nil)):
Target(@name) TOC(@content) Reference(@tag, @content = nil) Index(@keys, @description) TraverseElement(@action) ResolveElement(@action) CollectElement(@action) RenderElement(@action)
data(Style(@type = nil, @properties = []))
data(Tag(@part, @name, @target = .self, @display = nil))
data(
Part( -- nil or title content @title = nil -- the part style @style = Style new -- initial content before sub-parts @body = [] -- sub-parts @parts = [] -- parent part @parent = nil -- tags -- tag -> reference @tags = #{} @tag-prefix = nil -- tags that cannot be found by parents @local-tags = #{} -- the primary tag used for this Part -- used for URIs @tag = nil -- content that is inspected during the collect pass, -- but doesn't produce output @to-collect = [] -- dependent assets @assets = [] -- css files to add @css-additions = Set new @css-url-additions = Set new -- js files to add (order matters; thankfully Set preserves insertion order) @js-additions = Set new -- template to use when rendering html @template = nil -- omit children from table of contents @omit-children-from-table-of-contents? = false -- whether or not the part will handle mobile device sizes elegantly @mobile-optimized? = false))
def(Part set-tag(name, target = .self, display = nil)):
@tags[name] = Tag new(self, name, target, display)
def(Part set-local-tag(name, target = nil, display = nil)):
@local-tags[name] = Tag new(self, name, target, display)
def(Part inline-sections?):
style properties include?(.inline-sections)
def(Part inlined?):
inline-sections? || (@parent && @parent inlined?)
def(Part split-sections?):
style properties include?(.split-sections)
def(Part toc?):
style properties include?(.toc)
def(Part page-depth):
if(@parent) then: if(@parent split-sections? || @parent inline-sections?) then: 0 else: @parent page-depth + 1 else: 0
def(Part section-label):
if(@parent) then: parent-label = @parent section-label self-index = (@parent parts index(self) + 1) if(parent-label empty?) then: i"#{self-index}" else: i"#{parent-label}.#{self-index}" else: ""
def(Part inspect): i“#<Part: '#{@tag name}'>”
def(Part template):
@template || (@parent && @parent template)
– search in order: – 1. local hidden tags – 2. local tags – 3. children – 1. local tags – 2. children – 4. parent – 1. local hidden tags – 2. tags – 3. siblings, searching in order – 4. parent … def(Part find-tag(tag, excluding = nil)):
catch(.found): search-tag-excluding(tag, nil) nil
def(Part search-tag-excluding(name, excluding)): do:
when(found = (@local-tags[name] || @tags[name])): throw(.found, found) when(name == @title): throw(.found, @tag) @parts each [p]: unless(p == excluding): p search-tag(name) when(@parent): @parent search-tag-excluding(name, self) nil
– called from find-tag; only search exposed tags and children def(Part search-tag(name)): do:
when(name == @title): throw(.found, @tag) when(found = @tags[name]): throw(.found, found) @parts each [p]: p search-tag(name)
def(Part top):
if(@parent) then: @parent top else: self
def(Part contains-part?(other)):
if(self == other) then: true else: @parts any? &.contains-part?(other)
def(content?(String)): true def(content?(Element)): true def(content?(nil)): true def(content?(x & Array)): x all? &.content? def(content?(_)): false
def(sanitize(x)):
contents-of(x) gsub(r" & ", " and ") gsub(r"\s+", "-") gsub(r"[^[:alnum:]_\-]", "") downcase
def(contents-of(s & String)): s def(contents-of(e & Element)): contents-of(e content) def(contents-of(b & Block)): contents-of(b content) def(contents-of(a & Array)): a collect [x] { contents-of(x) } join def(contents-of(nil)): “”