Page MenuHomePhabricator

Add image support to Diviner
Open, NormalPublic

Description

For screenshots and such.

Event Timeline

epriestley triaged this task as Normal priority.
epriestley added a project: Diviner.
epriestley added subscribers: epriestley, davidreuss.
chad changed the visibility from "All Users" to "Public (No Login Required)".Jul 3 2015, 4:19 AM

Is this hard to do? Can me accomplish?

I'd guess it's several days of work.

Something like this:

First, let .book files specify a list of resource directories. I think this should probably be a list (not a single directory) so several projects could share a directory of common assets (for example, project logos).

Define a remarkup rule (sort of) for referencing an image resource from those directories, with whatever fancy stuff you want to add (alt text, etc), so users can type <<<~~~screenshot.png~~~>>> or whatever to embed a screenshot.

However, I don't think we should do this at display time. In particular, I think it should be possible to generate a documentation book using local resources and then destroy those local resources (or update them, etc) without the book breaking. For example, you could have a script that automatically generates documentation for v1, v2, v3 of your library. It should be able to do this by using one working directory, rather than needing to keep three copies of stuff on disk forever. See also T4558 (moving Diviner code to Arcanist) and T8555 (letting Diviner publish a self-contained static documentation "site" with just HTML documents). In both cases, the publish phase needs to do an upload/copy step so we end up with a self-contained result.

Instead, you can run the engine with a variant rule that extracts <<<~~~screenshot.png~~~>>> references from markup blocks, similar to how we extract mentions and embedded file PHIDs. As it works, it can collect a list of all files that are referenced by any document. (The first time it encounters a reference to a new file, it can check if that file exists and raise a warning or error if it does not.)

Once the publishing phase completes, go through the list and run a new publishing phase on each resource. Here, we'll create new files in Files and bind them to the book PHID to get permissions right. In the future "static html" target, we might just copy them into the result directory.

Our publishing phase would look something like this:

  • For each path we encountered while publishing, hash the file content. This builds a "new resource map" of <path, hash>.
  • Add some kind of new storage which tracks <bookPHID, path, hash, filePHID>.
  • Load that list. This it the "old resource map".
  • (If --clean was passed, immediately delete the entire old resource map and all associated files.)
  • Delete every entry in the old list that does not appear in the new list (either the path is missing, or the hash is different).
  • Create every entry in the new list that does not appear in the old list (as above), uploading a copy of the local file to get a filePHID.
  • Update the storage to store the new map.

Then, at display time, we run a production variant of the remarkup rule. When it encounters <<<~~~screenshot.png, alt="a duck"~~~>>>, it looks up the appropriate file PHID in the resource map. If it finds it, it treats it like {F123}, using the file PHID from the lookup to identify which file should be shown.

An easier version of this might be T9819, where we bind Phurl pointers to other objects. Then you could bind screenshot.manage to F1234 and embed it with {((screenshots.manage))} or something, conceivably. I don't totally love this. Local preview won't work since the Phurl pointer will only exist in production.

An even easier version of this is just to write {F1234} in the source. This is fragile and local preview won't work, but it should work in production.

I've been locally previewing in Phriction.

Oh I see the problem with that

Embedding files by alias might be useful