rust-lang / mdBook

Create book from markdown files. Like Gitbook but implemented in Rust
https://rust-lang.github.io/mdBook/
Mozilla Public License 2.0
17.62k stars 1.61k forks source link

Google analytics support #268

Closed Michael-F-Bryan closed 7 years ago

Michael-F-Bryan commented 7 years ago

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?

azerupi commented 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.

Michael-F-Bryan commented 7 years ago

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:

Michael-F-Bryan commented 7 years ago

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.

azerupi commented 7 years ago

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.