Goal
My goal for today is to implement the shortcut directive from ikiwiki in
riki. The plugin allows the page shortcuts in the site define shortcuts that
can be used on page. A shortcut is defined like this:
[[!shortuct wikpedia https://en.wikipedia.org/wiki/%W]]
[[!wikipedia War_of_1812]]
The shortcut directive defines a new directive, which can be invoked as if
it were a normal directive. The first nameless parameter is the name of the
new directive, and the second is the URL pattern.
In the URL pattern, %s is replaced by the nameless argument to the
invocation of the directive added as the shortcut, with URL encoding. %S
(upper case) is the same, but without encoding. %W is encoded in a way
suitable for Wikipedia. The desc parameter in the definition or invocation
sets a description for the link, i.e., link text.
Plan
I don't quite like the way ikiwiki implements shortcuts, so my plan is to
be compatible, but different.
- The
shortcutdirective can be used anywhere on the site, not just in the page calledshortcuts. - It's an error to define a shortcut with the name of a directive, or another shortcut.
- I don't want a dynamic set of directives. I think
ikiwikidoes things that because it was easy to do in Perl. I'll implement something different. rikidoes not currently support nameless parameters. I will add those, but I'll tackle the shortcut directive first. While I do that, I'll require named parameters. Once I add support for nameless parameters, I'll change therikidirective to define shortcuts.
Notes
Add phases for directives
- Some directives depend on other directives having been executed first. The
shortcutdirective needs to be executed before any shortcut is processed. Theinlinedirective requires other pages to have been processed into HTML first. - I can deal with this by adding explicit dependencies on directives, and pages using them, but that seems like a lot of work and prone to bugs.
- Instead, I'll add the concept of "phases" to execution of directives. Each directive execution will be given the "phase number" currently executing. After phases 0 (the first phase), any invocation of a directive must be either a known builtin directive, or a known shortcut for the site.
- Each directive will return a value indicating it has been executed in a phase, and does not need to be executed again.
- The site build process will iterate over invocations of directives, executing them until all directives have been executed.
- Actually, that seems unnecessarily tricky. New plan: each directive can define
three methods,
execute_0,execute_1, andexecute_2. The site build process will loop over directive invocations three times, calling a successive execution method in each loop. Further, all invocations on all pages are executed in each phase. - Adding that was easy and quick.
- Next I'll implement a datatype for holding known shortcuts. I'll add a field to
the type that represents the site to use this. The
shortcutdirective will be able to add to that. - I don't know what the Wikipedia encoding is, so I'll skimp on that. In fact, I'll
only implement
%sas that's the only thing I use. I'll get back to this later. - All directives will need to get a mutable reference to the site.
Ran out of time implementing this today, will continue tomorrow.
Next morning
- I've coded myself into a corner. I want directives to be able to modify the site, but also the pages, and this results in more than one mutable reference to the site.
- I'll put the shortcut set in an arc box, or something.
- But not this early in the morning.
- I'm juggling too many changes at the same time. That might be a signal that I should start over and do one thing at a time.
Summary
Things did not end well. Mistakes were made. I will try again another day.