Goal

Last time I added positional parameters to directives. Since then I've added a type to represent shortcuts. The goal for today is to add metadata to the Site type, which will include site shortcuts.

Plan

  • Add a SiteMetadata type, initially empty, and corresponding field to Site.
  • Change directives so they get a reference to Site so that they have a way to update site metadata.
  • Add shortcuts to site metadata.
  • Change shortcut directive so it adds the shortcut to site metadata.

Notes

  • Added the SiteMetadata type. It's currently empty, as that's enough to play with the Rust type system and to get interfaces right.
  • Tried passing a reference to a mutable Site, but this runs into Rust borrow checking rules. The problem is that Site::process needs to mutate itself but also let a directive do that. That's what the Rust rules are meant to prevent.
  • I can work around that in various ways, such as providing internal mutability for a site. Except that also fails: a site asks a page to mutate itself, and needs to give it a reference to the site. The mutable page reference is to a mutable site, and then there's both a mutable and immutable site reference at the same time.
  • An interesting problem, too, is that there's a riki render-page command that operates on an individual page that is not part of a site. I'll just drop that, first.
  • Ah! At this time I only need to modify site metadata when processing the shortcut directive, and that only needs to do that at the very start. In general, I suspect directives don't need to do that.
  • I'll add a prepare method to the DirectiveImpl trait that only shortcut will implement. Every other directive will get a default no-op implementation provided for them.
  • This also means the site processing will iterate over pages twice. Once to call the prepare method, and other to call the process method.
  • Further, when looking up directives that match invocations, we'll have to check shortcuts, too, if a directive doesn't match.
  • Created a test site that defines and uses a shortcut, for manual testing, while I experiment.
  • Hm, the prepare step also runs into the problem if mixing mutable and immutable references. Of course it does. I need to do a rethink.
  • Hmm.
  • Hmm.
  • Repeat a few times while I do the dishes.
  • I can sidestep the mixed types of references by making a copy (clone) of the site metadata, passing a mutable reference to that to `Page::prepare, and copying back into the site. It's not entirely elegant, but it's good enough.
  • Phew. I almost felt like the borrow checker was going to hold a grudge against me.
  • Next I'll make Page::prepare actually do wikitext parsing and call directive implementations that match invocations, but ignore ones that don't.
  • Another borrow checking situation: if I want to store the wikitext parsing result in the page, I need to make the method get a mutable reference to self. Luckily the sidestep makes this not be a problem. So very exciting!
  • Added a prepare step to directives. Called it at the opportune time.
  • Hmm, the shortcut directive can have both positional and named parameters. Will need to fix the invocation code, but I'll stick with just positionals, for now.
  • After some tired debugging, got things to work.
  • But now I'm too tired to add a test suite for this. The test suite will need to create a test site that defines and uses a shortcut and build the HTML and make sure the shortcut is expanded correctly.
  • I'll merge this but open issues to fix the desc parameter and add a test suite.

Summary

This was more complicated than I wished, but the way the shortcut directive interacts with other directives and site building turned out to be complicated.