 Welcome everybody. My name is Brecht. I'll be giving a talk about my project Rhino type. It's a project I've been working on since 2008. I was doing a PhD back then. I was using Laatig and I was kind of getting fed up with it. Because of the difficult error messages and the difficulty to create a custom style. So these were the reasons I started working on Rhino type. Now finally, after all these years, it's in a kind of beta stage. So it's more or less ready for general use. So what is it? If you're familiar with Laatig, you will know how it works. It's a patch document processor. As an input, it takes structured document. This can be restructured text or markdown format. Besides these lightweight markup formats, it also accepts or does a very simple frontend for dogbook files. And there's also a commercial frontend for data files, which is an XML format that is used by technical writers. Of course, besides the text stored in the structured documents, we can also provide images. Rhino type accepts PDF, BNG and JPEG images. If you want to use other bitmaps, you can do so if below is installed. To style the outputs, Rhino type depends on style definition in the form of a style sheet and a document template. These are both in plain text files in any format. Besides these style definitions, we also require fonts. Rhino type supports the most common font formats, such as OpenType, TrueType and PostScript type 1 format. So combining these inputs, Rhino type will produce an output that is a PDF document. An example of its usage, Rhino type comes with a command line tool called Rhino. We can pass a restructured text document or the file name of a restructured text document to it, and Rhino will render it to a PDF file and tell you about it like this. It also accepts common markdown files. You can see that Rhino also accepts some options. We'll go over them later. For example, this one renders a document to an A5 paper format. It also presents the progress using a progress bar so you can see how long it will take to render the document. Besides the command line tool, there is also a Sphinx builder. This is basically a drop-in replacement for the Latik builder, so you do not require to have a large Latik installation to produce PDFs from Sphinx anymore. You can use it like this using the Sphinx build command. You just pass the Rhino to the builder option of Sphinx build, along with the source directory and the output directory. I will also give an example of this further on. As for installation, Rhino type works on Python 3 only, Python 3.3, and up to be precise. It is written in pure Python, so there is no compilation required, and it depends on just a couple of external packages. There are packages for common mark or markdown support, for restructured text that is handled by docutals, and then there are pure .png to parse .png files. Besides that, Rhino type also packages fonts separately. These are also installed when you install Rhino type. For the next release, I have planned to also provide standalone applications, so if you do not have Python installed, you can just download a Windows installer or macOS application bundle, and that includes Python along with Rhino type. I want to give a small demo. This will be difficult. In this folder, we have an example restructured text file. With a document title, section, another section, and then a subsection, a paragraph here with a link in it, a small table, another paragraph in the second section, and some nested lists. We can just call Rhino passing it the file name. You can see it has to render a document twice, and this is to make sure that page references are handled correctly. If you're familiar with LaTeCh, you know you have to run it a couple of times. Rhino type handles this transparently, and you mostly need to run for a single document. If we run it again, it will only need a single pass because it writes cache file storing reference information. Then for the Sphinx builder, I have as an example taken a relatively small Sphinx project from a simple JSON project to make this built with Rhino type. We have to make one small adjustment and just to add the Sphinx builder module location to the list of extensions in Convult Pi. After this, we can run Sphinx build like this, so passing it the Rhino as the builder option, the source directory, which is the current directory in this case, and an output directory. Then you get the standard Sphinx outputs along with Rhino type's progress indicator. This takes a little bit longer because it's a larger document. Again, there's a second pass. Then I'll show the output of the first example. This Rhino by default uses the article template, which consists of a title page. We have a document title here that was specified in this restructured text document. Along with the date, then we have a table of contents, which is hyperlinked to the pages and also lists the pages as you'd expect. Rhino type also generates bookmarks in PDF, so you can jump to each section using that. This is the actual content of the document. You can see the two sections and the table. Then the output of the Sphinx builder. This uses the book template by default, which can be configured. It's a title page, a larger table of contents, and then the actual content is a preface. You can also see the syntax highlighting for code blocks. This is the first chapter. You can see that chapters start on new pages. You might recognize the style of the document. It's modeled after the latech output produced by Sphinx. That's a default style sheet shipped with Rhino type. Special in the book template is that it also generates an index. This is not limited to documents generated by Sphinx. It's also possible for plain restructured text documents. It's generated by Rhino type itself. Let's go back to the presentation. This is a summary of what I've shown. For the Sphinx builder, it basically uses the latex document definition in Conf.py. If you have latech output configured, Rhino type will interpret this configuration. You only have to add it to the list of extensions. Suppose we want to change the style of the output. First, we need to know how Rhino type handles this. In fact, it's very similar to CSS, where we select the elements on the page using selectors. This is performed in the document tree. At the front end, it creates a document tree, which is then transformed to internal representation in Rhino type to another document tree. This sample document is displayed on the right. There are two sections, each with a unique ID, a subsection, and you have the heading of the section paragraph table over here, and the list over here. Once we have this, we can start selecting elements. Let me first say that paragraphs are also included in this document tree, and they also consist of a tree to represent nested styling. This paragraph above with nested styling is represented in this tree. We have, for example, the simple text without styling, and then this whole part is emphasized as this one, and part of that is then strongly emphasized, and so on. This basically completes the tree shown above in the previous slide. We can match elements based on their context. Just like in CSS, each element in this tree is called a flowable, which is float onto a page, and you can adapt to the width of the page or center itself inside the available width. Also, each element in this tree is a Python object, and so this is a class name. These selectors are basically Python source codes. Using operator overloading, we can use this to construct selectors. For example, this one represents a table cell or represents a paragraph that's a direct child of a table cell by using the forward slash notation. It selects in this tree, this paragraph, for example. We can use the ellipsis that's provided by Python to match multiple levels of elements, and this selects then all paragraphs that are part of a list, so as well as this list item in the enumerated list. It also matches the paragraph in the bulleted list. We can also match elements based on their style. Style is similar to HTML's ID or class attributes. For example, enumerated lists, excuse me, you can see they are the same object. Enumerated and bulleted lists are the same flowable, but their style is different, so this is enumerated and this is bulleted, and that's basically the enumerated is provided by styling it as an enumerated list. And it's selected like this using this class method called like and then passing the style name. We can also match arbitrary attributes such as the level. The section has a level attribute specified that specifies its level in the hierarchy. So this is a level two section, so this is a level one section, as well as this one, so it's not selected, but this one is subsection is a level two section, and we select the heading below it, so it matches this element. We can do some more complex things like this, but I will not go into detail about this. Different from CSS is that Hynotype provides an extra level of abstraction, so instead of specifying selectors in a style sheet, we first map the selectors to style names. This has two advantages, they provide a descriptive name, and second, these matchers that collect all these selectors and map them to style names can be reused by multiple style sheets, so this saves some work. We can also reuse style names in new style and new selector definitions, so line block over here is defined like this, and if we combine them, we can map that to a nested line block. There are some more examples given, but they are pretty straightforward. Then on to the style sheet, as I said, it's a basic text file in any format, so a style sheet starts with the style sheet section, we can give it a name, it also supports variables, so for example, we can define a variable sans typeface to specify which font to use for all sans typefaces in the document, so if we use this variable in style definitions later on, we only need to change this one. Same for color blue, which can later be changed easily. Then we define a default paragraph style, so except for these two sections, all of the other sections they should map to style names that are defined in a matcher. Except for this one, it is not specified in the matcher, and that's why we have to specify that it's a paragraph style. Why? Because this is used as a base for other styles, so we can define some font properties, some settings regarding to type setting, text alignment, how to align the text horizontally. Then we have the body style, this is a style for body paragraphs, so most of the paragraphs in your document, it has the base style default as the base style, so it basically inherits all of these properties and adds the space above property. Then we also have an inline text style for emphasize text, and this sets the font's length to italic. We also support inheritance in stylesheets, so mostly you will use a stylesheet that is shipped with Rhino type or provided separately. You can inherit from this simply by specifying the base, so Sphinx is a stylesheet that is included with Rhino type and you can just specify it by name. You can also specify others by file name, for example. We can overwrite variables, so for example, we replace old sans typefaces with dried sans in this stylesheet, and we also overwrite emphasize text. Note that this inherits all properties of the emphasize text or emphasis style of the base stylesheet, and additionally sets the font color, so text will be italic and receive a color. If you don't want to inherit the properties of the base stylesheet style, you can set base to default style as indicated here, so this will only change the font color and not the font weight as was done in the base stylesheets, for example. How much time is left? Ten minutes, okay. So, because this is a little bit slower with one hand, so suppose we want to change some of the properties of the restructured text documents I've shown before. Now, how do we find out which style definitions we have to change? For this Rhino type, I need to change back. Every time Rhino type renders a document, it also generates a style log, and this is basically a representation of the document as it is rendered. For each page, it will list the three of the elements that have been rendered to the page, so let's go to page three where the actual content is, and there we can find the first section, and we can see that this maps to the chapter style for the section heading. It maps to the heading level one style, so we can start and change this in the stylesheet. In case heading level one was not specified in the stylesheet, it would move on, put an X here, and it would move on to the next style in the list. So we can do this for the example document, so here we specified some name description and which base stylesheet to use. We also override a variable, which changes the font, and finally we change the heading level style. So it also inherits from the base style, but we change some properties such as font size, font weight, font color, and also change the format of the number preceding the section title, and similar for level two, we make similar changes. So the result of this, to make it use the custom stylesheet, we can specify it like this, so dash dash stylesheet, specify the file name, and then this is the original document, and this is where the changed stylesheet, so you can see that section titles have received a different color. The numbering has changed to using Roman numerals, and also this title has changed and using ABC for the section numbers. You can also see that the font has changed because we set the variable not only in the body paragraphs, but also in the table. Finally, we can also customize the look of the output document by using document templates. These determine which parts are part of a document, so typically there's a title page, from matter with table of contents, and possibly other things, than the actual contents of the document, and finally back matter with an index. So this is defined by the template. For each document part, there's also a page template provided, and this can be configured, so for example, margins can be set the number of columns, spacing between columns, which takes to place in the header and the footer fields, for example. Besides the configuration of page templates, you can also configure certain aspects of the document parts. So here's an example. So we configure the article template, which is part of the rhino type distribution. We specify which parts to include in the output, so here it omits the front and back matter, so only leaves the title and the contents part. You can also specify which style sheet to use. You can specify which language to use for typical titles, such as table of contents, or the index, and we can also, for the article template, as a special option, which allows you to select where to display the abstract on the title page, or later in the document. We can also override titles for sections, so the language already sets these for each language, but you can still override them like this. So for the table of contents, you can manually give a string. Again, you can work with variables. The paper size variable is used in the page template, so this will change the page all over the document, and this corresponds to the title part, and so you can set the page number format, using lower case Roman numerals in this case, and at which page to end the part. Make sure that the next part starts on the right-hand page. And for the title page template, you can set the margins. For example, top margin is changed here, and you can even set the background using this PDF image, and we can set the scale option to fill or fit the page, for example. So this is an example of style for the Rhinotype manual, I've been working on, and it shows what is possible. So using margins and indentation in a smart way, you can obtain this kind of result. It also changes the link color, etc. This is using a background for the title to make it a little bit more nice. And this is a page spread with a left page and a right page. It changes the footers separately for the left and the right-hand pages to obtain this result. Now, all of these things like style sheets and document templates are handled similarly by Rhinotype. They are called resources, and they can be retrieved by name, by entry points. These can be provided in separate packages on PyPI, and then used in documents by just referring to them by name. You can find out which of them are installed by using the appropriate list options. Also, the front ends are handled in this way. In the future, I hope to enable to automatically install fonts, for example, from PyPI when it's being used by documents, so you don't have to manually install it when you retrieve a document and render it. So, that's it. Some more references and contact information. Do we have still time for questions? A couple of questions. No, that is not supported at this moment. The PDF backend is as simple as possible at this moment to make this possible. No, no. But there is a... That would be a fun project, perhaps. There's a Latig parser for Python, only 2.7. You could use it to write the front end for Rhinotype. And I think it even evaluates tech code, so perhaps it's pretty powerful. Yes? Sorry, can you repeat the question? Yes, you can set the alignment of images using the style sheet. Yes? It does handle unicode. But it's not been properly tested with other scripts yet, but that's why I wrote it in Python 3, so that internally it's all unicode, so that... In the after-generation... Yeah, yeah. Right or left? Yeah, right or left is not yet supported, but unicode, it should handle. It does, depending on... If the custom directive expands to known directive, you don't have to change anything in Rhinotype, but you can also, for example, create a specific flowable that renders your custom directory. Yes? How difficult is it to implement another front-end? Anything, for example, textile? It should not be too difficult. It starts from a documentary in which each node has a name, and this is mapped to a Python class, so in this class you implement the mapping to the internal representation. So with Sphinx, Sphinx kind of handles this for restructured text, but for other formats, like the basic restructured text front-end, it's not possible to pass it to two documents and it will not concatenate it. That's not supported now. Okay, that's it, I think. Thank you.