I have been thinking of rewriting mdBook for a while now and I have a pretty good idea of how I want it to look like from the users point of view, but I am less certain on how I could implement it.
I would like to support multiple renderers that can be enabled / disabled to be able to render to html, pdf, epub, ... so in the configuration file you would be able to put:
book.toml
[outputs]
html = { destination = "book/" }
pdf = { destination = "pdf/mdBook.pdf" }
This should create two renderers that will be run when the book is build.
Ideally I would like to support multiple renderers of the same type with different configurations.
[outputs]
html = { destination = "book/" }
html2 = { renderer = "html", destination = "book2/" }
So in this case 2 renderers of type html
will be created with names html
and html2
to be able to differentiate the two.
Finally I don't want to exclude the possibility of providing a way to add third-party-renderers as plug-ins, but this seems particularly tricky at the moment as I heard plugins should only use the C abi because Rust is not stable for that purpose?
Now the problem is, I have absolutely no clue how to implement this more or less efficiently in my code.. I have experimented with the idea of having a Renderer
trait and having all renderers implement that. I have to register all renderers before I can create instances of them to use. For now the way I have it is that the Renderer
trait has a fn identifier(&self) -> &'static str
method. Registering is just making an instance and when I want to create a new renderer I iterate over the registered renderers and clone the one with matching identifier.
I am interested to hear how others would solve this problem, or if there is a better design for this.