RinohType, a document processor inspired by LaTeX
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Machiels, Brecht
Brecht Machiels - RinohType, a document processor inspired by LaTeX RinohType is a document processor inspired by [LaTeX] and written in Python. It renders [reStructuredText] and [Sphinx] documents to PDF based on a document template and a style sheet. RinohType already implements many of the features that make LaTeX so great. Not stopping there, RinohType also tries to fix LaTeX's weaknesses; it should not only be easy to use, but easy to _customize_ and _extend_ as well. To minimize frustration when things go wrong, care is taken to provide descriptive warning and error messages. The powerful layout engine makes it easy to define custom page layouts. And the CSS- inspired stylesheets simplify the styling of document elements. At a lower level, Python makes the writing of extensions much more accessible when compared to TeX's rather arcane macro language. In the talk, I would like to introduce RinohType to the Python community. No special prerequisite knowledge is required. I will start off by discussing my motivation for starting RinohType development, its design goals and the currently available features. This will be followed by an example of how you can use RinohType to render a reStructuredText document to a neat PDF document, highlighting some of the features along the way. Next, we'll explore some of RinohType's internals such as the page layout engine and the style sheet system. We will explore how these can be used in a Python application to create a document from scratch. A first RinohType release was recently created. While this preview release is of alpha quality, it should be able to render most reStructuredText documents. It also includes a preliminary Sphinx builder. Please find more details in the package's description at [PyPI].
 My name is Bercht Machils. A little bit more about me. I'm from Belgium. I'm about 30 years old. And I've been enjoying computers since a very long time, as you can see in the picture. It's with a Commodore 64, by the way. I've obtained a PhD degree in microelectronics. However, I haven't really been practicing electronics anymore since I graduated. I've been programming in C and C++ in Python, and some other languages also for professionally and for fun. Although in the case of C++, perhaps the fun part doesn't really apply. So what is Rhino type? It's a document typesetter in the style of Laatig. Who here does not know Laatig or has not used it before? Okay, a couple of people. But it's not necessary to understand this talk, so you should be fine. Basically, it takes an input document in a structured text format. So for now, this is limited to restructured text and Sphinx documents. And the difference with Laatig is that the style and content are more strictly separated. I'll come back to that in a couple of slides. So taking this restructured input file, you can style the document elements using a style sheet, which is similar to CSS. And you can choose to typeset the document in a number of formats, such as a book or an article based on the template you choose or provide yourself. And the output is a PDF format. It's also possible to add other backends so that other formats are supported in the future. I'm thinking of SVG or scalable vector graphics that might be interesting to display in a browser. Then onto my motivation for starting RhinoType. Like you have used Laatig before, and generally it has been a pretty good experience. You provide it with content and it takes care of formatting it in a rather nice way. However, there is also quite a number of problems with Laatig. This is due to its age mostly, I think, because it doesn't rely on modern technologies. Typical complaints about Laatig are the cryptic warning and error messages, as those you can see over there. You can find control sequences and followed by the name of some weird TecMaco. You have no hope of finding out what the problem is, so this takes a lot of time to fix these errors. The TecMaco language is not very accessible. It's very different from modern programming languages. So if you want to extend or customize a style in Laatig, you need to be quite the expert in Tec. Lastly, it's also very large and complex system. That's not very transparent. If you want to install Laatig, it's for the TecLive distribution, which is a default distribution. Nowadays, it's a 2GB download and installed. It's unpecs to quite a bit more. I think there's also some smaller distributions, but then you often run into problems with missing packages. So that's not really a good solution. Maybe I should ask if any other people here kind of hate Laatig, even though they have to use it now and then. Okay, that's good. It gives me some confidence here. So we had that. My goals in the development of RhinoType is for it to be as capable as Laatig or eventually even more capable. But it's very important for it to be very easy to use. These problems I mentioned in the last slide, I want to try and fix these. So it should be easy to style documents. And I hope to fix this by presenting the CSS-like stylesheets. I think they're a good match for styling documents in general. And document templates should also be easy to modify or configure at least, or it should also be easy to write new ones from scratch. RhinoType is written in pure Python. Currently it's written in Python 3. I might do a backport to Python 2, but I'm not sure about that yet. And I try to minimize dependencies. So currently it depends only on docutils for parsing restructured text. But if you're using Sphinx, you have that dependency installed anyway. And it also depends on a pure Python PNG library if you want to include PNG images in your document. The current status, I've already shown this slide during the lightning talk. So there was a first release a couple of weeks ago. It's a kind of early beta, you could call it. So it contains most of the features that are also offered by Laatig. One major exception there are equations. But these are definitely on the to-do list. And also important is that there's very few documentation on it. However, there's a readme, so if you want to try playing with RhinoType, I recommend you start with the readme and that should get you started, along with this presentation, of course. Furthermore, I need to do lots of testing, like write many unit tests and fix the bugs that pop up. I will release a new version soon, that will probably be early next week. It features nearly complete Sphinx support. For example, it renders the Sphinx's own documentation, which is a large document, and uses most of Sphinx's features. And it also comes with a prettier style sheet. So on the first couple of slides, I will present how you can use RhinoType as a kind of end user level. And afterwards, we'll dive a little bit more into the details, looking at the style sheet mechanism, for example. So if you look at RhinoType in the center as an engine, we feed it an input file. That is a structured text document. So for now, that's restructured text or Sphinx documentation project. Other backends could be added. It just takes a lot of work, I suppose, in the case of Markdown that work is limited. But for Dogbook, I think that's a very broad specification, but I believe it's fairly...it's used often by publishers, so I think that's a good frontend to add. The structured text, it can refer to images. These can be in PDF format, or in PNG or JPEG format. So these bitmaps are more or less included as is in the PDF, so they don't require any long processing time. So these get fed to RhinoType, and then RhinoType looks for some style sheets and document templates to determine the style of the documents. These are basically both Python source files. I might provide a text-based layer for style sheets in the future to ensure security, but that is not yet present. And of course, we need some fonts to render text. And all base...all currently widely supported font technologies are supported, including for OpenType and TrueType. And Outcomes in nice PDF, if everything goes well. So who is not familiar with restructured text? Okay, so that makes things easier also. So here's an example on the right. So it's basically plain ASCII text, and it's structured, as the name says. So you can see two sections, and then there's an enumerated list with a bullet list inside of it. A very important feature of restructured text is that it is, in fact, extensible, so you can add new roles and directives. And you can use this contrast to LaTeG, where the input file is a source...text source file. You can basically program anything. In RhinoType, you're kind of...I shouldn't say stuck, but with this restructured text format, so you cannot program in it, but you can still extend it. And on the RhinoType site, you can implement a corresponding part, so in some sense, it's still programmable. And the content and style is more separated, so you're kind of forced to make this separation, and I believe this will lead to a better...and a cleaner document. And even if that sounds like more work than in LaTeG, I think it will be much easier to do this in RhinoType than trying to figure out how to do something in LaTeG using the tech language. So like I said, there's also a Sphinx front-end provided. Anyone who's not familiar with Sphinx? Okay, looking good. So you all know this. It's used for larger document projects, like, example, API documentation, but you can also use it for books and manuals that are not related to source code. And you can render to HTML, to LaTeG, and then to PDF or EPUB. And now with RhinoType, you can render directly to PDF using nothing but Python and the Python packages. So I'll show a little demonstration. First, I'll hand a small restructure text file using the command line tool that is included with RhinoType. And I'll also look at how you can compile a Sphinx documentation project using RhinoType. So this is just a small restructure text file. There are some images in the images directory. Open the restructure text file. So this should look familiar to most of you. Here I have defined a custom rule for typesetting acronyms. This will be matched in the RhinoType style sheet. So these will be displayed as small capitals. Then we have a paragraph with some inline styling, an inline image also. And here we have a... Maybe I should make it a little smaller. So with a paragraph with a custom class assigned using the class directive, we will also use this to apply special formatting in RhinoType. This is, of course, something you normally would not do in a normal document. This is just to display the styling features of RhinoType. We have a right-lined paragraph, some more of these here. And then we have some typical body elements like lists, field lists, option lists, a code block, an indented paragraph, a table, and some images. We'll see how that gets rendered. So the RhinoTool is available. At this moment, it only accepts a single argument, but I will add some more so you can choose the style sheet to apply and perhaps also choose page orientation and maybe configure page margins if you want. So you can ignore this line for now. I will not explain this, but this line shows the error reporting or warnings in RhinoType, so it shows the input file that is the cause of the warning and the line number. So you do the exact location of where the cause of the problem is. In this case, there's a very long line in a code block because these code blocks are not line wrapped. It flows into the margin of the page. And it also displays that this occurs on page three of the rendered document. I believe this is a nice improvement over Laatich. The second line, this indicates that the first rendering pass has finished because page references or cross references have not yet converged because in the first pass, you don't know how many pages the document will consist of, so we need to do another page if this reference is included somewhere. So after the second pass, the output is written. Have a look at the result. So we have a title with a subtitle. The author is there. Then we have the first section, which is automatically numbered by RhinoType. You can choose to number this in different ways using Roman numerals or just ABCD. Then we have some inline styles such as italic for emphasized text, bold for strongly emphasized text. We have some monospace text for literals. We can have subscripts, superscripts, inline images as here. And hyphenation is also supported automatically. You can even on a subparagraph basis, so parts of paragraphs, you can set a language and the maximum amount of, or the minimum amount of characters to keep together when hyphenating words. And it uses open office or LibreOffice hyphenation dictionaries to perform this hyphenation. Cross references are transformed into links in the PDF document. It's interesting to note that restructured text supports unicode, so you can write in many languages. And since RhinoType is written in Python 3, it's internally all unicodes. So I have to say I haven't tested this thoroughly yet, but yesterday I tried with this Vietnamese text and it seems to map well to my example that I've seen. Here we have a left aligned paragraph, so it's ragged on the right side. We have a right lined paragraph. These are center aligned. They're support for kerning and ligatures, which can be turned on and off as in here. I'm sorry about that if you don't know what it means, but it basically makes text more readable. So in the case of AV here, by default, there's a rather large space in between, and kerning information in the font makes this placed closer together, so it's easier to read. Like in a title, it could occur that these are like two words, while in fact it's one word, so this helps readability. Similarly, we have ligatures. The VIVI, for example, is contracted into a single glyph that is supposedly easier to read. Oh, yeah, and the top paragraph, we also have a footnote reference, and the footnote can be seen on the bottom of the page. Then we have a local table of contents with page references on the right, and they are also hyperlinks. And we have the typical body elements, like the lists, field lists, option lists. Some block-level elements. So here is the paragraph that generated the warning. So the text is flowing into the margin. We have an indented paragraph, and then tables. We can have row spanning and column spanning cells as in HTML, and the width of the table and the columns, individual columns are sized automatically based on their contents. This is something that is missing from the Sphinx-Latech builder, I believe. I suppose that there's a latech package that fixes this, but I'm not sure if that's possible to use with Sphinx. Then we have a section with some images. So this image is simply kind of inline image, and after this paragraph there is a floating image or figure inserted, and this gets floated to the top of the page, as you can see here, along with a caption. And then finally we have some admonitions that are styled differently based on their type. So here we have the Sphinx-Latech. Now I'll go to the Sphinx demos. So this is basically the Sphinx Git repository checked out. If we move into the doc directory, we're already there. I've made some changes to com.py to configure RhinoType. So first we need to include the Sphinx builder that's included with RhinoType in the extension list, and we need to specify this variable to instruct RhinoType what to render exactly. So this is very similar to configuration variables for other backends of Sphinx, so we will render contents.rst, which contains basically all documentation. We will output to Sphinx.pdf by specifying Sphinx here, by specifying document title and author. And the following part configures custom headers and footers for the document. So the headers and footers, they each consist out of three tab stops, so one on the left, one in the center, one on the right. So if we add a tab element, this moves the cursor to the middle tab stop, so this text will be in the header, will be centered. And for the footer, on the left we insert the page number, forward two tabs, so we end up on the right of the footer, and that's where we insert the chapter description, which is simply the section number followed by the section title of the level one or top level section. We can also configure the style sheets, page size, orientation, and configure margins of the page for this Sphinx project. We can also configure the number of columns to use to typeset document. So we'll not render this real time, because it takes a little bit too long, at least for this presentation. So this is using the book template, so it comes with the title page, followed by a blank page, and then the table of contents. This looks similar like the one in the previous document, and this goes down to two levels in the section three. It's a longer document. You can see at the bottom the page numbers are in Roman, small case numerals. And then for the body part of the text, we can see the custom header and footer we have defined. So page number on the left and section description on the right. And the style more or less was copied from the Laatig style file used by Sphinx. So continuing with the presentation. I quickly mentioned Sideprocpy. This is a sister project to Rhino type. It's basically a CSL processor, and CSL is a standardized XML format to describe the formatting of citations and bibliographies. It comes with, or a lot of styles are available, so you probably don't need to write your own style if you are writing a document with citations. It parses a Beeptech databases, so you can use these, and it can output the formatted citations and bibliography as HTML restructured text or using the internal Rhino type representation. This is not yet usable from within restructured text or Sphinx, but this should be a very small step. So this is an example of how citations and references lists could be formatted by Sideprocpy. So this extends this schema, so we can add references and Sideprocpy handles the formatting of those. Now diving a little bit deeper into the internals, we'll look at the style sheets for this. To understand this, you need to know how document elements are represented. These are basically Python instances of flowable classes. So we have flowables such as a paragraph or an image, and then we have inline images which make up a paragraph. After that, I will discuss the style sheets and how flowables are linked to style definition. So as I said, flowable can be, for example, a paragraph. A paragraph adapts to the available width that is provided by the document template, and they are flowed onto the page. That's a term that is often used in this context. Images, for example, they don't adapt to the available width, or generally not at least, they can horizontally align themselves within the available space. And flowables form a tree that's together form a documentary, such as is the case in HTML also, so that should be intuitive. Here we have a title paragraph, so it has a special title style. So this paragraph functions as the title of the document. Then we have two top-level sections, and the first top-level section has two subsections with some additional flowables inside of them. Inline elements, for example, this short paragraph with nested styling is also represented as a tree. I will skip over that quickly. So style sheets, like I said, they are very similar to CSS. You first select the document elements you want to style, and you select them based on their place in the documentary, their style attribute, which is similar to the ID and class attributes in CSS. Or you can select based on any other attribute or any combination of these three. Style sheets are plain Python source files. I also mentioned that before. We'll have a look at an example now. So suppose we want to select the paragraphs that are part of a list item here, but we don't want to select this one. We make use of a context selection, so we only select list items that are direct child... Sorry, we only select paragraphs that are a direct child of a list item. Or we can also use this selector, the Python ellipsis keyword. It represents any number of levels of flowables, and in this case, it simply matches the list item. We can match based on the style attribute as for the title paragraph using the like class method. And we can match on arbitrary attributes. For example, level two section headings, we can select like this. We limit the selection of the sections by passing the level argument to the like method. I'll skip the next one because I'm running out of time. There's some limitations to CSS, I think. So I added another level of indirection. I split up style sheets between a style matcher and a style sheet. A style matcher basically collects all the selectors and maps these to style names. And these style names can then in a style sheet be mapped to a style definition. That means that single style matcher, because these are often the same, all these selectors, the same for multiple documents, can be reused by multiple style sheets. I think maybe this might make less sense for HTML, but I think for a document processor, this is a good fit. Rhino type also supports variables in the style sheets to avoid duplication. This is a problem that is often not, or this is a missing feature from CSS that is often complained about. And we can also inherit from one style to again avoid duplication. So let's look at the style matcher and style sheet. We create a new style matcher. So for example, we select a style text with the emphasis style and we assign it to the emphasis style name. The same for nested line blocks, which should be more or less self-explanatory. And we use this matcher or refer to it in a style sheet we create. And over there we map style elements to each of the different style names. So emphasize text is represented using a tele-sized text and nested line blocks are indented on the left. Variables can be used if we reuse a single value for multiple styles. For example, fonts is a good example of that. So we define a variable here, IEEE family, which collects a number of fonts. And we can use this as follows in a style definition. Note that you can also refer to attributes of this or of the value that the variable references. You have inheritance. Suppose we have defined a style for headings, for numbered headings. We often also have a unnumbered heading style for table of contents title, for example. In this case, we want to base this on the default heading style. And we can simply override one or more of the style attributes as is the case here. So all other attributes are simply the same as for the standard heading style. You can also extend this style sheet. So for example, you use a standard style sheet that is shipped with Rhino type. And you want to make some changes, you can simply inherit. Additionally, you can add new matchers. So for example, for the acronym role that was visible in the demonstration, you can define a new matcher. Then you can create an inherited or a style sheet that is matched based on the previous style sheet and also refer to the new matcher. And now we can define a style for the acronym role, restructure text role. So we set small capitals to true in this case. We can also override styles that were present in the base style sheet like this. So we change the font weight to bold additionally. And we can change variables that will also have effects on all styles that use this variable in the base style sheet. So here we replace all fonts with some others. Then a small note about performance. So this things documentation. I forgot to update this, but with a new style sheet, it's about 230 pages. And this takes about 70 seconds to render from scratch. So this takes two passes if the cache file is in place. So the document has been rendered already. It takes only about 40 seconds. I think this is not too bad for a Python document processor. However, I still looked into speeding it up a little bit. That would be nice. So I tried Scython. Unfortunately, I didn't get to make a big speed up with that. I think this is due to the fact that I'm basically doing lots of things with lists and dictionaries instead of tight loops, number crunching. I also tried PyPy. Fortunately, it was twice as slow as Cpython. The PyPy developers are not sure what the cause of this is, but I've talked to Fijal yesterday about it, and we'll have a look at it during the sprint. I should mention the license. So my intention is to keep Rhinotype free for non-commercial use. So open source projects can use it to generate documentation. I'm thinking about offering a separate license for commercial use, but I have to determine the details about this. It's a very complicated matter, I understand. So for more information, please note the spelling of Rhinotype. It could help you to say that it spells Python backwards. And please look at these URLs for more information and downloads. Maybe you still have some time for some questions. Thank you. So your lightning talk mentioned, if I'm not mistaken, that there is no support for formulas, right? Mathematical equations. Yeah, it's not supported at the moment. So there is a project in JavaScript world called Katex. Which one is it? Katex. K-A-Tech. Oh, no, I don't know that. I know about JSMOT or something. It's another one. So Katex, they are explicitly dedicated to mathematical equations and everything related. But it's in JavaScript, so it's just a hint. Thanks. Okay, thanks. How, well, I guess you did try to compare with regular latex for the same document, the same content, I mean, because it seemed the compilation was horribly slow compared to proper latex. It is quite slow compared to latex. I think, yes. So that's why I tried to look at PyPy for speeding up. However, for small documents, this is not a problem. But I'll definitely look into speeding the rendering up a little more. And did you compare with Sphinx? Same speed as Sphinx? Sphinx latex render? Yeah, did you compare the compiling with Sphinx? Anyone? I don't know. The fastest. Make PDF was Sphinx and PDF with the Rhino type? No, I have not compared that. I would like to know how far along are you with the idea of rendering this to SVG? I haven't started yet. It's just an idea. Any more questions? Which actually text processing library are you using internally? Because to do all the paragraph formatting and all the page styling or type setting effectively, what library are you using? Did you reimplement everything that is in tech? Yeah. So everything is pure Python. So you cannot rely on external libraries except for docutals or the PNG library. Any more questions? Hi. Do you support or will you support absolute placement constraints? So if a box needs to be placed at an exact position on the page, or maybe if you have a table where the cells may not be broken, if it's multi-page? Yeah. So there's nothing in place for absolute placement as of yet. This could be added, but I'm not sure how that would interact with the rest of the elements. As for tables, you can set a constraint of how many rows to keep together at a minimum. So if you can just render like two rows on a page, it will skip to the next one if you have specified like four. Any more questions? I have a question about testing. So since it's all related to visuals, how do you automate testing and stuff? Thanks. I've done very little testing up to now because I've been constantly refactoring also. That's a good excuse. But yeah, I'm also a bit worried about how to do this testing. I guess I will have to mock the backend and maybe it will just be limited to regression testing that I know which is the good location just to make sure it doesn't change. Thanks for talking. I tried the line type with Japanese language, tekis. And the line type accept the... cause the exception. How do you plan to support as a merge-byte language? Yeah, Unicode should be a good part of that, but I'm sure there's more to do there. Of course, you need to also make sure that you have fonts that contain the necessary glyphs. But this is something I could probably use some help from since I do not read or write Japanese or many other languages. Any more questions? Hi. How do you handle images and is there some sort of scaling mechanism in the line type? Yeah, you can specify to scale it to the total available width or specify an absolute width just in points or centimeters. Okay, any more questions? Thank you very much for your talk and it has been really interesting.
 My name is Bercht Machils.  A little bit more about me. I'm from Belgium. I'm about 30 years old.  And I've been enjoying computers since a very long time, as you can see in the picture.  It's with a Commodore 64, by the way.  I've obtained a PhD degree in microelectronics.  However, I haven't really been practicing electronics anymore since I graduated.  I've been programming in C and C++ in Python, and some other languages also for professionally and for fun.  Although in the case of C++, perhaps the fun part doesn't really apply.  So what is Rhino type? It's a document typesetter in the style of Laatig.  Who here does not know Laatig or has not used it before?  Okay, a couple of people.  But it's not necessary to understand this talk, so you should be fine.  Basically, it takes an input document in a structured text format.  So for now, this is limited to restructured text and Sphinx documents.  And the difference with Laatig is that the style and content are more strictly separated.  I'll come back to that in a couple of slides.  So taking this restructured input file, you can style the document elements using a style sheet, which is similar to CSS.  And you can choose to typeset the document in a number of formats, such as a book or an article based on the template you choose or provide yourself.  And the output is a PDF format.  It's also possible to add other backends so that other formats are supported in the future.  I'm thinking of SVG or scalable vector graphics that might be interesting to display in a browser.  Then onto my motivation for starting RhinoType.  Like you have used Laatig before, and generally it has been a pretty good experience.  You provide it with content and it takes care of formatting it in a rather nice way.  However, there is also quite a number of problems with Laatig.  This is due to its age mostly, I think, because it doesn't rely on modern technologies.  Typical complaints about Laatig are the cryptic warning and error messages, as those you can see over there.  You can find control sequences and followed by the name of some weird TecMaco.  You have no hope of finding out what the problem is, so this takes a lot of time to fix these errors.  The TecMaco language is not very accessible.  It's very different from modern programming languages.  So if you want to extend or customize a style in Laatig, you need to be quite the expert in Tec.  Lastly, it's also very large and complex system.  That's not very transparent.  If you want to install Laatig, it's for the TecLive distribution, which is a default distribution.  Nowadays, it's a 2GB download and installed.  It's unpecs to quite a bit more.  I think there's also some smaller distributions, but then you often run into problems with missing packages.  So that's not really a good solution.  Maybe I should ask if any other people here kind of hate Laatig, even though they have to use it now and then.  Okay, that's good.  It gives me some confidence here.  So we had that.  My goals in the development of RhinoType is for it to be as capable as Laatig or eventually even more capable.  But it's very important for it to be very easy to use.  These problems I mentioned in the last slide, I want to try and fix these.  So it should be easy to style documents.  And I hope to fix this by presenting the CSS-like stylesheets.  I think they're a good match for styling documents in general.  And document templates should also be easy to modify or configure at least,  or it should also be easy to write new ones from scratch.  RhinoType is written in pure Python. Currently it's written in Python 3.  I might do a backport to Python 2, but I'm not sure about that yet.  And I try to minimize dependencies.  So currently it depends only on docutils for parsing restructured text.  But if you're using Sphinx, you have that dependency installed anyway.  And it also depends on a pure Python PNG library if you want to include PNG images in your document.  The current status, I've already shown this slide during the lightning talk.  So there was a first release a couple of weeks ago.  It's a kind of early beta, you could call it.  So it contains most of the features that are also offered by Laatig.  One major exception there are equations.  But these are definitely on the to-do list.  And also important is that there's very few documentation on it.  However, there's a readme, so if you want to try playing with RhinoType,  I recommend you start with the readme and that should get you started,  along with this presentation, of course.  Furthermore, I need to do lots of testing, like write many unit tests and fix the bugs that pop up.  I will release a new version soon, that will probably be early next week.  It features nearly complete Sphinx support.  For example, it renders the Sphinx's own documentation, which is a large document,  and uses most of Sphinx's features.  And it also comes with a prettier style sheet.  So on the first couple of slides, I will present how you can use RhinoType as a kind of end user level.  And afterwards, we'll dive a little bit more into the details,  looking at the style sheet mechanism, for example.  So if you look at RhinoType in the center as an engine, we feed it an input file.  That is a structured text document.  So for now, that's restructured text or Sphinx documentation project.  Other backends could be added.  It just takes a lot of work, I suppose, in the case of Markdown that work is limited.  But for Dogbook, I think that's a very broad specification,  but I believe it's fairly...it's used often by publishers,  so I think that's a good frontend to add.  The structured text, it can refer to images.  These can be in PDF format, or in PNG or JPEG format.  So these bitmaps are more or less included as is in the PDF,  so they don't require any long processing time.  So these get fed to RhinoType,  and then RhinoType looks for some style sheets and document templates  to determine the style of the documents.  These are basically both Python source files.  I might provide a text-based layer for style sheets in the future to ensure security,  but that is not yet present.  And of course, we need some fonts to render text.  And all base...all currently widely supported font technologies are supported,  including for OpenType and TrueType.  And Outcomes in nice PDF, if everything goes well.  So who is not familiar with restructured text?  Okay, so that makes things easier also.  So here's an example on the right.  So it's basically plain ASCII text, and it's structured, as the name says.  So you can see two sections,  and then there's an enumerated list with a bullet list inside of it.  A very important feature of restructured text is that it is, in fact, extensible,  so you can add new roles and directives.  And you can use this contrast to LaTeG, where the input file is a source...text source file.  You can basically program anything.  In RhinoType, you're kind of...I shouldn't say stuck,  but with this restructured text format, so you cannot program in it,  but you can still extend it.  And on the RhinoType site, you can implement a corresponding part,  so in some sense, it's still programmable.  And the content and style is more separated,  so you're kind of forced to make this separation,  and I believe this will lead to a better...and a cleaner document.  And even if that sounds like more work than in LaTeG,  I think it will be much easier to do this in RhinoType  than trying to figure out how to do something in LaTeG using the tech language.  So like I said, there's also a Sphinx front-end provided.  Anyone who's not familiar with Sphinx?  Okay, looking good.  So you all know this.  It's used for larger document projects,  like, example, API documentation,  but you can also use it for books and manuals that are not related to source code.  And you can render to HTML, to LaTeG, and then to PDF or EPUB.  And now with RhinoType, you can render directly to PDF  using nothing but Python and the Python packages.  So I'll show a little demonstration.  First, I'll hand a small restructure text file  using the command line tool that is included with RhinoType.  And I'll also look at how you can compile a Sphinx documentation project  using RhinoType.  So this is just a small restructure text file.  There are some images in the images directory.  Open the restructure text file.  So this should look familiar to most of you.  Here I have defined a custom rule for typesetting acronyms.  This will be matched in the RhinoType style sheet.  So these will be displayed as small capitals.  Then we have a paragraph with some inline styling,  an inline image also.  And here we have a...  Maybe I should make it a little smaller.  So with a paragraph with a custom class assigned  using the class directive,  we will also use this to apply special formatting in RhinoType.  This is, of course, something you normally would not do  in a normal document.  This is just to display the styling features of RhinoType.  We have a right-lined paragraph, some more of these here.  And then we have some typical body elements like lists,  field lists, option lists,  a code block, an indented paragraph, a table,  and some images.  We'll see how that gets rendered.  So the RhinoTool is available.  At this moment, it only accepts a single argument,  but I will add some more so you can choose the style sheet to apply  and perhaps also choose page orientation  and maybe configure page margins if you want.  So you can ignore this line for now.  I will not explain this,  but this line shows the error reporting or warnings in RhinoType,  so it shows the input file that is the cause of the warning  and the line number.  So you do the exact location of where the cause of the problem is.  In this case, there's a very long line in a code block  because these code blocks are not line wrapped.  It flows into the margin of the page.  And it also displays that this occurs on page three  of the rendered document.  I believe this is a nice improvement over Laatich.  The second line, this indicates that the first rendering pass  has finished because page references or cross references  have not yet converged because in the first pass,  you don't know how many pages the document will consist of,  so we need to do another page if this reference is included somewhere.  So after the second pass, the output is written.  Have a look at the result.  So we have a title with a subtitle.  The author is there.  Then we have the first section,  which is automatically numbered by RhinoType.  You can choose to number this in different ways  using Roman numerals or just ABCD.  Then we have some inline styles such as italic for emphasized text,  bold for strongly emphasized text.  We have some monospace text for literals.  We can have subscripts, superscripts, inline images as here.  And hyphenation is also supported automatically.  You can even on a subparagraph basis,  so parts of paragraphs, you can set a language  and the maximum amount of, or the minimum amount of characters  to keep together when hyphenating words.  And it uses open office or LibreOffice hyphenation dictionaries  to perform this hyphenation.  Cross references are transformed into links in the PDF document.  It's interesting to note that restructured text supports unicode,  so you can write in many languages.  And since RhinoType is written in Python 3, it's internally all unicodes.  So I have to say I haven't tested this thoroughly yet,  but yesterday I tried with this Vietnamese text  and it seems to map well to my example that I've seen.  Here we have a left aligned paragraph,  so it's ragged on the right side.  We have a right lined paragraph.  These are center aligned.  They're support for kerning and ligatures,  which can be turned on and off as in here.  I'm sorry about that if you don't know what it means,  but it basically makes text more readable.  So in the case of AV here, by default,  there's a rather large space in between,  and kerning information in the font makes this placed closer together,  so it's easier to read.  Like in a title, it could occur that these are like two words,  while in fact it's one word, so this helps readability.  Similarly, we have ligatures.  The VIVI, for example, is contracted into a single glyph  that is supposedly easier to read.  Oh, yeah, and the top paragraph,  we also have a footnote reference,  and the footnote can be seen on the bottom of the page.  Then we have a local table of contents  with page references on the right,  and they are also hyperlinks.  And we have the typical body elements,  like the lists, field lists, option lists.  Some block-level elements.  So here is the paragraph that generated the warning.  So the text is flowing into the margin.  We have an indented paragraph, and then tables.  We can have row spanning and column spanning cells as in HTML,  and the width of the table and the columns,  individual columns are sized automatically based on their contents.  This is something that is missing from the Sphinx-Latech builder, I believe.  I suppose that there's a latech package that fixes this,  but I'm not sure if that's possible to use with Sphinx.  Then we have a section with some images.  So this image is simply kind of inline image,  and after this paragraph there is a floating image or figure inserted,  and this gets floated to the top of the page, as you can see here,  along with a caption.  And then finally we have some admonitions  that are styled differently based on their type.  So here we have the Sphinx-Latech.  Now I'll go to the Sphinx demos.  So this is basically the Sphinx Git repository checked out.  If we move into the doc directory, we're already there.  I've made some changes to com.py to configure RhinoType.  So first we need to include the Sphinx builder that's included with RhinoType  in the extension list, and we need to specify this variable  to instruct RhinoType what to render exactly.  So this is very similar to configuration variables for other backends of Sphinx,  so we will render contents.rst, which contains basically all documentation.  We will output to Sphinx.pdf by specifying Sphinx here,  by specifying document title and author.  And the following part configures custom headers and footers for the document.  So the headers and footers, they each consist out of three tab stops,  so one on the left, one in the center, one on the right.  So if we add a tab element, this moves the cursor to the middle tab stop,  so this text will be in the header, will be centered.  And for the footer, on the left we insert the page number, forward two tabs,  so we end up on the right of the footer,  and that's where we insert the chapter description,  which is simply the section number followed by the section title of the level one  or top level section.  We can also configure the style sheets, page size, orientation,  and configure margins of the page for this Sphinx project.  We can also configure the number of columns to use to typeset document.  So we'll not render this real time, because it takes a little bit too long,  at least for this presentation.  So this is using the book template, so it comes with the title page,  followed by a blank page, and then the table of contents.  This looks similar like the one in the previous document,  and this goes down to two levels in the section three.  It's a longer document.  You can see at the bottom the page numbers are in Roman, small case numerals.  And then for the body part of the text,  we can see the custom header and footer we have defined.  So page number on the left and section description on the right.  And the style more or less was copied from the Laatig style file used by Sphinx.  So continuing with the presentation.  I quickly mentioned Sideprocpy.  This is a sister project to Rhino type.  It's basically a CSL processor,  and CSL is a standardized XML format to describe the formatting of citations and bibliographies.  It comes with, or a lot of styles are available,  so you probably don't need to write your own style  if you are writing a document with citations.  It parses a Beeptech databases, so you can use these,  and it can output the formatted citations and bibliography as HTML restructured text  or using the internal Rhino type representation.  This is not yet usable from within restructured text or Sphinx,  but this should be a very small step.  So this is an example of how citations and references lists could be formatted by Sideprocpy.  So this extends this schema, so we can add references  and Sideprocpy handles the formatting of those.  Now diving a little bit deeper into the internals,  we'll look at the style sheets for this.  To understand this, you need to know how document elements are represented.  These are basically Python instances of flowable classes.  So we have flowables such as a paragraph or an image,  and then we have inline images which make up a paragraph.  After that, I will discuss the style sheets  and how flowables are linked to style definition.  So as I said, flowable can be, for example, a paragraph.  A paragraph adapts to the available width that is provided by the document template,  and they are flowed onto the page.  That's a term that is often used in this context.  Images, for example, they don't adapt to the available width,  or generally not at least, they can horizontally align themselves within the available space.  And flowables form a tree that's together form a documentary,  such as is the case in HTML also, so that should be intuitive.  Here we have a title paragraph, so it has a special title style.  So this paragraph functions as the title of the document.  Then we have two top-level sections,  and the first top-level section has two subsections  with some additional flowables inside of them.  Inline elements, for example, this short paragraph with nested styling  is also represented as a tree.  I will skip over that quickly.  So style sheets, like I said, they are very similar to CSS.  You first select the document elements you want to style,  and you select them based on their place in the documentary,  their style attribute, which is similar to the ID and class attributes in CSS.  Or you can select based on any other attribute or any combination of these three.  Style sheets are plain Python source files.  I also mentioned that before.  We'll have a look at an example now.  So suppose we want to select the paragraphs that are part of a list item here,  but we don't want to select this one.  We make use of a context selection,  so we only select list items that are direct child...  Sorry, we only select paragraphs that are a direct child of a list item.  Or we can also use this selector, the Python ellipsis keyword.  It represents any number of levels of flowables,  and in this case, it simply matches the list item.  We can match based on the style attribute as for the title paragraph  using the like class method.  And we can match on arbitrary attributes.  For example, level two section headings, we can select like this.  We limit the selection of the sections by passing the level argument to the like method.  I'll skip the next one because I'm running out of time.  There's some limitations to CSS, I think.  So I added another level of indirection.  I split up style sheets between a style matcher and a style sheet.  A style matcher basically collects all the selectors and maps these to style names.  And these style names can then in a style sheet be mapped to a style definition.  That means that single style matcher, because these are often the same,  all these selectors, the same for multiple documents, can be reused by multiple style sheets.  I think maybe this might make less sense for HTML, but I think for a document processor,  this is a good fit.  Rhino type also supports variables in the style sheets to avoid duplication.  This is a problem that is often not, or this is a missing feature from CSS  that is often complained about.  And we can also inherit from one style to again avoid duplication.  So let's look at the style matcher and style sheet.  We create a new style matcher.  So for example, we select a style text with the emphasis style  and we assign it to the emphasis style name.  The same for nested line blocks, which should be more or less self-explanatory.  And we use this matcher or refer to it in a style sheet we create.  And over there we map style elements to each of the different style names.  So emphasize text is represented using a tele-sized text  and nested line blocks are indented on the left.  Variables can be used if we reuse a single value for multiple styles.  For example, fonts is a good example of that.  So we define a variable here, IEEE family, which collects a number of fonts.  And we can use this as follows in a style definition.  Note that you can also refer to attributes of this or of the value that the variable references.  You have inheritance.  Suppose we have defined a style for headings, for numbered headings.  We often also have a unnumbered heading style for table of contents title, for example.  In this case, we want to base this on the default heading style.  And we can simply override one or more of the style attributes as is the case here.  So all other attributes are simply the same as for the standard heading style.  You can also extend this style sheet.  So for example, you use a standard style sheet that is shipped with Rhino type.  And you want to make some changes, you can simply inherit.  Additionally, you can add new matchers.  So for example, for the acronym role that was visible in the demonstration, you can define a new matcher.  Then you can create an inherited or a style sheet that is matched based on the previous style sheet  and also refer to the new matcher.  And now we can define a style for the acronym role, restructure text role.  So we set small capitals to true in this case.  We can also override styles that were present in the base style sheet like this.  So we change the font weight to bold additionally.  And we can change variables that will also have effects on all styles that use this variable in the base style sheet.  So here we replace all fonts with some others.  Then a small note about performance.  So this things documentation.  I forgot to update this, but with a new style sheet, it's about 230 pages.  And this takes about 70 seconds to render from scratch.  So this takes two passes if the cache file is in place.  So the document has been rendered already.  It takes only about 40 seconds.  I think this is not too bad for a Python document processor.  However, I still looked into speeding it up a little bit.  That would be nice.  So I tried Scython.  Unfortunately, I didn't get to make a big speed up with that.  I think this is due to the fact that I'm basically doing lots of things with lists and dictionaries instead of tight loops, number crunching.  I also tried PyPy.  Fortunately, it was twice as slow as Cpython.  The PyPy developers are not sure what the cause of this is, but I've talked to Fijal yesterday about it, and we'll have a look at it during the sprint.  I should mention the license.  So my intention is to keep Rhinotype free for non-commercial use.  So open source projects can use it to generate documentation.  I'm thinking about offering a separate license for commercial use, but I have to determine the details about this.  It's a very complicated matter, I understand.  So for more information, please note the spelling of Rhinotype.  It could help you to say that it spells Python backwards.  And please look at these URLs for more information and downloads.  Maybe you still have some time for some questions.  Thank you.  So your lightning talk mentioned, if I'm not mistaken, that there is no support for formulas, right?  Mathematical equations.  Yeah, it's not supported at the moment.  So there is a project in JavaScript world called Katex.  Which one is it?  Katex.  K-A-Tech.  Oh, no, I don't know that.  I know about JSMOT or something.  It's another one. So Katex, they are explicitly dedicated to mathematical equations and everything related.  But it's in JavaScript, so it's just a hint.  Thanks.  Okay, thanks.  How, well, I guess you did try to compare with regular latex for the same document, the same content, I mean,  because it seemed the compilation was horribly slow compared to proper latex.  It is quite slow compared to latex. I think, yes.  So that's why I tried to look at PyPy for speeding up.  However, for small documents, this is not a problem.  But I'll definitely look into speeding the rendering up a little more.  And did you compare with Sphinx?  Same speed as Sphinx?  Sphinx latex render?  Yeah, did you compare the compiling with Sphinx?  Anyone? I don't know. The fastest.  Make PDF was Sphinx and PDF with the Rhino type?  No, I have not compared that.  I would like to know how far along are you with the idea of rendering this to SVG?  I haven't started yet. It's just an idea.  Any more questions?  Which actually text processing library are you using internally?  Because to do all the paragraph formatting and all the page styling or type setting effectively,  what library are you using? Did you reimplement everything that is in tech?  Yeah. So everything is pure Python.  So you cannot rely on external libraries except for docutals or the PNG library.  Any more questions?  Hi. Do you support or will you support absolute placement constraints?  So if a box needs to be placed at an exact position on the page,  or maybe if you have a table where the cells may not be broken, if it's multi-page?  Yeah. So there's nothing in place for absolute placement as of yet.  This could be added, but I'm not sure how that would interact with the rest of the elements.  As for tables, you can set a constraint of how many rows to keep together at a minimum.  So if you can just render like two rows on a page, it will skip to the next one if you have specified like four.  Any more questions?  I have a question about testing. So since it's all related to visuals,  how do you automate testing and stuff? Thanks.  I've done very little testing up to now because I've been constantly refactoring also.  That's a good excuse. But yeah, I'm also a bit worried about how to do this testing.  I guess I will have to mock the backend and maybe it will just be limited to regression testing  that I know which is the good location just to make sure it doesn't change.  Thanks for talking. I tried the line type with Japanese language, tekis.  And the line type accept the... cause the exception.  How do you plan to support as a merge-byte language?  Yeah, Unicode should be a good part of that, but I'm sure there's more to do there.  Of course, you need to also make sure that you have fonts that contain the necessary glyphs.  But this is something I could probably use some help from since I do not read or write Japanese  or many other languages.  Any more questions?  Hi. How do you handle images and is there some sort of scaling mechanism in the line type?  Yeah, you can specify to scale it to the total available width or specify an absolute width  just in points or centimeters.  Okay, any more questions?  Thank you very much for your talk and it has been really interesting.
Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_0_983.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_984_4235.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_4236_5255.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_5256_6719.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_6720_7379.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_7380_8495.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_8496_16247.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_16248_17195.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_17196_17303.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_17304_17579.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_17580_17651.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_17652_17723.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_17724_19955.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_19956_20183.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_20184_20315.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_20316_22355.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_22356_26219.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_26220_26399.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_26400_26483.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_26484_27947.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_27948_27995.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_27996_30239.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_30240_31187.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_31188_31391.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_31392_31451.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_31452_34295.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_34296_38387.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_38388_39935.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_39936_46175.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_46176_46319.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_46320_48239.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_48240_48707.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_48708_50039.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_50040_52163.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_52164_53159.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_53160_53315.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_53316_54707.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_54708_56471.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_56472_57203.png Brecht_Machiels_-_RinohType__a_document_processor_inspired_by_LaTeX_57204_57438.png