Elembic 1.0.0: Custom elements and types!

Apologies @janekfleper, you’re totally right that I should add a dedicated page for this on the docs (you can consider the docs to be a bit of a “work in progress” right now). I’ll do this in the next few days.

For a quick summary while that isn’t there, it will store your set rules in a set bibliography(title: metadata(...)) rule which only applies to elements with a special label. Those elements can then use context to read the bibliography.title property to retrieve set rules. This way, we hijack one built-in set rule that can hold unlimited data to create and manage our own set rules, with nearly the same semantics as usual set rules. Something like this:

#let element(..args) = [#context {
  let previous-rules = if (
    [#bibliography.title].func() == metadata
    and bibliography.title.at("label", default: none) == <custom-styles>
  ) {
    bibliography.title.value
  } else {
    ()  // default
  }
 
  // For elements: just need to read, e.g. join all set rules + args
  let fields = previous-rules.sum(default: (:)) + args.named()
  display(fields)
}<lbl-get>]

#let set(element, ..args) = doc => [#context {
  let previous-rules = if (
    [#bibliography.title].func() == metadata
    and bibliography.title.at("label", default: none) == <custom-styles>
  ) {
    bibliography.title.value
  } else {
    ()  // default
  }

  // For set rules: need to write too
  // e.g. set(element, field: 5)
  // Suppose there is only one element so just one array
  let new-rules = previous-rules
  new-rules.push((field: 5))
  show <lbl-get>: set bibliography(title: [#metadata(new-rules)<custom-styles>])

  // Apply that show-set to any "getters" in the rest of the document
  doc
}<lbl-get>]

Everything else builds up from this concept. Notably, we need to set bibliography(title: ...) again for hygiene so we don’t erase your bibliography title, which is why we always use two nested context blocks (one to get the previous value to reset later, one to get the styles). To separate set rules between elements, we use a dictionary with one entry per eid (element id). And so on… there’s lots to say which I will probably write down in the docs soon enough. :slight_smile:

6 Likes