Registry / RepositoryTypeScriptRustPython
Rollpie
ReadmeFiles
Versions
Info
Download
0.4.01085.8 KB2026-10-160.3.21087.6 KB2026-10-160.3.11087.5 KB2026-10-160.3.0117.8 KB2026-10-160.2.1106.1 KB2026-10-150.2.0105.5 KB2026-10-15
Version
0.2.0
Copyright
Rollpie, Irohabook
Publisher
math
Published
2026-10-15
Size
105.5 KB
Downloads
18
Checksum
f438a48f6f2fc61d892f930eb4fb56fb5a8e302e733a8c3a6283d0ff7350cd08
Dependencies
rust/[email protected]
rust/[email protected]

[email protected]

iroha get rust/[email protected]

hongo

A Rust library that typesets documents written in LaTeX into PDF.

It uses neither TeX nor LaTeX. Reading the source, breaking lines, laying out pages and writing the PDF are all done here. Math goes to suki, and chemical structures go to lina. Apart from these two, it depends on no crates.

It can set text that mixes Japanese and Latin script. It handles the spacing between Japanese characters, the space between Japanese and Latin text, and the characters that may not begin or end a line.

Usage

cargo build --release
./target/release/hongo doc.tex

The PDF is written next to the document, with the same name and .pdf. Change it with -o.

./target/release/hongo doc.tex -o out.pdf

Fonts go in font/. The math typeface is looked up under the name latinmodern-math.otf. For Japanese, the first file in font/ that is not the math typeface is used. To choose a font for each role, pass --font-roman, --font-japanese and so on. --help lists them.

It also works as a library.

use std::path::Path;

let library = hongo::font::open(
    Path::new("font/latinmodern-math.otf"),
    None, None, None, None, None,
    Some(Path::new("font/ipaexm.ttf")),
)?;
let source = std::fs::read_to_string("doc.tex")?;
let made = hongo::render(&source, &library, &hongo::Style::default(), Path::new("."))?;
std::fs::write("doc.pdf", made.data)?;

Trying it in a browser

A small server comes with it. Paste a source and press the button, and it becomes a PDF that shows on the page and can be saved.

cargo run --release --example serve

Open http://127.0.0.1:7830. It does not accept connections from other machines. If there is no Japanese typeface in font/, pass one with --font-japanese.

cargo run --release --example serve -- --font-japanese /path/to/mincho.otf

test/report.tex is loaded at the start. Edit it and press the button to typeset it again. If the source has a mistake, the page says on which line and what could not be read.

Samples

They are in test/. cargo run --example check typesets all of them.

  • article.tex - an article with math, tables, footnotes and references (3 pages)
  • report.tex - a report with chapters, an appendix, floating figures, p{} columns and chemical structures (14 pages)
  • sample.tex - one of each command (3 pages)
  • figure.tex - images, floats and footnotes (2 pages)
  • feature.tex - chapters, the appendix, alignment and nested lists (3 pages)

What you need

Latin Modern Math (latinmodern-math.otf) is needed as the math typeface. It is the same file as in suki's font/. Without it, neither math nor Latin text can be set.

To set Japanese, put a Japanese typeface in font/. IPAex Mincho and Noto Serif JP may be embedded in PDF. Without one, Japanese characters do not appear, and hongo lists the missing characters at the end.

With the Latin Modern text faces (lmroman10-regular.otf and so on), body text is set in them. Otherwise the Latin glyphs of the math typeface are used, and bold and italic are replaced by the math alphanumeric characters (from U+1D400).

Where it runs

It is written with the standard library only, so it runs wherever Rust does. It makes no OS-specific calls. Sources with CRLF line endings are read too.

It has been checked on macOS only, not on Linux or Windows.

Only examples/check.rs looks for a macOS font when font/ has no Japanese typeface. It exists for local checks, and a font in font/ is used first.

Supported LaTeX

The document structure covers \documentclass, \title, \author, \date, \maketitle, \tableofcontents, headings from \part to \subparagraph, and \appendix. article has no chapters; report and book do. A chapter starts on a new page.

Font changes are \textbf, \textit, \emph, \texttt, \textsf and \underline, and declarations such as \bfseries. Sizes run from \small to \Huge.

Environments are itemize, enumerate, description, quote, quotation, center, flushleft, flushright, verbatim, abstract, tabular, table, figure and thebibliography. Tables take l, c, r and p{width} columns, | rules, \hline and \multicolumn.

Math is $…$, \(…\), $$…$$, \[…\], equation, align and gather, with their starred forms. suki sets the contents, including aligned, split and gathered inside a formula. Chemical structures are \chemfig and \chemname, set by lina.

References are \label, \ref, \pageref, \cite, \footnote and \caption. Images are \includegraphics, which reads width, height and scale. PNG and JPEG can be used.

You can define your own commands and environments. \newcommand{\name}[number of arguments][default]{body} and \newenvironment{name}[number of arguments]{begin}{end} are read and expanded into the tokens. plain TeX's \def\name#1{body} is read too. \input and \include are replaced by the contents of the file.

Furigana is added with \ruby{漢字}{かんじ}. The base text and the reading are centered on the wider of the two. The reading is drawn in the space between lines, so the line spacing does not change. The table of contents and the bookmarks show only the base text.

Some commands from common packages are read with a substitute. booktabs' \toprule and the like become horizontal rules, and \textcolor drops the color and keeps the content. \fbox, \mbox, \rule, \eqref, \footnotemark, \footnotetext, minipage, repeated columns such as *{3}{c}, and accented letters such as \'e are read as well.

How it works

Reading, layout and writing are kept apart.

token cuts the source into tokens, and parse builds a tree. The contents of math, chemical structures and verbatim are kept as written, to be passed to suki and lina unchanged.

number numbers headings, figures, tables, equations and references, and ties each \label to its number.

layout turns the tree into a vertical list. line breaks body text into lines. When both edges are justified, it chooses the breaks by looking at the whole paragraph; otherwise it fills each line as far as it goes. Zero-width spaces sit between Japanese characters, so lines of Japanese alone are justified the same way.

page lays the vertical list out on pages. A footnote is placed on the same page as the line that carries it, and the room for body text shrinks accordingly. Floats go to the top of the first page where they fit.

pdf writes the file. Every character is set in a Type0 font with Identity-H, so glyph IDs can be written directly. Glyphs with no character assigned (such as stretched delimiters) and Japanese are handled the same way. ToUnicode is added so that text can be selected and copied.

The table of contents and \pageref cannot be written until page numbers are known, so layout runs twice.

Decisions

No outside crates. Fonts are read with suki's code, and the PDF writer is written here.

Content streams are not compressed, so that no compressor has to be written; the files are larger for it. Japanese typefaces are cut down to the glyphs used before they are embedded, so even a 20 MB typeface ends up as a few hundred kilobytes.

PNG and JPEG are passed to the PDF without being decoded. PNG's IDAT is zlib, and so is PDF's FlateDecode, so the data can go in as it is once the predictor parameters are copied over. PNGs with transparency are not read, because separating the transparency would mean decoding the image.

Not supported

There is no hyphenation for Latin text. Without hyphenation tables, a long word that does not fit simply runs past the end of the line.

Kerning and ligatures are not applied, because the font's kern and GPOS tables are not read.

Two-column layout, marginal notes, indexes and reading references from .bib files are not supported.

License

Dual licensed under MIT and Apache-2.0. Take whichever you prefer.