Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build_assets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
with:
name: nw-assets
path: |
novelwriter/assets/manual.pdf
novelwriter/assets/manual*.pdf
novelwriter/assets/sample.zip
novelwriter/assets/i18n/*.qm
if-no-files-found: error
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ See :ref:`a_started` for more details.
:hidden:

Main Page <self>
More Documents <https://novelwriter.io/about/docs.html>
More Documents <https://novelwriter.io/more/>

.. toctree::
:maxdepth: 1
Expand Down
9 changes: 5 additions & 4 deletions docs/source/tech_source.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ You can also build a PDF manual from the documentation using the ``pkgutils.py``

.. code-block:: bash

python pkgutils.py manual
python pkgutils.py docs-pdf en

This will build the documentation as a PDF using LaTeX. The file will then be copied into the
assets folder and made available in the **Help** menu in novelWriter. The Sphinx build system has a
few extra dependencies when building the PDF. Please check the `Sphinx Docs`_ for more details.
This will build the English documentation as a PDF using LaTeX. The file will then be copied into
the assets folder and made available in the **Help** menu in novelWriter. Replace ``en`` with
``all`` to build for all languages. The Sphinx build system has a few extra dependencies when
building the PDF. Please check the `Sphinx Docs`_ for more details.
3 changes: 2 additions & 1 deletion novelwriter/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,8 @@ def hasError(self) -> bool:

@property
def pdfDocs(self) -> Path | None:
return self._manuals.get(f"manual_{self.locale.name()}", self._manuals.get("manual"))
"""Return the local manual PDF file, if any exist."""
return self._manuals.get(f"manual_{self.locale.bcp47Name()}", self._manuals.get("manual"))

@property
def nwLangPath(self) -> Path:
Expand Down
34 changes: 18 additions & 16 deletions pkgutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import utils.build_binary
import utils.build_debian
import utils.build_windows
import utils.docs
import utils.icon_themes

from utils.common import ROOT_DIR, SETUP_DIR, extractVersion, readFile, stripVersion, writeFile
Expand Down Expand Up @@ -88,13 +89,13 @@ def cleanBuildDirs(args: argparse.Namespace) -> None:
print("")

folders = [
ROOT_DIR / "build",
ROOT_DIR / "build_bin",
ROOT_DIR / "dist",
ROOT_DIR / "build",
ROOT_DIR / "dist_appimage",
ROOT_DIR / "dist_bin",
ROOT_DIR / "dist_deb",
ROOT_DIR / "dist_minimal",
ROOT_DIR / "dist_appimage",
ROOT_DIR / "dist_doc",
ROOT_DIR / "dist",
ROOT_DIR / "novelWriter.egg-info",
]

Expand Down Expand Up @@ -211,20 +212,21 @@ def genMacOSPlist(args: argparse.Namespace) -> None:
)
)
cmdUpdateDocsPo.add_argument("lang", nargs="+")
cmdUpdateDocsPo.set_defaults(func=utils.assets.updateDocsTranslationSources)
cmdUpdateDocsPo.set_defaults(func=utils.docs.updateDocsTranslationSources)

# Build Docs i18n Files
cmdBuildU18nDocs = parsers.add_parser(
"docs-lrelease", help="Build the translated PDF manual files."
# Build PDF Docs
cmdBuildPdfDocs = parsers.add_parser(
"docs-pdf", help="Build the PDF manual files."
)
cmdBuildU18nDocs.add_argument("lang", nargs="+")
cmdBuildU18nDocs.set_defaults(func=utils.assets.buildDocsTranslationAssets)
cmdBuildPdfDocs.add_argument("lang", nargs="+")
cmdBuildPdfDocs.set_defaults(func=utils.docs.buildPdfDocAssets)

# Build Manual
cmdBuildManual = parsers.add_parser(
"manual", help="Build the help documentation as a PDF (requires LaTeX)."
# Build HTML Docs
cmdBuildHtmlDocs = parsers.add_parser(
"docs-html", help="Build the HTML docs."
)
cmdBuildManual.set_defaults(func=utils.assets.buildPdfManual)
cmdBuildHtmlDocs.add_argument("lang", nargs="+")
cmdBuildHtmlDocs.set_defaults(func=utils.docs.buildHtmlDocs)

# Build Sample
cmdBuildSample = parsers.add_parser(
Expand All @@ -234,13 +236,13 @@ def genMacOSPlist(args: argparse.Namespace) -> None:

# Clean Assets
cmdCleanAssets = parsers.add_parser(
"clean-assets", help="Delete assets built by manual, sample and qtlrelease."
"clean-assets", help="Delete assets built by docs-pdf, sample and qtlrelease."
)
cmdCleanAssets.set_defaults(func=utils.assets.cleanBuiltAssets)

# Build Assets
cmdBuildAssets = parsers.add_parser(
"build-assets", help="Build all assets. Includes manual, sample and qtlrelease."
"build-assets", help="Build all assets. Includes docs-pdf, sample and qtlrelease."
)
cmdBuildAssets.set_defaults(func=utils.assets.buildAllAssets)

Expand Down
132 changes: 5 additions & 127 deletions utils/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,59 +21,14 @@
from __future__ import annotations

import argparse
import os
import subprocess
import sys
import zipfile

from pathlib import Path

from utils.common import ROOT_DIR, writeFile


def buildPdfManual(args: argparse.Namespace | None = None) -> None:
"""This function will build the documentation as manual.pdf."""
print("")
print("Building PDF Manual")
print("===================")
print("")

buildFile = ROOT_DIR / "docs" / "build" / "latex" / "manual.pdf"
finalFile = ROOT_DIR / "novelwriter" / "assets" / "manual.pdf"
finalFile.unlink(missing_ok=True)

try:
subprocess.call(["make", "clean"], cwd="docs")
exCode = subprocess.call(["make", "latexpdf"], cwd="docs")
if exCode == 0:
print("")
buildFile.rename(finalFile)
else:
raise Exception(f"Build returned error code {exCode}")

print("PDF manual build: OK")
print("")

except Exception as exc:
print("PDF manual build: FAILED")
print("")
print(str(exc))
print("")
print("Dependencies:")
print(" * pip install sphinx")
print(" * Package latexmk")
print(" * LaTeX build system")
print("")
print(" On Debian/Ubuntu, install: python3-sphinx latexmk texlive texlive-latex-extra")
print("")
sys.exit(1)

if not finalFile.is_file():
print("No output file was found!")
print("")
sys.exit(1)

return
from utils.docs import buildPdfDocAssets


def buildSampleZip(args: argparse.Namespace | None = None) -> None:
Expand All @@ -90,7 +45,9 @@ def buildSampleZip(args: argparse.Namespace | None = None) -> None:

if srcSample.is_dir():
dstSample.unlink(missing_ok=True)
with zipfile.ZipFile(dstSample, "w") as zipObj:
with zipfile.ZipFile(
dstSample, mode="w", compression=zipfile.ZIP_DEFLATED, compresslevel=3
) as zipObj:
print("Compressing: nwProject.nwx")
zipObj.write(srcSample / "nwProject.nwx", "nwProject.nwx")
for doc in (srcSample / "content").iterdir():
Expand Down Expand Up @@ -249,84 +206,6 @@ def buildTranslationAssets(args: argparse.Namespace | None = None) -> None:
return


def updateDocsTranslationSources(args: argparse.Namespace) -> None:
"""Build the documentation .po files."""
print("")
print("Building Docs Translation Files")
print("===============================")
print("")

docsDir = ROOT_DIR / "docs"
locsDir = ROOT_DIR / "docs" / "source" / "locales"
locsDir.mkdir(exist_ok=True)

print("Generating POT Files")
subprocess.call(["make", "gettext"], cwd=docsDir)
print("")

lang = args.lang
update = []
if lang == ["all"]:
update = [i.stem for i in locsDir.iterdir() if i.is_dir()]
else:
update = lang

print("Generating PO Files")
print("Languages: ", update)
print("")

for code in update:
subprocess.call(["sphinx-intl", "update", "-p", "build/gettext", "-l", code], cwd=docsDir)
print("")

print("Done")
print("")

return


def buildDocsTranslationAssets(args: argparse.Namespace | None = None) -> None:
"""Build the documentation i18n PDF files."""
from PyQt6.QtCore import QLocale

print("")
print("Building Docs Manuals")
print("=====================")
print("")

docsDir = ROOT_DIR / "docs"
locsDir = ROOT_DIR / "docs" / "source" / "locales"
pdfFile = ROOT_DIR / "docs" / "build" / "latex" / "manual.pdf"
locsDir.mkdir(exist_ok=True)

lang = args.lang if args else ["all"]
build = []
if lang == ["all"]:
build = [i.stem for i in locsDir.iterdir() if i.is_dir()]
else:
build = lang

for code in build:
data = (locsDir / f"authors_{code}.conf").read_text(encoding="utf-8")
authors = [x for x in data.splitlines() if x and not x.startswith("#")]
env = os.environ.copy()
env["SPHINX_I18N_AUTHORS"] = ", ".join(authors)
exCode = subprocess.call(
f"make -e SPHINXOPTS=\"-D language='{code}'\" clean latexpdf",
cwd=docsDir, env=env, shell=True
)
if exCode == 0:
print("")
name = f"manual_{QLocale(code).name()}.pdf"
pdfFile.rename(ROOT_DIR / "novelwriter" / "assets" / name)
else:
raise Exception(f"Build returned error code {exCode}")

print("")

return


def cleanBuiltAssets(args: argparse.Namespace | None = None) -> None:
"""Remove assets built by this script."""
print("")
Expand All @@ -350,8 +229,7 @@ def cleanBuiltAssets(args: argparse.Namespace | None = None) -> None:
def buildAllAssets(args: argparse.Namespace) -> None:
"""Build all assets."""
cleanBuiltAssets()
buildPdfManual()
buildSampleZip()
buildTranslationAssets()
buildDocsTranslationAssets()
buildPdfDocAssets()
return
Loading