diff --git a/config/pdf/hugo.toml b/config/pdf/hugo.toml new file mode 100644 index 00000000000..b28f381a1b1 --- /dev/null +++ b/config/pdf/hugo.toml @@ -0,0 +1,59 @@ +[params] +output = "pdf" +print_title = "preCICE" +print_subtitle = "The coupling library for partitioned multi-physics simulations" + +[outputs] +home = ["PDFTitle", "PDFTOC", "PDFDocsPart", "PDFTutorialsPart", "PDFAppendixPart", "PrinceList"] +page = ["HTML"] +section = ["HTML"] + +[outputFormats.PDFTitle] +mediaType = "text/html" +baseName = "title" +path = "pdf" +isHTML = true +notAlternative = true + +[outputFormats.PDFTOC] +mediaType = "text/html" +baseName = "toc" +path = "pdf" +isHTML = true +notAlternative = true + +[outputFormats.PDFDocsPart] +mediaType = "text/html" +baseName = "docs-part" +path = "pdf" +isHTML = true +notAlternative = true + +[outputFormats.PDFTutorialsPart] +mediaType = "text/html" +baseName = "tutorials-part" +path = "pdf" +isHTML = true +notAlternative = true + +[outputFormats.PDFAppendixPart] +mediaType = "text/html" +baseName = "appendix-part" +path = "pdf" +isHTML = true +notAlternative = true + +[outputFormats.PrinceList] +mediaType = "text/plain" +baseName = "prince-list" +path = "pdf" +isPlainText = true +notAlternative = true + +[segments.pdf] + [[segments.pdf.includes]] + output = "{pdftitle,pdftoc,pdfdocspart,pdftutorialspart,pdfappendixpart,princelist}" + + [[segments.pdf.includes]] + output = "html" + path = "{/docs,/docs/**,/tutorials,/tutorials/**}" diff --git a/content/docs/adapters/overview.md b/content/docs/adapters/overview.md index d6b183c5aff..bb28e5dda31 100644 --- a/content/docs/adapters/overview.md +++ b/content/docs/adapters/overview.md @@ -15,6 +15,7 @@ There are various codes - free and proprietary ones - currently coupled with pre We host adapters for the following codes in the [preCICE GitHub organization](https://github.com/precice/) and we maintain them to work with the latest release of preCICE (unless stated otherwise). | Adapter for | Contact | Resources | Typical applications | Comments | +| --- | --- | --- | --- | --- | | [CalculiX](https://www.calculix.de/) | preCICE Developers | [code](https://github.com/precice/calculix-adapter), [docs](adapter-calculix-overview.html) | Structure part in CHT, FSI | | | [code_aster](https://code-aster.org/) | preCICE Developers | [code](https://github.com/precice/code_aster-adapter), [docs](adapter-code_aster.html) | Structure part in CHT | | | [deal.II](https://www.dealii.org/) | preCICE Developers | [code](https://github.com/precice/dealii-adapter), [docs](adapter-dealii-overview.html) | Structure part in FSI, any FEM | | @@ -32,6 +33,7 @@ The preCICE community has successfully coupled the following codes with preCICE Wherever meaningful (license, maturity of the project, no other home), we host the code repository. | Adapter for | Contact | Resources | Typical applications | Comments | +| --- | --- | --- | --- | --- | | [Alya](https://www.bsc.es/research-development/research-areas/engineering-simulations/alya-high-performance-computational) | [Benjamin Uekermann](https://github.com/uekerman) | | Fluid and structure part in FSI | Not actively maintained (but not abandoned) | | [Ansys Fluent](https://www.ansys.com/products/fluids/ansys-fluent) | preCICE Developers | [code](https://github.com/precice/fluent-adapter), [docs](https://github.com/precice/fluent-adapter/wiki) | Fluid part in FSI | Experimental | | [Ateles (APES)](https://apes-suite.org/ateles/) | [APES team](https://apes-suite.org/pages/impressum) | [code](https://github.com/apes-suite/ateles) | Fluid-Acousting, Fluid-Fluid coupling | | @@ -58,6 +60,7 @@ Wherever meaningful (license, maturity of the project, no other home), we host t These adapters and/or the respective solvers are not maintained and might not work anymore, but are listed here as an example of which other projects have used preCICE in the past. | Adapter for | Contact | Resources | Typical applications | Comments | +| --- | --- | --- | --- | --- | | [Carat++](https://www.cee.ed.tum.de/en/st/software/research/carat/) | [TUM Statik](https://www.cee.ed.tum.de/en/st/home/) | None | Structure part of FSI | | | [EFD](https://github.com/precice/efd) | [TUM SCCS](https://www.cs.cit.tum.de/en/sccs/home/) | [code](https://github.com/precice/efd) | Fluid part of FSI | | | [foam-extend](https://sourceforge.net/projects/foam-extend/) | [TU Delft Aerodynamics](https://www.tudelft.nl/index.php?id=4542&L=1) | [code](https://github.com/davidsblom/FOAM-FSI) | Fluid and structure part of FSI, Fluid-Fluid coupling | | diff --git a/content/docs/docs-meta/publish-to-pdf.md b/content/docs/docs-meta/publish-to-pdf.md index 0d78e8c2662..9e1e913cc51 100644 --- a/content/docs/docs-meta/publish-to-pdf.md +++ b/content/docs/docs-meta/publish-to-pdf.md @@ -1,189 +1,163 @@ --- title: Generate PDF Documentation permalink: docs-meta-publish-to-pdf.html +aliases: + - /docs-meta-publish-to-pdf.html keywords: pdf, publish to pdf, generate pdf -summary: +summary: "Build the complete documentation PDF with Hugo and Prince." --- ## Overview and tools needed -At the core of PDF generation process is [Prince](https://www.princexml.com/), which converts HTML/CSS (and even some JS) to print quality PDF with bookmarks, links, page numbers etc. Unfortunately there are no open-source alternatives that operate at the same level as Prince (yet) - however, Prince offers a [non-commercial license](https://www.princexml.com/purchase/license_faq/#non-commercial) that is perfectly suited for our use-case. As a requisite a water-mark is displayed on the first page of the PDF and we must place prominent links to the Prince website at the places we intend to serve the PDF. +The full-document PDF is generated by rendering the Hugo site and converting +the resulting HTML with [Prince](https://www.princexml.com/). Prince supports +print-specific CSS, bookmarks, cross-reference page numbers, links, and the +JavaScript needed for equation rendering. Its [non-commercial +license](https://www.princexml.com/purchase/license_faq/#non-commercial) is +sufficient for local and project use, but it adds a watermark to generated +documents. A license suitable for public distribution is required before +publishing an unwatermarked PDF. -[Download Prince](https://www.princexml.com/download/): The minimum version for MathJax 3 support is `20210624`, so get the [latest release](https://www.princexml.com/latest/). - -On a Windows environment it makes sense to add the location of the Prince executable, e.g. `C:\Program Files (x86)\Prince\engine\bin`, to the `PATH`. +Install Hugo Extended, Go, Python 3, `curl`, and Prince before running the +generator. The minimum Prince version for the MathJax compatibility script is +`20210624`; the latest Prince release is recommended. ## Build process -The bash script 'pdf-docs.sh' in root can be used to build the PDF. It goes through the following steps - -### Build a web target with jekyll +The repository-root `pdf-docs.sh` script performs the complete build directly +with Hugo. It performs four steps: -First, let's kill all running instances of jekyll: +1. Hugo renders the PDF outputs and selected documentation pages into a + temporary directory. +2. Hugo generates a Prince input list from the documentation, tutorials, and + appendix sidebars. +3. A temporary local HTTP server serves the rendered HTML and static assets. +4. Prince reads the input list and writes the final PDF. -```bash -kill -9 $(ps aux | grep '[j]ekyll' | awk '{print $2}') -``` +### Render the PDF target with Hugo -Then build the site locally with jekyll: +Run the script from the repository root: -```bash -bundle exec jekyll serve --detach --config _config.yml,pdfconfigs/config_docs_pdf.yml +```sh +./pdf-docs.sh ``` -The `--detach` option is not strictly necessary, it detaches jekyll from the terminal. For debugging reasons it might actually be preferable to use two separate shells in parallel. - -Note that in a Windows environment the `--detach` option will likely fail and that the `--config` option, which specifies a list of `config.yml`s to be used, needs to be enclosed in `"`: +Internally, the Hugo step is equivalent to: -```bash -bundle exec jekyll serve --config "_config.yml,pdfconfigs/config_docs_pdf.yml" +```sh +hugo --gc --minify --cleanDestinationDir \ + --environment pdf \ + --renderSegments pdf \ + --destination public-pdf \ + --baseURL http://127.0.0.1:4173/ ``` -At this point the site is up and can be accessed at `http://localhost:4000/`. - -In the directory `pdfconfigs` there is a file called `prince-list.txt` that looks like this: - -```liquid -{%raw%}{% for entry in sidebar %} - {% for folder in entry.folders %} - {% if folder.output contains "pdf" %} - {% for folderitem in folder.folderitems %} - {% if folderitem.output contains "pdf" %} - - {{folderitem.url}} - - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} - {% endfor %}{%endraw%} - ``` +The `pdf` environment is defined in `config/pdf/hugo.toml`. It adds the title +page, table of contents, part-title pages, and Prince input-list output. The +`pdf` segment limits normal HTML output to the documentation and tutorial +sections included in the PDF. -I.e. we loop through every item in the appropriate `sidebar.yml`, check whether `output` is `pdf`, and if so print the item's URI. As a result, after running jekyll, `prince-list.txt` contains a list of URIs for all items in `sidebar.yml`: +### Generate the Prince input list -```txt -http://localhost:4000/titlepage.html -http://localhost:4000/tocpage.html -http://localhost:4000/docs.html -[...] -``` +The list is generated at `public-pdf/pdf/prince-list.txt`; it must not be +edited manually. `layouts/partials/pdf/prince-list.txt` traverses the Hugo +sidebar data and includes only entries whose sidebar `output` contains `pdf`. +The current order is: -### Convert to PDF +1. title page; +2. table of contents; +3. documentation part page and documentation pages; +4. tutorials part page and tutorial pages; and +5. appendix part page and appendix pages. -This list is consumed by Prince and converted into PDF: +The generated list contains local absolute URLs, for example: -```bash -prince --javascript --raster-dpi=150 --input-list=_site/pdfconfigs/prince-list.txt -o pdf/docs.pdf +```text +http://127.0.0.1:4173/pdf/title.html +http://127.0.0.1:4173/pdf/toc.html +http://127.0.0.1:4173/docs/fundamentals/overview/ ``` -The final PDF can be found in `pdf/docs.pdf` as specified. The `--javascript` option enables JavaScript support. - -## Styling +`layouts/partials/pdf/page-for-url.html` resolves sidebar URLs and aliases to +the corresponding Hugo page, so renamed pages can still be included. -The web target built by +### Convert the rendered pages to PDF -```bash -bundle exec jekyll serve --config "_config.yml,pdfconfigs/config_docs_pdf.yml" -``` +After the temporary server is ready, the script invokes Prince with the +generated list: -is different from a usual build only in the way it specifies a second `config.yml` namely `pdfconfigs/config_docs_pdf.yml`. From a styling perspective the latter includes a different default layout of type `page_print`: - -```yml -defaults: - - - scope: - path: "" - type: "pages" - values: - layout: "page_print" - comments: true - search: true +```sh +prince --javascript \ + --input-list=public-pdf/pdf/prince-list.txt \ + -o pdf/docs.pdf ``` -This layout type includes a separate `
` in the form of `_includes/head_print.html`. Apart from some minor changes, e.g. by referencing resources such as stylesheets, scripts and fonts locally, it also points to `css/printstyles.css`. This is where styles specific to the PDF are stored. +The final document is written to `pdf/docs.pdf`. The server is stopped and its +temporary log is removed automatically when the script exits. -For further reference consult the [documentation of documentation-theme-jekyll](https://idratherbewriting.com/documentation-theme-jekyll/mydoc_generating_pdfs.html). +The output directory, output file, and local server port can be changed using +environment variables: -## Contents, title page and table of contents - -The PDF will contain every page of type `pdf` that is referenced in the sidebars configured in `pdfconfigs/config_docs_pdf.yml`. -You can configure a single sidebar via `pdf_sidebar` or multiple sidebars via `pdf_sidebars`. E.g. if - -```yml - -pdf_sidebars: - - docs_sidebar - - tutorials_sidebar +```sh +PDF_BUILD_DIR=/tmp/precice-pdf \ +PDF_OUTPUT=/tmp/precice-docs.pdf \ +PDF_PORT=4174 \ +./pdf-docs.sh ``` -and `docs_sidebar.yml` is - -```yml - - title: "A selection of fruits" - output: web, pdf - folderitems: - - - title: Apples - url: /apples.html - output: web, pdf - - - title: Oranges - url: /oranges.html - output: web -``` - -the PDF will contain `apples.html` but not `oranges.html`. - -Furthermore two more pages have to be included in `prince-list.txt`: +## Styling -```html -{{site.url}}{{site.baseurl}}/titlepage.html -{{site.url}}{{site.baseurl}}/tocpage.html -``` +When `params.output` is `pdf`, the base and content layouts use the print +markup instead of the normal navigation and sidebar wrappers. The print +templates and PDF-specific partials are in `layouts/partials/pdf/`, while +`layouts/partials/head_print.html` loads the local print resources. -These two pages are located in `pdfconfigs/` and govern the layout of the title page as well as the table of contents. +PDF-only styles are in `static/css/printstyles.css`. They define page headers +and footers, page counters, table-of-contents leaders, page breaks, image +limits, and print-friendly alert boxes. Do not edit minified vendor CSS for a +PDF-only adjustment; add a scoped rule to `printstyles.css` instead. -For further information, see the [Jekyll theme documentation](https://idratherbewriting.com/documentation-theme-jekyll/mydoc_generating_pdfs.html). +Prince compatibility scripts and print assets are served locally from +`static/js/`, `static/fonts/`, and `static/webfonts/`. Keeping these resources +in the generated site prevents the PDF build from depending on a browser or +on CDN availability. -## Troubleshooting and common issues +## Contents, title page, and table of contents -### Warnings by prince +The Hugo sidebars in `data/sidebars/` define the PDF contents. Add `pdf` to a +sidebar entry's `output` value when a page belongs in the document, for example +`output: web, pdf`. Entries without `pdf` remain available on the website but +are excluded from the PDF. The appendix uses +`data/sidebars/pdf_appendix_sidebar.yaml`. -Prince XML is different from a browser in the way it handles HTML/CSS more rigorously and will warn about every CSS property that are not 100% W3C compliant. Bootstrap, say, on the other hand, does make use of CSS hacks deliberately. +The title page, table of contents, and part-title pages are separate Hugo +outputs. The table of contents is built recursively from the sidebar folders, +preserving nested sections and the order defined in the data files. -Prince also consumes one page at a time and doesn't cache common resources (stylesheets, scripts, etc) like a browser. +## Troubleshooting -Due to these two points, taken together, Prince can output a long number of warnings in the conversion process. +### Prince warnings -### Make resources available locally +Prince validates CSS more strictly than a browser. Warnings about unsupported +Bootstrap properties, modern pseudo-classes, or browser-only media features +are expected when they do not affect the printed output. A missing resource, +failed URL, or non-zero Prince exit status requires investigation. -Because Prince consumes HTML pages one at a time, it is convenient to make resources (stylesheets, scripts, fonts etc.) available locally and not have them fetched from a CDN. For this purpose a separate `_includes/head_print.html` exists. +### Missing resources -The print head references the local Bootstrap stylesheet in `css/bootstrap.min.css`. Keep the matching `css/bootstrap.min.css.map` next to it, since the minified stylesheet references that source map. The regular web head may still load Bootstrap from a CDN, but the print head should stay self-contained so that PDF generation does not depend on network access. +Prince reads one URL at a time from the local server. Run the script rather +than opening generated HTML with a `file://` URL, and check that referenced +stylesheets, images, scripts, and fonts exist below `public-pdf/`. ### Missing glyphs or fonts -If Prince complains about missing glyphs or fonts make sure that the specified fonts are either available as resources (as a `*.ttf`, `*.woff` etc) or installed on the local machine. In our case, at the time of writing, this includes - -* Fira Sans Light, Regular, Medium, Bold, Italic (in `./fonts`) -* Fira Mono Regular (in `./fonts`) -* Font Awesome 6.7.2 (in `./webfonts`) -* KaTeX fonts (in `./css/fonts`) - -The location of these fonts has to be relative to where they are referenced, e.g. `css/fontawesome.6.7.2.all.min.css` mentions `url(../webfonts/fa-brands-400.woff2)`. - -For further information see the [Prince documentation on missing fonts](https://www.princexml.com/doc/troubleshooting/). - -### Troubleshooting - -A useful hack is to modify `prince-list.txt` to only contain reference to a single html page, that can then be easily troubleshooted. - -For further information see the [Prince documentation on troubleshooting](https://www.princexml.com/doc/troubleshooting/). - -### Overriding Bootstrap print styles - -Do not edit the minified Bootstrap vendor file directly. Bootstrap is vendored as `css/bootstrap.min.css` for PDF builds, and project-specific print overrides belong in `css/printstyles.css`. If a Bootstrap update changes PDF output, add the required scoped overrides there and replace `css/bootstrap.min.css` and `css/bootstrap.min.css.map` together. +If Prince reports missing glyphs, verify that the required Fira Sans, Fira +Mono, Font Awesome, and KaTeX resources are present in `static/fonts/`, +`static/webfonts/`, and `static/css/fonts/`. See the [Prince troubleshooting +documentation](https://www.princexml.com/doc/troubleshooting/) for details. -### KaTeX +### Debugging one page -We are using KaTeX for the rendering of LaTeX formulas in the documentation. In order for KaTeX to work with prince, a rendering script has been added in '_includes/head_print.html'. +To debug a specific page, copy its local URL into a temporary input list and +run Prince against that list. This avoids rebuilding the entire document while +investigating CSS, images, or equations. diff --git a/css/printstyles.css b/css/printstyles.css deleted file mode 100644 index dc5b4c9255e..00000000000 --- a/css/printstyles.css +++ /dev/null @@ -1,292 +0,0 @@ - -/*body.print .container {max-width: 650px;}*/ - -body { - font-size:12px; -} - -body.print .print-container, -body.print .print-content { - width: 100%; - max-width: none; - padding-left: 0; - padding-right: 0; -} - -body.print .print-content img { - display: block; - max-width: 100%; - max-height: 520pt; - width: auto; - height: auto; - margin-left: auto; - margin-right: auto; -} - -.nav ul li a {border-top:0px; background-color:transparent; color: #808080; } -#navig a[href] {color: #040606 !important;} -table .table {max-width:650px;} - -#navig li.sectionHead { - font-weight: bold; - font-size: 1.25em; - color: #040606 !important; -} -#navig li.subSectionHead span{ - font-weight: normal; - padding-left: 20px; - padding-top: 2px; - padding-bottom: 2px; - font-size: 0.8em; - color: #040606 !important; -} -#navig li { - font-weight: normal; -} - - - -#navig a[href]::after { content: leader(".") target-counter(attr(href), page); } - -a[href]::after { - content: " (page " target-counter(attr(href), page) ")" -} - -a[href^="http:"]::after, a[href^="https:"]::after, a[href^="ftp:"]::after { - content: ""; -} - -a[href] { - color: #0A76BB !important; -} -a[href*="mailto"]::after, a[data-bs-toggle="tooltip"]::after, a[href].noCrossRef::after, a[data-bs-toggle="tab"]::after { - content: ""; -} - - -@page { - /*margin: 60pt 90pt 60pt 90pt;*/ - margin: 30pt 45pt 30pt 45pt; - font-family: sans-serif; - font-style:none; - color: gray; -} - -.printTitle { - line-height:30pt; - font-size:27pt; - letter-spacing: -.5px; - margin-bottom:5px; - margin-top: 100px; - color: #040606; - font-weight: 500; -} - -.printSubtitle { - font-size: 19pt; - color: #333 !important; - line-height: 22pt; - letter-spacing: -.5px; - margin-bottom:100px; -} -.printTitleArea hr { - color: #999999 !important; - height: 2px; - width: 100%; -} - -.printTitleImage { - max-width:300px; - margin-bottom:100px; -} - -#printTitleLogo { - height: 84px; -} - -.printVersion { - font-size: 19pt; - color: #0A76BB; - line-height: 22pt; - letter-spacing: -.5px; - margin-bottom:20px; -} - -#navig { - /*page-break-before: always;*/ -} - -.copyrightBoilerplate { - page-break-before:always; - font-size:14px; -} - -.lastGeneratedDate { - font-style: italic; - font-size:14px; - color: gray; -} - -.alert a { - text-decoration: none !important; -} - - -body.title { page: title } - -@page title { - @top-left { - content: " "; - } - @top-right { - content: " " - } - @bottom-right { - content: " "; - } - @bottom-left { - content: " "; - } -} - -body.frontmatter { page: frontmatter } -body.frontmatter {counter-reset: page 1} - - -@page frontmatter { - @top-left { - content: "Table of Contents"; - font-size: 11px; - font-style: italic; - } - @top-right { - content: prince-script(guideName) " " prince-script(versionNumber); - font-size: 11px; - } - - @bottom-right { - content: "Page " counter(page); - font-size: 11px; - } - @bottom-left { - content: "Generated: " prince-script(datestamp); - font-size: 11px; - } -} - -body.first_page {counter-reset: page 1} - -h1 { string-set: doctitle content() } - -@page { - @top-left { - content: string(doctitle); - font-size: 11px; - font-style: italic; - } - @top-right { - content: prince-script(guideName) " " prince-script(versionNumber); - font-size: 11px; - } - - @bottom-right { - content: "Page " counter(page); - font-size: 11px; - } - @bottom-left { - content: "Generated: " prince-script(datestamp); - font-size: 11px; - } -} -.alert { - background-color: #fafafa !important; - border-color: #dedede !important; - color: black; -} - -pre { - background-color: #fafafa; -} - -/* Some fixes */ -pre { - font-size: 80%; -} -pre { - margin: 1em 0; - padding: .6em; -} -p { - margin-bottom: 0.5em; -} -blockquote { - font-size: 100%; - margin-bottom: 0.5em; -} -pre > code { - /*overflow: auto; - word-wrap: normal;*/ - /*white-space: normal;*/ - overflow-x: initial; - white-space: pre-wrap; - word-wrap: break-word; -} -.alert { - margin: 1em 0; - padding: .6em; -} -h1[id], h2[id], h3[id], h4[id], h5[id], h6[id], dt[id] { - padding-top: 1.5em; - margin-top: -1em; -} - -/* prepare nav tabs for printing */ -.nav > li.active > a, /* tab headers */ -.nav > li > a { - color: black; - background-color: white; - border: 1px solid #ccc; - border-radius: 4px 4px 0 0; -} -.tab-content > .tab-pane { - display: block !important; /* display non-active panes */ - position: relative; -} -div.tab-content div.tab-pane pre { - margin-top: 1em; -} -/* create counters to link tab headers to tab contents */ -.post-content ul.nav.nav-tabs { - counter-reset: tab_number; /* creates a new instance of counter with name tab_number */ -} -.post-content .nav.nav-tabs li::after { - counter-increment: tab_number; /* increment counter */ - content: counter(tab_number); /* display value in small bubble */ - position: absolute; - top: -1em; - left: -1em; - padding: 2px 5px; - background-color: white; - color: black; - font-size: 0.65em; - border-radius: 50%; - border: 1px solid #ccc; - box-shadow: 1px 1px 1px grey; -} -div.tab-content { - counter-reset: pane_number; -} -div.tab-pane::after { - counter-increment: pane_number; - content: counter(pane_number); - position: absolute; - top: -1em; - left: -1em; - padding: 2px 5px; - background-color: white; - color: black; - font-size: 0.65em; - border-radius: 50%; - border: 1px solid #ccc; - box-shadow: 1px 1px 1px gray; -} diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 6b6cb096961..911bc913d88 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -14,6 +14,18 @@{{- else }} +{{- if eq (site.Params.output | default "web") "pdf" }} +
+ {{ partial "head_print.html" . }} + +
+{{- else }}
{{ partial "head.html" . }} @@ -77,4 +89,5 @@
{{- end }} +{{- end }}