Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Htmldocs – Typeset and generate pdfs with HTML/CSS (htmldocs.com)
226 points by kelvinzhang 8 months ago | hide | past | favorite | 89 comments
htmldocs is an Overleaf-style editor for typesetting documents using HTML/CSS, which provides the same benefits as LaTeX while being more accessible, customizable, and familiar.

I built this because I wanted to programatically generate invoices as well as automatically tailor my resume to jobs but had no good way of generating well-formatted PDFs. I ended up building a templating engine to Chromium rendering pipeline to generate PDFs, and due to the amount of engineering effort, turned it into a tool for others that might want to do the same. There's a built-in API (https://htmldocs.com/docs/documents) that you can call to turn JSON into PDFs in a single call.

htmldocs is different from other tools like Wkhtmltopdf and Weasyprint in that it uses Chromium to generate PDFs, meaning that it supports the most modern CSS features and there's minimal drift between the rendered HTML document and PDF.

Will also consider open sourcing if there's enough interest in the project!




> htmldocs is different from other tools like Wkhtmltopdf and Weasyprint in that it uses Chromium to generate PDFs, meaning that it supports the most modern CSS features and there's minimal drift between the rendered HTML document and PDF.

WeasyPrint is implemented as a from-scratch and specific-purpose rendering engine, so yeah, it’s different. But wkhtmltopdf uses WebKit, meaning it’s much the same as htmldocs, just backed by a different browser engine.

It’s important to realise, though, that using an existing browser engine doesn’t mean everything’s hunky-dory: in fact, when it comes to some of the things you care about with producing PDFs, some things will be worse, and the WeasyPrint approach has significant advantages. Because browsers don’t care about your use case at all. From time to time they’ll improve things incidentally, but all browsers are missing things like a lot of CSS Paged Media stuff, stuff that’s often been specified for a decade or more, where things like WeasyPrint have had them for years and years.


As the maintainer of wkhtmltopdf @ Odoo I can tell you it's not WebKit. Instead it's outdated WebKit from 2014 running on top of QT4 '^^


@monax Since you're the maintainer, I'll assume you no doubt will know more about it than me. But from what I (vaguely) recall, it's worse than that.

Not at liberty to elaborate on exact details, but not so long ago I had to deal with wkhtmltopdf, when it turned out to be the (still preferred/recommended) PDF rendering solution as part of a major popular web middle-ware framework, at a large corporate client. I was rather shocked to see a top-tear prestigious international institution working with such outdated tech (albeit certainly in ignorance), but never mind that.

What struck me most was the nature of the bugs I encountered. Probably one of the most baffling: seemingly randomly changing formatting of the output. In the end it turned out to be a Windows specific problem, where multiple administrators logged onto the Windows Server hosting the web application. Because of different workstation display geometries on their end, they effectively kept changing the display DPI settings of that server (a headless machine, only accessed through RDP). That in turn affected the rendering internals of wkhtmltopdf. Rather hilarious when I finally figured it out. That's when I learned it best never again use wkhtmltopdf on any Windows system (if anywhere at all, for that matter).

Wasn't the WebKit core even older than 2014? Maybe something about it being older but then just maintained independently until 2014 .. or something like that? Or maybe my memory is just messed up and failing me.

Either way, what I do remember is my amazement about seeing this (at best) 10 year old code (arguably of questionable quality to start with and certainly outdated by now) still in use as a go-to solution for rendering PDF from HTML. Ended up replaced it with a puppeteer-based solution. Arguably with its own problems, but less of a black hole than wkhtmltopdf. Especially considering it was (also) rendering user-supplied data. What could ever go wrong, right?


It seems you have more information about this situation than I do, as I recently took on the role of project maintainer and wasn't involved from the start.

I find the bug you mentioned interesting, and I'll promptly investigate to determine if it still exists. If I remember correctly, there's a --dpi option that may have already resolved this issue.

I share your concern about the code's state; it's problematic as it's currently leaking file descriptors and memory all over the place. We experimented with Puppeteer as an alternative, but its speed and memory usage were too high for our specific use case, so we're currently stuck with the current wkhtmltopdf.


