diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ccadd66a..f368b301 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -15,6 +15,15 @@ RUN apt-get update && apt-get install --no-install-recommends -y \ subversion=1.14.5-3 && \ rm -rf /var/lib/apt/lists/* +# Install LaTeX for PDF documentation generation +# texlive packages follow the TeX Live release cycle and are not pinned +RUN apt-get update && apt-get install --no-install-recommends -y \ + texlive-latex-recommended \ + texlive-fonts-recommended \ + texlive-latex-extra \ + latexmk && \ + rm -rf /var/lib/apt/lists/* + # Install ruby gem FPM for packaging RUN apt-get update && apt-get install --no-install-recommends -y \ ruby=1:3.3+b1 \ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 317c74cd..9e5a2a03 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,7 +44,10 @@ jobs: secrets: inherit docs: + needs: prep-release uses: ./.github/workflows/docs.yml permissions: - contents: read + contents: write secrets: inherit + with: + release_id: ${{ needs.prep-release.outputs.release_id }} diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 6bf32ba3..31cfa6c5 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -2,6 +2,11 @@ name: "Docs" on: workflow_call: + inputs: + release_id: + required: false + type: string + default: '' permissions: contents: read @@ -26,7 +31,6 @@ jobs: - name: Install documentation requirements run: | pip install .[docs] - pip install sphinx_design - name: Build docs run: "make -C doc html" @@ -50,7 +54,6 @@ jobs: - name: Install dependencies run: | pip install .[docs] - pip install sphinx_design - name: Build landing-page run: "make -C doc/landing-page html" @@ -63,3 +66,50 @@ jobs: external_repository: dfetch-org/dfetch-org.github.io publish_branch: main deploy_key: ${{ secrets.GH_DFETCH_ORG_DEPLOY }} + + pdf: + name: PDF Documentation + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 + with: + egress-policy: audit + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Setup Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: '3.13' + + - name: Install documentation requirements + run: | + pip install .[docs] + + - name: Install LaTeX + run: | + sudo apt-get install -y texlive-latex-recommended texlive-fonts-recommended \ + texlive-latex-extra latexmk + + - name: Build PDF + run: make -C doc latexpdf + + - name: Store PDF artifact + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: dfetch-pdf-documentation + path: doc/_build/latex/dfetch-*.pdf + + - name: Upload PDF to release + if: ${{ inputs.release_id }} + uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.5.0 + with: + tag_name: ${{ inputs.release_id }} + files: doc/_build/latex/dfetch-*.pdf + draft: true + preserve_order: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.plantwebrc b/.plantwebrc new file mode 100644 index 00000000..c5c01391 --- /dev/null +++ b/.plantwebrc @@ -0,0 +1 @@ +{"format": "png"} diff --git a/.readthedocs.yml b/.readthedocs.yml index 39519437..4d17f5f4 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -10,7 +10,7 @@ sphinx: configuration: doc/conf.py formats: - - epub + - pdf - htmlzip build: diff --git a/dfetch.code-workspace b/dfetch.code-workspace index 0a7e5eb5..bec7a18f 100644 --- a/dfetch.code-workspace +++ b/dfetch.code-workspace @@ -97,6 +97,30 @@ "panel": "shared" } }, + { + "label": "Build PDF Docs", + "type": "shell", + "linux": { + "command": "make" + }, + "windows": { + "command": "make.bat" + }, + "args": [ + "latexpdf" + ], + "options": { + "cwd": "${workspaceFolder}/doc" + }, + "group": { + "kind": "build", + "isDefault": false + }, + "presentation": { + "reveal": "always", + "panel": "shared" + } + }, { "label": "Build Landing page", "type": "shell", diff --git a/doc/_ext/sphinxcontrib_asciinema/asciinema.py b/doc/_ext/sphinxcontrib_asciinema/asciinema.py index 44dad260..be82899a 100644 --- a/doc/_ext/sphinxcontrib_asciinema/asciinema.py +++ b/doc/_ext/sphinxcontrib_asciinema/asciinema.py @@ -10,6 +10,8 @@ def copy_asset_files(app, exc): + if app.builder.format != "html": + return asset_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "_static") if exc is None: # build succeeded for file in os.listdir(asset_dir): @@ -83,7 +85,6 @@ def visit_html(self, node): def visit_unsupported(self, node): - logger.warning("asciinema: unsupported output format (node skipped)") raise nodes.SkipNode @@ -177,6 +178,7 @@ def to_b64(self, filename): _NODE_VISITORS = { "html": (visit_html, depart), + "epub": (visit_unsupported, None), "latex": (visit_unsupported, None), "man": (visit_unsupported, None), "texinfo": (visit_unsupported, None), diff --git a/doc/conf.py b/doc/conf.py index 9e43440b..e295ab66 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -80,7 +80,7 @@ # The short X.Y version. version = __version__ # The full version, including alpha/beta/rc tags. -release = "" +release = __version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -187,26 +187,70 @@ # -- Options for LaTeX output --------------------------------------------- +latex_logo = "images/dfetch_logo.png" + latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', + # Map Unicode check/cross marks used in alternatives.rst to pifont dingbats + # so pdflatex doesn't abort with "Unicode character not set up for use". + # Also configure fonts and colours to match the design system. + "preamble": r""" +\usepackage{newunicodechar} +\usepackage{pifont} +\newunicodechar{✔}{\ding{51}} +\newunicodechar{✘}{\ding{55}} +\usepackage{helvet} +\renewcommand*\familydefault{\sfdefault} +\usepackage[T1]{fontenc} +\usepackage{xcolor} +\definecolor{dfprimary}{HTML}{c2620a} +\definecolor{dfaccent}{HTML}{4e7fa0} +\definecolor{dftextmuted}{HTML}{78716c} +\definecolor{dfnearblack}{HTML}{1c1917} +""", + # Design-token colours for Sphinx's built-in LaTeX style hooks + "sphinxsetup": ( + "TitleColor={rgb}{0.761,0.384,0.039}," + "InnerLinkColor={rgb}{0.306,0.498,0.627}," + "OuterLinkColor={rgb}{0.306,0.498,0.627}," + "VerbatimColor={rgb}{0.996,0.973,0.941}," + "VerbatimBorderColor={rgb}{0.906,0.878,0.847}," + "noteBorderColor={rgb}{0.306,0.498,0.627}," + "warningBorderColor={rgb}{0.761,0.384,0.039}," + ), + # Custom title page with amber header bar, logo, and accent footer. + # \makeatletter/\makeatother are required to access \py@release (@ is a + # letter in LaTeX package code but not in regular document mode). + # \sphinxlogo is NOT used here because it has no size constraint; instead + # we include the logo directly with an explicit width to keep the page count + # at exactly one regardless of the image's natural resolution. + "maketitle": r""" +\makeatletter +\begin{titlepage} + \noindent{\color{dfprimary}\rule{\linewidth}{6pt}}\par + \vspace*{\fill} + \begin{center} + \includegraphics[width=0.35\linewidth]{dfetch_logo.png}\par + \vspace{1.2cm} + {\fontsize{40}{44}\selectfont\bfseries\color{dfprimary}Dfetch\par} + \vspace{0.3cm} + {\LARGE\color{dfnearblack}Documentation\par} + \vspace{0.6cm} + {\large\color{dftextmuted}\textit{vendor dependencies without the pain}\par} + \vspace{1.5cm} + {\large\color{dftextmuted}\py@release\par} + \end{center} + \vspace*{\fill} + \noindent{\color{dfaccent}\rule{\linewidth}{4pt}}\par +\end{titlepage} +\makeatother +""", } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, "dfetch.tex", "Dfetch Documentation", "Dfetch", "manual"), + (master_doc, f"dfetch-{__version__}.tex", "Dfetch Documentation", "Dfetch", "manual"), ] diff --git a/doc/howto/contributing.rst b/doc/howto/contributing.rst index 84456bfc..33520eca 100644 --- a/doc/howto/contributing.rst +++ b/doc/howto/contributing.rst @@ -26,10 +26,15 @@ Running in Github Codespaces Github codespaces make it possible to edit dfetch directly in the browser in a VSCode instance. All dependencies are pre-installed and makes it easy to get started. -|CodespacesLink|_ +.. raw:: html + + + Open in GitHub Codespaces + + +.. only:: not html -.. |CodespacesLink| image:: https://github.com/codespaces/badge.svg -.. _CodespacesLink: https://codespaces.new/dfetch-org/dfetch + `Open in GitHub Codespaces `_ .. tip::