– build paragraphs, set title info, add sub-parts

use(require(“atomy”))

data = require(“anatomy/data”)

fn(close-paragraph(body)):

when(body last is-a?(data Paragraph)):
  body last closed? = true

fn(ensure-paragraph(body)):

unless(body last is-a?(data Paragraph) && !(body last closed?)):
  body << data Paragraph new([])

fn(add-content-to(str & String, body)):

str split("\n\n", 2) match:
  [{ chomp empty? }, rest]:
    close-paragraph(body)
    add-content-to(rest, body)

  [content, rest]:
    ensure-paragraph(body)
    body last content << content
    close-paragraph(body)
    add-content-to(rest, body)

  [content]:
    ensure-paragraph(body)
    body last content << content

  []:
    close-paragraph(body)

fn(add-content-to(nil, body)):

nil

fn(add-content-to(x, body)):

ensure-paragraph(body)
body last content << x

def(pass(m & data MetaBlock, part, body = part body)):

m action[part]
nil

def(pass(a & Array, part, body = part body)):

a each [x]:
  pass(x, part, body)

nil

def(pass(p & data Part, part, body = part body)):

part parts << p
p parent = part
part body freeze
nil

def(pass(i & data Itemization, part, body = part body)):

unless(body frozen?):
  body <<
    i dup tap [x]:
      x elements collect! [n, b]:
        body = []
        pass(b, part, body)
        [n, body]

def(pass(l & data List, part, body = part body)):

unless(body frozen?):
  body <<
    l dup tap [x]:
      x elements collect! [b]:
        body = []
        pass(b, part, body)
        body

def(pass(b & data Block, part, body = part body)):

unless(body frozen?):
  body <<
    if(b prose-content?)
      then:
        b dup tap [x]:
          x content = []
          pass(b content, part, x content)
      else:
        b

def(pass(x, part, body = part body)):

condition:
  body frozen?: nil

  data content?(x):
    add-content-to(x, body)

  otherwise:
    body << x

def(over(x, part)):

pass(x, part, part body)