Closed Michael-F-Bryan closed 7 years ago
Seems like a sensible feature request. I would feel more comfortable to add this if we had some sort of "plugin" system. But until then I wouldn't mind adding it as a special case. If someone wants to tackle this, feel free to ask me questions.
What would be necessary to get the initial version of this going? At the moment I've copied the index.hbs
template from the default theme and made my own addition (link) but that's not exactly ideal...
From what I can see you'd need to do the following:
BookConfig
struct in bookconfig.rs and update the parse_from_btreemap()
method accordinglymake_data()
method in hbs_renderer.rs to check for google analytics? I've never used the rust handlebars crate before, so I'm not exactly sure how you'd go about getting the google analytics snippet into the rendered page.As an aside, in an ideal world, how would you imagine a plugin system to work?
In a dynamic language like Ruby or JavaScript it's easy enough to import any random library at runtime then look for a set of pre-determined hook functions. But unless you want to go down the route of DLLs and dlopen
, and getting plugins to export some common symbol that's not going to be an easy thing to do from a compiled language.
One way of doing plugins I thought of is that a "plugin" is any executable which takes a JSON representation of the book in stdin, does whatever manipulations it wants to do, then prints it to stdout so it can either be passed to the next plugin in the chain or back to mdbook
for rendering. That way adding a plugin is simply a case of making sure the executable is on your PATH
and adding its name to your book.toml
to tell mdbook
what to call and in which order.
As an aside, in an ideal world, how would you imagine a plugin system to work?
I was thinking that we could begin to have plugins in the core that could be switched on and of through configuration with a common interface so that they are not special cased everywhere in the code. And maybe later we could add a C API to have real plugins. But I have never done this before, so I am not sure how difficult this would be.
One way of doing plugins I thought of is that a "plugin" is any executable which takes a JSON representation of the book in stdin, does whatever manipulations it wants to do, then prints it to stdout so it can either be passed to the next plugin in the chain or back to mdbook for rendering
That's a very intriguing idea! It certainly makes plugins a lot easier. However, I am not sure this will be enough. Let's take the example of math support:
The plugin would need to parse the source before the markdown parser to avoid having the markdown parser interpret all the operators like *
. This doesn't necessarily have to happen in the plugin though, mdBook could do a pre-processing pass where it recognizes a certain pattern that could be used to delimit all non-markdown input. It would extract that input, feed the rest to the markdown parser to get an AST and then insert the extracted snippets back.
After that the plugin needs to work on the AST, to recognize the math snippets and give them some meaning. Finally the plugin should work during the rendering, where it tells the different renderers it supports how to render the thing. The plugin also needs to be able to create arbitrary ressource files, like the CSS and JS files for HTML.
Is it possible to add google analytics to the book? For example, I know most static site generators will allow you to add a google analytics tracking ID to the config and it'll automatically add the google analytics script to each page.
Is it possible to add a key to the
book.toml
config file for this?