10 ms·
Beautiful Documents with Groff (Part I)
- ggm 3y agoThe roff series of tools reaching back to runof(f) predate TeX by a decade. Obviously troff was more contemporary to TeX but the foundations were laid in '64. The model of .dd style directives, macros, and it's textual assembly model are good. They work. They suit the edit compile preview print model. Fitting tbl and eqn and pic in was not untenably hard. They're a product of brilliant minds in a different sense to Knuth's. They are just not infinitely designed around the harmonic mean, golden proportions, aesthetically pleasing models of arbitrary ink on paper. You wouldn't reach to groff or ditroff for calligraphy like by hand with a brush, where TeX might ask "can we encompass hand brush movement" It's made for a world immediately present in monotype machines, and phototypesetters with fonts on film. TeX aspires to more. I admit TeX confused me. It may explain why I failed at launch on writing a thesis 3 decades ago.
- atoav 3y agoWhen I wrote my MA thesis I opted for markdown that compiles to a Adobe Indesign .idml and did all the styling there. Everything including figures and footnotes worked fine with only two or three minor manual corrections needed after updating the material. Nowadays I might go for LaTeX, but I must say I liked the "write and forget"-nature of markdown and imagine LaTeX would distract me much more
- Lio 3y agoI guess a good compromise might be to use Markdown or Asciidoc and then combine it with LaTex layout using Pandoc. https://comparch-resources.ece.gatech.edu/resources/markdown/markdown/ https://comparch-resources.ece.gatech.edu/resources/markdown...
- agoose77 3y agoCheck out MyST or Quarto for new efforts in this direction!
- tannhaeuser 3y agoIndeed, not only is (g)roff a descendant of runof(f), but so is IBM's SCRIPT/VS, which, in turn, is the origin of SGML and hence HTML ;) Moreover, the .dd style directives would be later generalized into ... Generalized Markup Language (GML) and groff's original author James Clark would later develop SP/OpenSP and become co-author of ISO 8897 (SGML).
- jiehong 3y agoOnly time I tried Groff was last year, because I liked the idea and the speed. But couldn’t finish a single document, because by default accents in French or Chinese characters cause documents compilation issues. Tried using mom, without much luck. Wasn’t aware a secondary tool was needed to make it work, as Unicode is not supported by default. On top of poor documentation, I gave up.
- 2b3a51 3y agoYou might be interested in heirloom troff. Supports UTF-8 so French might be fine, but I'm not sure about Chinese characters. https://n-t-roff.github.io/heirloom/doctools.html https://n-t-roff.github.io/heirloom/doctools.html The page below might be of some use - seems like some work needed to get groff (GNU troff) to use Chinese characters. https://kleshwong.com/blog/post/composing-pdf-on-linux-happily-as-an-non-latin-coder/ https://kleshwong.com/blog/post/composing-pdf-on-linux-happi...
- epilys 3y agotried to build it, but it has some unorthodox ideas of filesystem structure; this gist I found gives a quick summary how to install it all in a single folder: https://gist.github.com/baruchel/0653cc7c041d58d21b202c8e94e4ea30 https://gist.github.com/baruchel/0653cc7c041d58d21b202c8e94e...
- yockyrr 3y ago> Alas, the site that inspired me doesn’t seem to exist anymore, but basically, it was a grad student who was procrastinating as I do and had decided to write their thesis in groff. I believe the site referenced was a blog post I wrote and submitted here in July. Unfortunately the post's popularity used up the free trial it was hosted on. The post can now be viewed here: https://yockyrr.gitlab.io/jstutter/ https://yockyrr.gitlab.io/jstutter/ with original comments https://news.ycombinator.com/item?id=32202209 https://news.ycombinator.com/item?id=32202209
- unwind 3y agoOmg that is like a thesis on thesis production, instead. Wildly impressive, and great job with the actual screenshots for comparing output. Thanks.
- hbbio 3y agoAnother good example of groff is that invoice: https://eseth.com/2020/cli-invoices-groff.html https://eseth.com/2020/cli-invoices-groff.html FWW, I started a new engine in Go quite similar to groff a few years ago. Extremely fast rendering and quite high quality!
- mikojan 3y agoI want to love groff. All the most beautifully typeset documents I have produced I have produced using groff. However, it is just so hard to remember how it all works. It is an amazing struggle everytime.
- taeric 3y agoI confess I'm intimidated by folks that have slow TeX documents. Especially on modern machines, it is hella fast for all documents I have seen. I assume full book rendering is the slow part?
- slavapestov 3y agoI believe certain macro packages can be slow, like TikZ (which is otherwise great).
- taeric 3y agoI would assume any high res asset generation would be best not done inline? Such that that makes sense, but is kind of unsurprising? Is also unsatisfying as an explanation. Since none of the examples people show to get off TeX show that. Rather they imply it is the typesetting aspect that is slow.
- belter 3y agoMy favorite part is : "...Fussing with typography is an excellent way to procrastinate..."
- macintux 3y agoOne of my all-time favorite books which of course I’ve owned multiple times but never read in its entirety: UNIX Text Processing, which covers the roff family in detail, plus eqn, awk, etc. https://www.oreilly.com/openbook/utp/ https://www.oreilly.com/openbook/utp/
- cpif 3y agoThis looks wonderful -- thank you for posting it!
- 2b3a51 3y agoPossibly of interest... https://github.com/larrykollar/Unix-Text-Processing https://github.com/larrykollar/Unix-Text-Processing A re-compilation of the book by various contributors coordinated by Larry Kollar. The whole thing compiles in a few seconds on an old Thinkpad (I had to fix a font location warning).
- cjensen 3y agoI very much endorse that book. I only have two small shelves of technical books, but that one makes the cut to be on it.
- cpif 3y agoMy introduction to roff and co. as a typesetting system was the 1997 edition of Dale Dougherty and Arnold Robbins's Sed & Awk. Many of the book's examples are geared toward automatically inserting/correcting roff macros. I can't recall a specific example from the book, but it would be something like "insert the roff 'section' macro on matches of `/^CHAPTER/`." Ultimately, it's probably not practical, but I liked the idea of using UNIX utilities to get around worrying about markup altogether during the writing process. The book isn't really about roff, so I only got a sideways view of this kind of workflow. Was this "a thing" in the 90s?
- sramsay 3y agoAuthor, here. I was just thinking yesterday that it's time to write part II of that piece. But briefly, for the HN crowd: I ended up switching my toolchain to a markdown-based system relying on a combination of pandoc, Makefiles, and various little command-line utilities. Again, this is mainly for large, book-length projects where compilation speed becomes an issue (though I have been using the same system for written lectures all semester). Pandoc, of course, gives me HTML, EPUB, docx, LaTeX, and plain text. But what I really wanted (for the speed boost) is groff -mom, so I wrote a custom pandoc Writer to make the translation. I haven't released it, though I'd like to eventually. Pandoc recently changed the way it does Readers and Writers, and I'm not sure I completely understand the new way (right now, it sort of does an "include" on the old-style code). Delighted to see that the post that inspired this journey is back online. Here's the link again, in case it gets too buried: https://yockyrr.gitlab.io/jstutter/ https://yockyrr.gitlab.io/jstutter/
- sirodoht 3y agoOh, I'm disappointed now, I wanted to learn more about groff and mom! I've been through many typesetting systems lately, namely latex, sile, pollen, patoline, scribble, typst, even affinity publisher. I ended up back to latex with tectonic as engine/distribution. My problem with the rest is that they don't output pdf. And my problem with typst is that it is still pretty immature (doesn't support foonotes, for example).
- dsign 3y ago> In order to assess whether the thing I’m writing is good or not, it’s important for me to see what it would look like as a real book (or letter, or article, or whatever). This resonates. There is a part of the brain that engages better with content which is properly formatted, even if the content itself is awful. And by "formatted," I mean either typography and spacing, or even the media. A bad audiobook read by a great narrator sounds way better than a great book read by an incredible TTS (like elevenlab's). But any content read by that same TTS somehow is more real and professional than the same content in a word processor, at least to me.
- JdeBP 3y ago> Actually, unicode support is one of groff’s most mysterious blind spots. Interesting. What didn't work about -Tutf8 for you? I assumed that I was simply doing something wrong, and left it as a problem to solve later given that I can view the original DocBook XML in UTF-8 without problem. This tells me that there's more to it than I thought.
- b3lm0nt 3y agoI've started using plain vanilla groff (eg., no mom or other macro packages) for formatting text files. Just run: groff -Tascii example.groff I've found it be perfect for my purposes. LaTeX felt like too much overhead for generating a few nice-looking README files and blog posts. I also have a soft spot for older UNIX / GNU tools. The best sources of documentation (which did take some time to track down) are: - gtroff reference: https://www.gnu.org/software/groff/manual/groff.html#gtroff-Reference https://www.gnu.org/software/groff/manual/groff.html#gtroff-... - man 7 groff: https://man7.org/linux/man-pages/man7/groff.7.html https://man7.org/linux/man-pages/man7/groff.7.html I keep a small, annotated .groff file in a gist. It serves as a reference for the formatting functions I use most frequently: https://gist.github.com/benjamindblock/0926f7346b79b93e739abc1b20a4fd8a https://gist.github.com/benjamindblock/0926f7346b79b93e739ab...
- noisy_boy 3y agoThanks for sharing your groff file. I'm on a Debian derivative and running the below command did produce a pdf but the line "This paragraph should be right-justified and indented by th" was chopped off on the right side: groff -Tpdf example.groff > example.pdf Also, the left/right margins are partically non-existent (top/bottom margins look fine). Did I miss any command-line option?
- b3lm0nt 3y agoFirst point: the groff file in my gist is designed for plain-text files, so not all the functionality will exactly translate to PDF rendering. Second point: to resolve the issue you're running into, remove these lines from the groff file to allow the default margins for PDF rendering to occur. \# Set the line lenth to \nl .ll \nl There can occasionally be some strange behavior with the macros when different output devices are used (some options are ignored, some may have unexpected consequences). I took a look at the PDF output using my file directly, and it looks like the em sizing for gropdf is different from the grotty implementation, causing some overflow. (Maybe the font needs to be set explicitly before setting the line-length? Not sure). Using a different unit of measurement (like inches or points) may be a better option for PDF files: https://www.gnu.org/software/groff/manual/html_node/Measurements.html https://www.gnu.org/software/groff/manual/html_node/Measurem... Bonus note: you can confirm the final output device that will be used by a groff command by adding the -V option. Example: groff -Tpdf -V examaple.groff Outputs: troff -Tpdf example.groff | gropdf Using -Tascii instead will produce: troff -Tascii example.groff | grotty Ref on output devices: https://www.gnu.org/software/groff/manual/html_node/Output-Devices.html#Output-Devices https://www.gnu.org/software/groff/manual/html_node/Output-D... * Edit: See 2b3a51's response for a better explanation.
- jimhefferon 3y agoThis is a fun read. But I don't find LaTeX to be slow, personally. I'm working on a math text. 449 pages with hundreds of equations, hundreds of graphics, you get the idea, and on reading this article I timed a compile. On my 2016 laptop it took 20 real seconds. Anyway, gripe aside, interesting read.
- mhd 3y agoLast time I did some longer groff documents (ages ago), I was quite disappointed by the paragraph layout, closer to Word quality than TeX. I know that heirloom troff[0] boasts some improvements here (by using the TeX algorithm), but did groff get better at it, too? [0]: http://n-t-roff.github.io/heirloom/doctools.html http://n-t-roff.github.io/heirloom/doctools.html
- kayo_20211030 3y agoNice. Looking forward to part 2.
- Dangeranger 3y agoA document describing how to use Groff and Mom together by Peter Schaffter[0] can be found here[1]. [0] https://schaffter.ca/pdf/curriculum-vitae.pdf https://schaffter.ca/pdf/curriculum-vitae.pdf [1] https://www.gnu.org/software/groff/groff-and-mom.pdf https://www.gnu.org/software/groff/groff-and-mom.pdf
- kazinator 3y agoThe TXR manual is written in troff. It's designed so that you can install it as a man page, but it has macros which retarget some of the formatting for HTML and PDF. When compiled to PDF, it comes out to over 900 pages. It may be the only man page you will ever see which auto-numbers its sections (down to three levels deep). I developed the macros for all that. Pretty much any large or large-ish man page you can think of does not have this feature. E.g. type "man gcc" or "man bash": no section numbers anywhere. I use Lucifredi's man2html converter from the man1.6 package. I think this is mostly abandonware. The man2html program is essentially a hacky reimplementation of enough of a subset of nroff to crank simple man pages into HTML. It does a better job than any other converter. (There is at least one more thing called man2html, like one unrelated program written in Perl.) I made some 30 commits to man2html, fixing bugs, adding some features, and making it understand and execute complex nroff macro definitions. One feature added is that man2html defines a variable M2 which the code can use to conditionally switch to code specific to man2html versus regular nroff. All that work is here: https://www.kylheku.com/cgit/man/log/ https://www.kylheku.com/cgit/man/log/ Anyone wanting to reproduce the HTML version of the TXR manual needs that version of man2html. A TXR program called genman.txr, in the root of the TXR source tree, analyzes the man2html output, and rearranges it, adds identifier cross-referencing, a collapsible table of contents (via a tiny bit of JS) and such. I use another TXR program for running checks for common markup mistakes in the manual: checkman.txr in the root of the TXR source tree. It understands the usage of many of my custom macros and validates that they are correctly used, in their intended structures. For instance if a syntax synopsis block is opened with .synb, it will tell you there is a missing .syne closer. There are "weird" formatting macros; e.g: .coNP Operators @ let and @ let* .synb .mets (let >> ({ sym | >> ( sym << init-form )}*) << body-form *) .mets (let* >> ({ sym | >> ( sym << init-form )}*) << body-form *) .syne .desc The .code let and .code let* operators introduce ... coNP is like NP, introducing a paragraph at a certain subsection level; the co refers to it having code markup. In co markup, a word preceded by @ will be typeset as code, e.g. typewriter font. A word preceded by @, (at comma) will be typeset in a typewriter font, followed immediately by a comma in the original font. .synb starts the syntax synopsis section and .synb ends it. We use .mets for markup in the syntax synopsis. The "met" refers to "meta": markup for meta-syntactic identifiers, which typically use italic in HTML and PDF of angle brackets like <sym> in the plain text man page. In .mets, everything is typewriter by default. When an argument is preceded by <, it is marked up as a meta identifier, italic or <angle>. When two arguments are preceded by <<, like << body-form *) the left one is meta, and the right one is tacked onto it with no intervening space. There is also <> with three arguments: <> A B C will typeset B as a meta, flanked by A and C with no space; and there is an opposite >< also. All these macros are defined near the top of the txr.1 file. The "meta" markup is implemented by lower-level macro called .getm which the higher level ones like .mets and .meti and .meIP use. That macro is implemented twice, conditionally switched for nroff mode (angle brackets) and regular (font switching).