PostgreSQL implementation of HTMLDOC conversion software. It is a program that reads HTML and Markdown source files or web pages and generates corresponding EPUB, HTML, PostScript, or PDF files with an optional table of contents. ### Requirements - PostgreSQL with the `pgxs` build infrastructure (`pg_config` on `PATH`). - [HTMLDOC](https://www.msweet.org/htmldoc/) built and installed as a shared library (`libhtmldoc.so`), headers included. - The bundled [pg_whitelist](https://github.com/RekGRpth/pg_whitelist) git submodule (initialize it with `git submodule update --init`). ### Installation ```sh git clone --recurse-submodules https://github.com/RekGRpth/pg_htmldoc.git cd pg_htmldoc make make install ``` Then, in the target database: ```sql create extension pg_htmldoc; ``` Run the regression tests with `make installcheck` (requires a running server and superuser access). ### Use of the extension `pg_htmldoc` builds up a single in-memory document per session by queuing one or more files/URLs/HTML fragments with the `htmldoc_add*()` functions, then rendering everything queued so far -- and clearing it -- with `convert2pdf()`/`convert2ps()`. ```sql select htmldoc_addurl('https://github.com'); copy ( select convert2pdf() ) to '/var/lib/postgresql/htmldoc.pdf' WITH (FORMAT binary, HEADER false) ``` Multiple `add*` calls in a row are concatenated into one document: ```sql select htmldoc_addfile('/srv/reports/cover.html'); select htmldoc_addfile('/srv/reports/body.html'); select convert2pdf('/srv/reports/report.pdf'); ``` ### Functions | Function | Returns | Description | | --- | --- | --- | | `htmldoc_addfile(file text)` | `bool` | Queue a local file (HTML or Markdown), resolved relative to the server's working directory. | | `htmldoc_addurl(url text)` | `bool` | Queue a web page, fetched over `http://`/`https://`. | | `htmldoc_addhtml(html text)` | `bool` | Queue an in-memory HTML/Markdown fragment. Always requires superuser -- any local files or URLs referenced from its markup (`img`/`body`/`embed`) are resolved deep inside HTMLDOC's rendering pipeline, where there's no single file/URL `pg_htmldoc.whitelist` can check against. | | `convert2pdf()` / `convert2ps()` | `bytea` | Render everything queued so far as PDF/PostScript and return it directly. | | `convert2pdf(file text)` / `convert2ps(file text)` | `bool` | Render and write the result to `file` on the server instead of returning it. Always requires superuser, since it writes to the server's filesystem. | Every `add*` call requires its argument to be non-`NULL`, and every `convert2*` call requires a document to already be queued (via a prior `add*` call) -- both raise an error otherwise. A successful `convert2*` call clears the queued document, so it must be rebuilt with `add*` before the next `convert2*` call. ### Permissions | Caller | `htmldoc_addfile()` / `htmldoc_addurl()` | `htmldoc_addhtml()` | `convert2pdf()` / `convert2ps()` (bytea) | `convert2pdf(file)` / `convert2ps(file)` | | --- | --- | --- | --- | --- | | Superuser | Allowed (narrowed by `pg_htmldoc.whitelist` if set) | Allowed | Allowed | Allowed | | Non-superuser | Allowed only if `pg_htmldoc.whitelist` explicitly grants the specific file/URL | Denied | Allowed (no filesystem access involved) | Denied | `pg_htmldoc.whitelist` is a `PGC_SUSET` GUC -- settable only by a superuser, including via `ALTER ROLE ... SET`, so a role can never loosen its own scope with a plain `SET` -- holding a comma-separated list of `file://` and `http(s)://` prefixes: ```sql alter role reporting set pg_htmldoc.whitelist = 'file:///srv/reports/,https://example.com/'; ``` - For a superuser, a non-empty whitelist *narrows* access: only matching files/URLs are allowed. - For a non-superuser, a non-empty whitelist is their *sole* grant: only matching files/URLs are allowed, everything else is denied. - An empty/unset whitelist means unrestricted access for a superuser, but denies everything for a non-superuser. ### License [MIT](LICENSE)