Just to clarify, I'm not bashing wkhtmltopdf. I think it is a great tool (or at least it was), for what it was initially designed for. I've used it myself several times, to great effect. Albeit mostly long ago (about a decade or so).

I'm not even concerned all that much about the code's state itself, rather that it still shows up today. In situations it was probably never designed for. Adding to that, it now often appears wrapped inside some interfacing layer/code, binding it to whatever other software it is embedded in. But then only exposing part of wkhtmltopdf. Case in point, the --dpi option you mentioned (which indeed might fix the mentioned bug), was simply inaccessible through how the framework interfaced with wkhtmltopdf (which was a design cluster-F# in its own right).

However, the bigger elephant in the room for me is that the HTML/CSS support has changed considerably over the last decade, with wkhtmltopdf pretty much stuck in time. It's just pretty much a random hit or miss when it comes to rendering any modern web content. Only for carefully crafted (legacy) content does it still make a good use case.

I won't blame wkhtmltopdf for that though, but I sure haves questions for those who apparently still consider it a valid tool for integration into modern web frameworks. I guess part of that comes down to unintentional ignorance, not knowing what they are actually integrating. Another reason might be that I've not seen much of a better sort-of-drop-in replacement for wkhtmltopdf, so people stick to it far a lack of a proper alternative. Maybe some of the people who integrated wkhtmltopdf elsewhere are even very well aware of all the limitations/dangers. Still, little use of that if that knowledge is lost on those who subsequently end up using it, primarily just as consumers.

Puppeteer is a very different beast in its own right, regardless which engine/browser you end up using. But if more modern html/css features are required, it can be a valid replacement (regardless of numerous downsides nonetheless). Still, I (also) doubt that it will work as a good replacement for all of wkhtmltopdf's use cases.

If nothing else, I got some free entertainment out of it all .. watching the shocked expression on the faces of top-level suits, when I explained to them what they had been blissfully unaware of. They had good reasons to be worried, because this exposure should have been caught by their rigorous technology-review procedures. However, it had been an ad-hock dependencies that was introduced as part of a legit feature request. The dev had probably never even noticed, because it appeared as a native framework functionality (hiding any obvious reference to using wkhtmltopdf under the hood). Anyways, wkhtmltopdf is certainly not to be blamed for that.

Still, it does illustrate the dangers of modern-day software integration. I think especially in (web) frameworks, where the name of the game often appears to have turned towards a popularity contest (with competing frameworks) and "making things as simple as possible". Something about a road paved with good intentions.


You can use paged.js (https://pagedjs.org/) it's a polyfill for CSS Paged Media to generate good PDFs with modern HTML/CSS.


Prince has been doing this for 20 years and is in my opinion the gold standard, with good support for footnotes, endnotes, page headers and other little extensions that are only relevant for printing. https://www.princexml.com/

But I'll be giving this a try!


I totally agree - PrinceXML is what I use for PDFs generation.


See also native CSS support for paged media:

https://www.w3.org/TR/css-page-3/

When I looked into it several years ago, browser support for some critical features wasn't there yet. Not sure whether this has improved.

In principle, this would be a great alternative to proprietary PDF rendering libraries which require you to design your document completely in (e.g. Java) code, and to the typical LaTeX approach. You really appreciate the elegance of HTML+CSS once you had the misfortune of having to do a simple fucking table in LaTeX.


I dunno about that.

For simple stuff, sure HTML and CSS is great, but when I want something print-perfect I use LaTeX.

A simple table in LaTeX is no harder than in HTML, assuming the same level of knowledge in the tool.

But then when you throw in a simple requirement like "left margins on even pages and right margins on odd pages need to be larger", HTML becomes hell to work in.

HTML and CSS, even with a media query for print, sucks.


I think in the long term, HTML/CSS will win out once there's better support for CSS Paged Module Level 3, and you'll be able to achieve that requirement with just

    @page :left {
        margin-left: 20mm;
        margin-right: 10mm;
    }
    
    @page :right {
        margin-left: 10mm;
        margin-right: 20mm;
    }

instead of needing to install/import different LaTeX packages. I think for most of my current use-cases level 2 has been sufficient but I can see if I can include Paged.js polyfill support by default so there's more support for customizability on that front.


@Page { size: A4; margin: 20mm 10mm 10mm 25mm; } Do my print specifics (hidden-print class etc), everyone can optimize it for his local layout, every browser supports "print to pdf", done.


TeX at this point has entered computing legend. It has such a long and storied life.

But it’s old. We need something modern, that represents current ways to make documents from code. And that way is CSS. I bet within my lifetime most scientific publications will move to a PDF tool that ingests CSS. We just need to find something open-source and clean that has no missing functionality.


What about https://typst.app ?


I designed some worksheets in Typst and it is the best experience I've had with a typesetting system, hands down. It's not for everything but its defaults are good and very simple.


Is it open source ?



> But it’s old. We need something modern, that represents current ways to make documents from code.

I'd love something newer than TeX/LaTeX. Something with consistency (is it \$CMD{...}, \begin{$CMD}...\end{$CMD} or \{$CMD ...}?), better error messages, more specific and targeted warnings (most hbox-full warnings can be ignored, but many can't!), support for specifying `-Werror` (like gcc) and other things like that.

> I bet within my lifetime most scientific publications will move to a PDF tool that ingests CSS.

Maybe[1]. CSS and HTML needs a lot more functionality though. They have no page counter, no chapter counter, section counters, etc. No river detection, run detection, orphan detection, etc. No automatic reference manager[2], no automatic referencing of chapters, sections, tables, figures, etc. Missing correct hyphenation breakpoints.

Additionally, some things are there, but in a poor (for typesetting) way - inter-paragraph spacing must be faked (no, `:after` isn't a good way to specify `inter` spacing), no way to prevent what should be an atomic element (say ... an mbox containing a paragraph and an image) being broken across pages, no way to float an element to the next point in the document where it will fit (LaTeX does this by default, and it annoyed me no end when I could not find a way to get HTML documents to stop breaking my pretty short table across a page, and instead just place it on the next page).

Another thing that I think are a poor fit, but others think are superior, are the scripting facilities for creating new commands: doing `\newcommand or \newenvironment` is a lot less friction than doing an entire custom element. It's so little friction, that for an invoice I can simply do `\newcommand{\client}{\textbf\emph{The Client PTY LTD}}` and then use `\client` everywhere in the document.

I'm looking forward to a new LaTeX/TeX that fixes all those things. Maybe CSS+HTML would eventually get them, but many of those things are table stakes for typesetting, and yet they are not even on the horizon (or roadmap) for CSS+HTML.

[1] Could be I'm wrong. Like I said in another response, I'm no expert in CSS or HTML. [1] This can be easily resolved with a custom web component

> And that way is CSS. I bet within my lifetime most scientific publications will move to a PDF tool that ingests CSS. We just need to find something open-source and clean that has no missing functionality.


> Could be I'm wrong. Like I said in another response, I'm no expert in CSS or HTML.

Looks like it. I'm pretty sure most of the things you mentioned are either already possible or in the paged media spec / covered by paged.js.


In CSS you can directly target even or odd or some other arithmetic sequence.

    :nth-of-type(2n+1)


I'm not an expert in CSS, but I don't know how I can use that to refer to pages.

I mean, I'm not creating pages with `<page>...</page>`.



Once I had the chance to move away from Word, TeX was the first place I went. That said, I eventually tired of the obtuse error messages and felt I was making things more complicated for no real gain.

Even keeping a BasicTex environment working requires effort that HTML does not.


> That said, I eventually tired of the obtuse error messages and felt I was making things more complicated for no real gain.

The error messages are pretty poor.

> Even keeping a BasicTex environment working requires effort that HTML does not.

I've been told, by Mac and Winodws users, that it's a pain.

Personally I've never had to download extra packages/styles directly on Debian. Performing `apt-get install tex-<whatever>` normally installs everything (where `<whatever>` is something I find from a search in synaptic).


I solved the issue by installing manually, but even that is a pain with TeX Live - some of the directory tree needed to be created before BasicTex was aware of the packages I was using.


Support is getting better, there is also a poly fill of sorts https://pagedjs.org


Some people might be interested in https://weasyprint.org/


Interesting, I'm looking for a solution to render PDFs at the moment, it looks like that one actually does not use chromium, unlike most tools that I've seen that render HTML to PDFs. What's the advantage? Is it more lightweight / faster / reliable?


We actually ran off of WeasyPrint at first but switched to Chromium due to emojis not rendering properly, poor flexbox support, no custom fonts, and other differences between the HTML you'd see in a browser vs. the generated PDF.

WeasyPrint implements its own rendering engine and might support some specific @page properties that Chromium does not but given the complexity of CSS and web browsers, you're generally better off sticking with Chromium due to its history.

Also – an added benefit is that we can use JS libraries like FontAwesome, Bootstrap, KaTeX, etc. which is where other HTML to PDF libraries fall flat.


Flexbox support has been [included][1] since 2018, although my use case was the prototypical one - a single row w/ 3 columns - so YMMV with how it handles more complex layouts.

[1]: https://github.com/Kozea/WeasyPrint/pull/579


In addition, so far I know, the @page "locations" (e.g, @top-center, etc.) are not well supported yet in all browsers which means the flexbox fallback is probably as close as we're going to get.

https://www.quackit.com/css/at-rules/css_top-center_at-rule....


Depending on your needs, Typst might be what you are looking for.

[1] https://github.com/typst/typst


wkhtmltopdf[1] uses the QT WebKit renderer. I used it as part of my job hut work-flow with pandoc to get pdf resumes from markdown. It got me a job, so there's that.

[1] https://wkhtmltopdf.org/


I used the same [0], however wkhtmltopdf stopped working correctly at some point, so I am stuck printing the pdf manually with chrome at the moment. Probably an update that broke some stuff.

[0] https://blog.horaceg.xyz/posts/resume/


agree with the other comment - I made my resume in HTML / CSS, and the most reliable way to generate a PDF is just Chrome's print to PDF. I tried weasyprint and wkhtmltopdf and they either dropped elements or changed the layout.


We're using weasyprint to generate pdf files from data of our websites. It works great, made huge progress those past few years.


Your terms of service appear to be bogus:

> You acknowledge that the Website is a general-purpose search engine and tool. Specifically, but without limitation, the Website allows you to search multiple websites for music. Moreover, the Website is a general-purpose tool that allows you to convert audio files from videos and audio from elsewhere on the Internet. The Website may only be used in accordance with law. We do not encourage, condone, induce or allow any use of the Website that may be in violation of any law.


Nice catch, I copy/pasted that from a previous project and forgot to remove - should be fixed now.

TOS is pretty general and just there for legal reasons, tl;dr feel free to use as you see fit as long as it's not for anything illegal.


Trying to login with google I get this error:

> htmldocs.com has not completed the Google verification process. The app is currently being tested, and can only be accessed by developer-approved testers. If you think you should have access, contact the developer.


I have been building a custom PDF generator for my Remarkable tablet using jsPDF. Something that has surprised me is how hard it is to keep the file size small with tools like this.

Its fun and fast to generate things but when you get to 1000+ pages for something like a year long planner the document can quickly balloon past 70 MB.

So far I have kept my 750-1300 page planner between 3-7 MB.

I will give this a try and compare.


Please report back and let us know!


733 pages with the same cover image but without any calendaring line art comes in at 2049 KB. Opening that PDF back up in Chrome and using print "save as pdf" results in 1760 KB so there is some compression happening the second time around.

Overall this looks very promising!


I would think that a PDF file of 700 blank pages could exceed 2 MiB.


Been using https://github.com/diegomura/react-pdf for this purpose for years

Uses React Native like components and styling.

WYSIWYG: https://react-pdf.org/repl


@kelvinzhang

Quite frankly, htmldocs is the exact project i'm looking for months. I'm tired of word and same alternative and wanted something i can write html and css3 to convert to PDF.

You do and in a beautiful way !

Some question : i just want to use your product be also need to be sure my doc will by avaivable in futur. what's your plan ?

- opensource ? - community/enterprise ? - close source but a docker version to go on premise ?

Thanks for you answer and by the work very good works !


The long term goal of this project is to make HTML/CSS the defacto way of typesetting PDF documents. I’ll definitely keep it running for as long as I can.

The web version is just the initial step, and will likely open source for people who want to self-host and to increase adoption. For pricing, will probably adopt a model similar to Overleaf where it’s free for most users and maybe charge for team collaboration or have an enterprise license.


If you do opensource it, happy to help maintain it. This product would be helpful for my (fledgling) company, but would need to be self-hosted (use case is esignatures)


How does this compare to Typst?[1]

What I like about Typst is that I can use it completely offline and with my editor of choice. Is this planned for htmldocs too?

[1] https://typst.app/


Offline isn’t a priority at the moment but can be done in the future by packaging with Electron.

Typst is great but there are a few key differences:

- full CSS support, allowing for more customizability and familiar styling without a learning curve

- less tailored towards academic use-cases are more towards personal/business use-cases like resumes, invoices, reports. Also adding a template gallery in the near future.

- has a templating engine and API baked in

- can use JS packages and ecosystem (ex. icon sets, fonts, etc.)


Great project and great work!

I had a similar itch to scratch and I found quarto (https://quarto.org/) - free, open-source and doesn’t depend on chrome (admittedly it has other dependencies, but at least not chrome).


quarto is just using pandoc behind the scenes


You use the word documents on the site, but you don't make it clear that it is for making pdfs. I thought that this was just an html/css webpage editor.

"Typeset and Generate PDFs with HTML/CSS"

really should be the H1 on that page for clarity.


This is a great suggestion and I feel dumb for not thinking of this earlier. Thanks!


Typesetting for print from HTML is one of those things that both keeps popping up but also never really seems to take off. Prince still remains the main player and as proprietary as ever.

2005: https://alistapart.com/article/boom/

2015: https://www.smashingmagazine.com/2015/01/designing-for-print...

Today, this.


I've used flying saucer pdf[1] for this in the past, but the missing piece always seems to be a descent WYSIWYG template editor. Either open source or paid.

Any suggestions on a web solution that allows non-devs to make great templates would be appreciated.

Historically I've built something simple with Tiny and added a preview button to render, but that super clunky.

[1] https://github.com/flyingsaucerproject/flyingsaucer


My firm is currently in the process of creating a similar product that features a sophisticated visual page editor. While it's not officially launched yet, the product is about 95% complete. At the moment, we are on the lookout for early adopters.

For those interested in giving it a try, please contact us at support at cx-reports dot com. We are providing complimentary licenses to users who are eager to collaborate with us during this phase.

Screenshot: https://pasteboard.co/th5f4s0uVWJH.png


Oh wow. I started Flying Saucer 20 years ago. I’m amazed it’s still in use.


It does the job very nicely, and I can easily embed on-the-fly generated images. Not sure there is a better option in the Java ecosystem.

Thanks for your long lived contribution.


This might be great, and it might not. It's hard to tell as a lot of the documentation is missing, or has broken links. It would be really nice if the docs were more complete, and didn't require a sign-up to kick the types. Is it fundamentally better than, say Apache FOP? Multi-page tables with overflow/keep together control is hard. Does this do it better? I can't tell as all the templates seem to be single page.


Oh, is this like a paid version of pandoc?


You can probably get away with Pandoc depending on your use-case, this is primarily built for:

- having a web editor interface without needing to re-run a CLI command

- people who don't want to deal with packages/dependencies on their own system

- users that just want an affordable and easy-to-use API to generate PDF documents instead of having to set up their own server <> task queue <> worker system which would usually cost more

- in the future, teams that want to collaborate together on a document


This looks awesome, congratulations.

I think you’re onto something here.

I work on an OSS reporting and analytics tool (https://github.com/evidence-dev/evidence) and the amount of time and effort that goes into a really good “print pdf”, and how valuable people find it, has been one of the more surprising parts of the project to me.


What is the pricing like, e.g., per-template created, per-PDF rendered, or per-API call? I don't see any pricing info on the public site.


Pricing info is in a modal under the user dropdown, it's currently based on a monthly credit system. If there's another pricing model you'd prefer, let me know!


My feedback is that I was ready to move on after I searched for pricing, and it appears that it's not shown anywhere unless I sign up. I'll give it a try because it looks interesting and I'm looking for something similar.


It’s a good idea. You’ll want to support GitHub flavoured markdown as an input, if you don’t already. Be sure to allow an inline <style> so documents can still be customised using code.

I’d also like to have a mode — the default? — where all rendering was being done locally. There are documents I write that just can’t be stored on a third party computer.

Overleaf, to some extent, has shown the appeal for letting people focus on writing 100% of the time and running software 0% of the time. I’d prefer to use your tool though to write a quick letter to go in a parcel as a packing slip.

By the way: on mobile, your animated headline causes the page to jump up and down.


Weasyprint has a bunch of options to do almost anything you can think of, but in my case, it's just a generator.

To your point that htmldocs supports more modern CSS features, I can see the advantage. Although the most complicated things I needed - aside from @page rules - were a replacement for a 2nd page header (solved w/ Flexbox) and automatic page breaks that would display correctly (a few lines of CSS processed w/ Weasyprint came out better and didn't require me to print to PDF manually.)


Hi @kelvinzhang, the burger menu does not work on firefox for android


Same for me. I get a blue focus ring, but no menu.


Does not work in FF on iOS either (WebKit)


Fixed! Sorry about that


Maybe it’s because I come from the printing world of catalogs, magazines, and books printed on web offset printers but typeset implies a level of control and precision that I’ve never seen with HTML/CSS. When I had to build a backend to generate print ready PDF files being printed on pre-printed invoice stock, it was ReportLab all the way. I needed pixel level accuracy and control.


Nice Idea, looking forward to using its API in my application.

I've used https://github.com/xpublisher/weasyprint-rest for a many years but now planning to switch from it as it's archived by the maintainer.

All the best for the future of htmldocs.


I have used Gotenberg [1] in a production environment. Dockerized in a Kubernetes Cluster. It just works! I can absolutely recommend it. Uses Chromium under the hood and was able to render gradients and text shadow, nice! [1] https://gotenberg.dev/


Awesome idea, been looking for something like this every now and then, esp right now.

But

could use some performance improvements...

Maybe you tested this on your state of the art workstation but my i7 8th gen is getting choked to death...

EDIT:

It doesn't seem to work: I picked the resume template and set the margin and padding on `li` to 0 but nothing changed in the output.


I think it should be on the <ul> tag. See https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_li...


Great stuff! Yes, please open source it.


It seems to be a cool project, any differences from Vivliostyle[0]? It looks like they have one thing in common: typesetting using HTML+CSS.

[0]: https://vivliostyle.org/


This looks well implemented. I will play with it some. I have a couple projects that rely on html interface to pdf output (or at least print > save to PDF reliability). I would love to be able to remove the management of internal dependencies.


Please open source it!! I've looked for a solution like this multiple times. Well done!


There’s a similarly named html -> pdf tool called htmldoc:

https://www.msweet.org/htmldoc/

It’s crazy fast, but doesn’t handle Unicode well or have much support for CSS.


Had a similar scrapped idea a few years ago: https://benoror.github.io/laystack-landing/


The landing page after login resembles Gdoc but that's ok.

One small thing, when signing up with Gmail, it still asks for my Name and Surname when supposedly it's something you can get out of the OAuth APIs.


Does jsreport already cover the usecases listed?

https://playground.jsreport.net/


Would love to see an open-source version. Also, are you thinking of making a version that one could run locally with the command line?


Good luck with the project.

About 20 years ago, I did something along similar lines, except going the HTML-XML-XSL/FO-Apache FOP.

That was ... "fun".


Cool service! I like that it’s just HTML/CSS but the front end editor looks quite cool.

I also just open sourced part of my app that does PDF generation, but it’s completely bare bones.

I basically wanted a wrapper around the pdf generating part of chromium so that i could generate pdfs on pages within my own app.

Its here if anyone wants to check it out: https://github.com/awongh/bakso-doc


run headless chrome to render your web page to pdf


You pretty much spelled out the use case for XSL-FO.


[deleted]




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: