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/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/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 @@

Redirecting…

Click here if you are not redirected. {{- else }} +{{- if eq (site.Params.output | default "web") "pdf" }} + + {{ partial "head_print.html" . }} + + + + +{{- else }} {{ partial "head.html" . }} @@ -77,4 +89,5 @@

Redirecting…

{{- end }} +{{- end }} diff --git a/layouts/_default/default_print.html b/layouts/_default/default_print.html index 99cb5c3df5a..ff6360f6c26 100644 --- a/layouts/_default/default_print.html +++ b/layouts/_default/default_print.html @@ -6,7 +6,7 @@ diff --git a/layouts/_default/list.html b/layouts/_default/list.html index bb2fa24b893..b7e26757985 100644 --- a/layouts/_default/list.html +++ b/layouts/_default/list.html @@ -1,4 +1,17 @@ {{ define "main" }} +{{ if eq (site.Params.output | default "web") "pdf" }} +
+
+

{{ .Title }}

+
+ + {{ with .Params.summary }} +
{{ . | markdownify }}
+ {{ end }} + + {{ partial "compat_content.html" . }} +
+{{ else }}

{{ .Title }}

@@ -32,3 +45,4 @@

{{ .Title }}

{{ end }}
{{ end }} +{{ end }} diff --git a/layouts/_default/page.html b/layouts/_default/page.html index 05a74ee498c..2409a55a047 100644 --- a/layouts/_default/page.html +++ b/layouts/_default/page.html @@ -1,4 +1,17 @@ {{ define "main" }} +{{ if eq (site.Params.output | default "web") "pdf" }} +
+
+

{{ .Title }}

+
+ + {{ with .Params.summary }} +
{{ . | markdownify }}
+ {{ end }} + + {{ partial "compat_content.html" . }} +
+{{ else }}

{{ .Title }}

@@ -30,3 +43,4 @@

{{ .Title }}

{{ partial "breadcrumb.html" . }}
{{ end }} +{{ end }} diff --git a/layouts/_default/page_print.html b/layouts/_default/page_print.html index d2c37886714..f69e692f313 100644 --- a/layouts/_default/page_print.html +++ b/layouts/_default/page_print.html @@ -13,7 +13,7 @@

{{ . | markdownify }} {{ end }} - {{ .Content }} + {{ partial "compat_content.html" . }} diff --git a/layouts/_default/single.html b/layouts/_default/single.html index 05a74ee498c..2409a55a047 100644 --- a/layouts/_default/single.html +++ b/layouts/_default/single.html @@ -1,4 +1,17 @@ {{ define "main" }} +{{ if eq (site.Params.output | default "web") "pdf" }} +
+
+

{{ .Title }}

+
+ + {{ with .Params.summary }} +
{{ . | markdownify }}
+ {{ end }} + + {{ partial "compat_content.html" . }} +
+{{ else }}

{{ .Title }}

@@ -30,3 +43,4 @@

{{ .Title }}

{{ partial "breadcrumb.html" . }}
{{ end }} +{{ end }} diff --git a/layouts/index.pdfappendixpart.html b/layouts/index.pdfappendixpart.html new file mode 100644 index 00000000000..758d6df3b57 --- /dev/null +++ b/layouts/index.pdfappendixpart.html @@ -0,0 +1 @@ +{{ partial "pdf/appendix-part.html" . }} diff --git a/layouts/index.pdfdocspart.html b/layouts/index.pdfdocspart.html new file mode 100644 index 00000000000..f37042654a9 --- /dev/null +++ b/layouts/index.pdfdocspart.html @@ -0,0 +1 @@ +{{ partial "pdf/docs-part.html" . }} diff --git a/layouts/index.pdftitle.html b/layouts/index.pdftitle.html new file mode 100644 index 00000000000..294dbba61fe --- /dev/null +++ b/layouts/index.pdftitle.html @@ -0,0 +1 @@ +{{ partial "pdf/title.html" . }} diff --git a/layouts/index.pdftoc.html b/layouts/index.pdftoc.html new file mode 100644 index 00000000000..64f164e166e --- /dev/null +++ b/layouts/index.pdftoc.html @@ -0,0 +1 @@ +{{ partial "pdf/toc.html" . }} diff --git a/layouts/index.pdftutorialspart.html b/layouts/index.pdftutorialspart.html new file mode 100644 index 00000000000..c0eeb57c2a9 --- /dev/null +++ b/layouts/index.pdftutorialspart.html @@ -0,0 +1 @@ +{{ partial "pdf/tutorials-part.html" . }} diff --git a/layouts/index.princelist.txt b/layouts/index.princelist.txt new file mode 100644 index 00000000000..e832c680d4d --- /dev/null +++ b/layouts/index.princelist.txt @@ -0,0 +1 @@ +{{ partial "pdf/prince-list.txt" . }} diff --git a/layouts/partials/pdf/appendix-part.html b/layouts/partials/pdf/appendix-part.html new file mode 100644 index 00000000000..567c1673a83 --- /dev/null +++ b/layouts/partials/pdf/appendix-part.html @@ -0,0 +1 @@ +{{ partial "pdf/part-title.html" (dict "page" . "title" "Appendix") }} diff --git a/layouts/partials/pdf/docs-part.html b/layouts/partials/pdf/docs-part.html new file mode 100644 index 00000000000..2bf2b487e45 --- /dev/null +++ b/layouts/partials/pdf/docs-part.html @@ -0,0 +1 @@ +{{ partial "pdf/part-title.html" (dict "page" . "title" "Part I: Documentation") }} diff --git a/layouts/partials/pdf/page-for-url.html b/layouts/partials/pdf/page-for-url.html new file mode 100644 index 00000000000..d73f60d40ab --- /dev/null +++ b/layouts/partials/pdf/page-for-url.html @@ -0,0 +1,20 @@ +{{- $target := path.Clean .url -}} +{{- $resolvedPage := false -}} +{{- range .site.Pages -}} + {{- $page := . -}} + {{- if eq $target (path.Clean .RelPermalink) -}} + {{- $resolvedPage = . -}} + {{- end -}} + {{- range .Params.aliases -}} + {{- if eq $target (path.Clean .) -}} + {{- $resolvedPage = $page -}} + {{- end -}} + {{- end -}} + {{- range .Aliases -}} + {{- $alias := strings.TrimPrefix "/pdf" (path.Clean .) -}} + {{- if eq $target $alias -}} + {{- $resolvedPage = $page -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- return $resolvedPage -}} diff --git a/layouts/partials/pdf/part-title.html b/layouts/partials/pdf/part-title.html new file mode 100644 index 00000000000..d543cb9697c --- /dev/null +++ b/layouts/partials/pdf/part-title.html @@ -0,0 +1,15 @@ + + + + {{ partial "head_print.html" .page }} + + + + + diff --git a/layouts/partials/pdf/prince-list.txt b/layouts/partials/pdf/prince-list.txt new file mode 100644 index 00000000000..2c4db2238f5 --- /dev/null +++ b/layouts/partials/pdf/prince-list.txt @@ -0,0 +1,31 @@ +{{- $title := site.Home.OutputFormats.Get "pdftitle" -}} +{{- $toc := site.Home.OutputFormats.Get "pdftoc" -}} +{{- $docsPart := site.Home.OutputFormats.Get "pdfdocspart" -}} +{{- $tutorialsPart := site.Home.OutputFormats.Get "pdftutorialspart" -}} +{{- $appendixPart := site.Home.OutputFormats.Get "pdfappendixpart" -}} +{{ $title.Permalink }} +{{ $toc.Permalink }} +{{ $docsPart.Permalink }} +{{- range hugo.Data.sidebars.docs_sidebar.entries }} + {{- with .folders }} + {{- range partial "pdf/sidebar-urls.html" (dict "site" site "nodes" .) }} +{{ . }} + {{- end }} + {{- end }} +{{- end }} +{{ $tutorialsPart.Permalink }} +{{- range hugo.Data.sidebars.tutorial_sidebar.entries }} + {{- with .folders }} + {{- range partial "pdf/sidebar-urls.html" (dict "site" site "nodes" .) }} +{{ . }} + {{- end }} + {{- end }} +{{- end }} +{{ $appendixPart.Permalink }} +{{- range hugo.Data.sidebars.pdf_appendix_sidebar.entries }} + {{- with .folders }} + {{- range partial "pdf/sidebar-urls.html" (dict "site" site "nodes" .) }} +{{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/layouts/partials/pdf/sidebar-urls.html b/layouts/partials/pdf/sidebar-urls.html new file mode 100644 index 00000000000..13c674f953a --- /dev/null +++ b/layouts/partials/pdf/sidebar-urls.html @@ -0,0 +1,21 @@ +{{- $urls := slice -}} +{{- $site := .site -}} +{{- range .nodes -}} + {{- $node := . -}} + {{- $output := lower (printf "%v" ($node.output | default "")) -}} + {{- if in $output "pdf" -}} + {{- with $node.url -}} + {{- with partial "pdf/page-for-url.html" (dict "site" $site "url" .) -}} + {{- $urls = $urls | append .Permalink -}} + {{- end -}} + {{- end -}} + {{- range $key := slice "folders" "folderitems" "subfolders" "subfolderitems" -}} + {{- with index $node $key -}} + {{- range partial "pdf/sidebar-urls.html" (dict "site" $site "nodes" .) -}} + {{- $urls = $urls | append . -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- return $urls -}} diff --git a/layouts/partials/pdf/title.html b/layouts/partials/pdf/title.html new file mode 100644 index 00000000000..5426a16c884 --- /dev/null +++ b/layouts/partials/pdf/title.html @@ -0,0 +1,43 @@ + + + + {{ partial "head_print.html" . }} + + + + + diff --git a/layouts/partials/pdf/toc-nodes.html b/layouts/partials/pdf/toc-nodes.html new file mode 100644 index 00000000000..30694132a28 --- /dev/null +++ b/layouts/partials/pdf/toc-nodes.html @@ -0,0 +1,29 @@ +{{- $site := .site -}} +{{- $level := int (.level | default 0) -}} +{{- range .nodes -}} + {{- $node := . -}} + {{- $output := lower (printf "%v" ($node.output | default "")) -}} + {{- $type := lower (printf "%v" ($node.type | default "")) -}} + {{- $resolvedPage := false -}} + {{- with $node.url -}} + {{- $resolvedPage = partial "pdf/page-for-url.html" (dict "site" $site "url" .) -}} + {{- end -}} + {{- if and (in $output "pdf") (ne $type "frontmatter") (or (not $node.url) $resolvedPage) }} + + {{- with $resolvedPage -}} + {{ $node.title }} + {{- else -}} + {{- if eq $level 0 -}} + {{ $node.title }} + {{- else -}} + {{ $node.title }} + {{- end -}} + {{- end -}} + {{- range $key := slice "folders" "folderitems" "subfolders" "subfolderitems" -}} + {{- with index $node $key }} + + {{- end -}} + {{- end -}} + + {{- end -}} +{{- end -}} diff --git a/layouts/partials/pdf/toc.html b/layouts/partials/pdf/toc.html new file mode 100644 index 00000000000..bc4ef25587d --- /dev/null +++ b/layouts/partials/pdf/toc.html @@ -0,0 +1,30 @@ + + + + {{ partial "head_print.html" . }} + + + + + diff --git a/layouts/partials/pdf/tutorials-part.html b/layouts/partials/pdf/tutorials-part.html new file mode 100644 index 00000000000..630e8d5d19c --- /dev/null +++ b/layouts/partials/pdf/tutorials-part.html @@ -0,0 +1 @@ +{{ partial "pdf/part-title.html" (dict "page" . "title" "Part II: Tutorials") }} diff --git a/pdf-docs.sh b/pdf-docs.sh old mode 100644 new mode 100755 index a17c8bb5ae5..a92bb37ccab --- a/pdf-docs.sh +++ b/pdf-docs.sh @@ -1,17 +1,62 @@ #!/bin/sh -# Note that .sh scripts work only on Mac. If you're on Windows, install Git Bash and use that as your client. -echo 'Kill all Jekyll instances' -killall -9 jekyll -clear +set -eu -echo "Building PDF-friendly HTML site for Mydoc ..."; -bundle exec jekyll serve --detach --config _config.yml,pdfconfigs/config_docs_pdf.yml; -echo "done"; +pdf_port="${PDF_PORT:-4173}" +pdf_build_dir="${PDF_BUILD_DIR:-public-pdf}" +pdf_output="${PDF_OUTPUT:-pdf/docs.pdf}" +pdf_base_url="http://127.0.0.1:${pdf_port}/" +pdf_server_log=$(mktemp "${TMPDIR:-/tmp}/precice-pdf-server.XXXXXX") +pdf_server_pid="" -echo "Building the PDF ..."; -prince --javascript --raster-images-res 150 --input-list=_site/pdfconfigs/prince-list.txt -o pdf/docs.pdf; -echo "Done. Look in the pdf directory to see if it printed successfully." +cleanup() { + if [ -n "${pdf_server_pid}" ]; then + kill "${pdf_server_pid}" 2>/dev/null || true + wait "${pdf_server_pid}" 2>/dev/null || true + fi + rm -f "${pdf_server_log}" +} +trap cleanup EXIT INT TERM -# bundle exec jekyll serve --config "_config.yml,pdfconfigs/config_docs_pdf.yml" -# prince --javascript --input-list=_site/pdfconfigs/prince-list.txt -o pdf/docs.pdf +for command in hugo prince python3 curl; do + if ! command -v "${command}" >/dev/null 2>&1; then + echo "Required command not found: ${command}" >&2 + exit 1 + fi +done + +hugo --gc --minify --cleanDestinationDir \ + --environment pdf \ + --renderSegments pdf \ + --destination "${pdf_build_dir}" \ + --baseURL "${pdf_base_url}" + +pdf_input_list="${pdf_build_dir}/pdf/prince-list.txt" +if [ ! -s "${pdf_input_list}" ]; then + echo "Hugo did not generate ${pdf_input_list}" >&2 + exit 1 +fi + +python3 -m http.server "${pdf_port}" \ + --bind 127.0.0.1 \ + --directory "${pdf_build_dir}" \ + >"${pdf_server_log}" 2>&1 & +pdf_server_pid=$! + +pdf_attempt=0 +until curl --fail --silent --output /dev/null "${pdf_base_url}pdf/title.html"; do + pdf_attempt=$((pdf_attempt + 1)) + if [ "${pdf_attempt}" -ge 20 ]; then + cat "${pdf_server_log}" >&2 + echo "Timed out waiting for the local PDF server." >&2 + exit 1 + fi + sleep 0.25 +done + +mkdir -p "$(dirname "${pdf_output}")" +prince --javascript \ + --input-list="${pdf_input_list}" \ + -o "${pdf_output}" + +echo "Generated ${pdf_output}" diff --git a/pdf/README.md b/pdf/README.md index 62edf072e20..6b8621e1e41 100644 --- a/pdf/README.md +++ b/pdf/README.md @@ -1 +1,4 @@ -This PDF document was generated using [Prince](http://www.princexml.com). +The PDFs in this directory are generated with [Prince](https://www.princexml.com/). + +Run `./pdf-docs.sh` from the repository root to build the Hugo documentation and +write the current PDF to `pdf/docs.pdf`. diff --git a/pdfconfigs/appendix_part_title.html b/pdfconfigs/appendix_part_title.html deleted file mode 100644 index 67980e7ef83..00000000000 --- a/pdfconfigs/appendix_part_title.html +++ /dev/null @@ -1,8 +0,0 @@ ---- -layout: page_print -permalink: appendix_part_title.html -search: exclude ---- -
-

Appendix

-
\ No newline at end of file diff --git a/pdfconfigs/config_docs_pdf.yml b/pdfconfigs/config_docs_pdf.yml deleted file mode 100644 index 7b905bf1e81..00000000000 --- a/pdfconfigs/config_docs_pdf.yml +++ /dev/null @@ -1,23 +0,0 @@ -destination: _site/ -url: "http://127.0.0.1:4000" -baseurl: "" -port: 4000 -output: pdf -product: docs -print_title: preCICE -print_subtitle: The coupling library for partitioned multi-physics simulations -defaults: - - - scope: - path: "" - type: "pages" - values: - layout: "page_print" - comments: true - search: true - - -pdf_sidebars: - - docs_sidebar - - tutorial_sidebar - - pdf_appendix_sidebar diff --git a/pdfconfigs/docs_part_title.html b/pdfconfigs/docs_part_title.html deleted file mode 100644 index 29f9cb41e13..00000000000 --- a/pdfconfigs/docs_part_title.html +++ /dev/null @@ -1,8 +0,0 @@ ---- -layout: page_print -permalink: docs_part_title.html -search: exclude ---- -
-

Part I: Documentation

-
\ No newline at end of file diff --git a/pdfconfigs/prince-list.txt b/pdfconfigs/prince-list.txt deleted file mode 100644 index cdd2b6a6252..00000000000 --- a/pdfconfigs/prince-list.txt +++ /dev/null @@ -1,80 +0,0 @@ ---- -layout: none -search: exclude ---- - - {% assign docs_sidebar = site.data.sidebars.docs_sidebar.entries %} - {% assign tutorial_sidebar = site.data.sidebars.tutorial_sidebar.entries %} - {% assign pdf_appendix_sidebar = site.data.sidebars.pdf_appendix_sidebar.entries %} - -{{site.url}}{{site.baseurl}}/titlepage.html -{{site.url}}{{site.baseurl}}/tocpage.html -{{site.url}}{{site.baseurl}}/docs_part_title.html - - {% for entry in docs_sidebar %} - {% for folder in entry.folders %} - {% if folder.output contains "pdf" %} - {% for folderitem in folder.folderitems %} - {% if folderitem.output contains "pdf" %} - {{site.url}}{{site.baseurl}}{{folderitem.url}} - {% for subfolders in folderitem.subfolders %} - {% if subfolders.output contains "pdf" %} - {% for subfolderitem in subfolders.subfolderitems %} - {% if subfolderitem.output contains "pdf" %} - {{site.url}}{{site.baseurl}}{{subfolderitem.url}} - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} - {% endfor %} - -{{site.url}}{{site.baseurl}}/tutorials_part_title.html - - {% for entry in tutorial_sidebar %} - {% for folder in entry.folders %} - {% if folder.output contains "pdf" %} - {% for folderitem in folder.folderitems %} - {% if folderitem.output contains "pdf" %} - {{site.url}}{{site.baseurl}}{{folderitem.url}} - {% for subfolders in folderitem.subfolders %} - {% if subfolders.output contains "pdf" %} - {% for subfolderitem in subfolders.subfolderitems %} - {% if subfolderitem.output contains "pdf" %} - {{site.url}}{{site.baseurl}}{{subfolderitem.url}} - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} - {% endfor %} - -{{site.url}}{{site.baseurl}}/appendix_part_title.html - - {% for entry in pdf_appendix_sidebar %} - {% for folder in entry.folders %} - {% if folder.output contains "pdf" %} - {% for folderitem in folder.folderitems %} - {% if folderitem.output contains "pdf" %} - {{site.url}}{{site.baseurl}}{{folderitem.url}} - {% for subfolders in folderitem.subfolders %} - {% if subfolders.output contains "pdf" %} - {% for subfolderitem in subfolders.subfolderitems %} - {% if subfolderitem.output contains "pdf" %} - {{site.url}}{{site.baseurl}}{{subfolderitem.url}} - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} - {% endif %} - {% endfor %} - {% endfor %} - \ No newline at end of file diff --git a/pdfconfigs/titlepage.html b/pdfconfigs/titlepage.html deleted file mode 100644 index 9002fbe1ed7..00000000000 --- a/pdfconfigs/titlepage.html +++ /dev/null @@ -1,32 +0,0 @@ ---- -type: title -search: exclude -permalink: titlepage.html ---- -
-
- - - -
-
{{site.print_subtitle}}
-
Documentation of preCICE v{{site.precice_version}}
-
Generated: {{ site.time | date: '%B %d, %Y' }}
-
- -
-

- This PDF document is a snapshot of the preCICE documentation hosted at precice.org as of {{ site.time | date: '%B %d, %Y' }}. The HTML/CSS version of the documentation is available on Github at - https://github.com/precice/precice.github.io and can also be built locally. - More snapshots are listed on https://precice.org/fundamentals-previous-versions.html. -

-

- This snapshot has been generated with a non-commercial license of Prince: https://www.princexml.com/. While we do our best to improve the quality of this PDF archive, some content is only meant for online use, or still needs typesetting adjustments. Find more details on how we generate this archive on https://precice.org/docs-meta-publish-to-pdf.html and help us improve it. -

-

- preCICE is free/open-source software. The core library is distributed under the GNU LGPL3 license. The code is publicly available and actively developed on GitHub. Further components of the preCICE ecosystem are distributed under different free/open-source licenses and maintained in separate repositories, following independent release cycles and versioning systems. - The documentation is licensed under the Creative Commons Attribution 4.0 International license. License information: https://precice.org/fundamentals-license.html. -

-
- -
diff --git a/pdfconfigs/tocpage.html b/pdfconfigs/tocpage.html deleted file mode 100644 index a5a36ffe78b..00000000000 --- a/pdfconfigs/tocpage.html +++ /dev/null @@ -1,112 +0,0 @@ ---- -type: frontmatter -search: exclude -permalink: tocpage.html ---- - - \ No newline at end of file diff --git a/pdfconfigs/tutorials_part_title.html b/pdfconfigs/tutorials_part_title.html deleted file mode 100644 index 0b015ac790c..00000000000 --- a/pdfconfigs/tutorials_part_title.html +++ /dev/null @@ -1,8 +0,0 @@ ---- -layout: page_print -permalink: tutorials_part_title.html -search: exclude ---- -
-

Part II: Tutorials

-
\ No newline at end of file diff --git a/css/printstyles.css b/static/css/printstyles.css similarity index 100% rename from css/printstyles.css rename to static/css/printstyles.css diff --git a/js/prince.es6.polyfill.min.js b/static/js/prince.es6.polyfill.min.js similarity index 100% rename from js/prince.es6.polyfill.min.js rename to static/js/prince.es6.polyfill.min.js diff --git a/js/prince.mathjax.compat.js b/static/js/prince.mathjax.compat.js similarity index 100% rename from js/prince.mathjax.compat.js rename to static/js/prince.mathjax.compat.js