Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add internationalisation support for docs #2224

Merged
merged 6 commits into from
Feb 3, 2025
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 @@ -21,7 +21,7 @@ jobs:
uses: actions/checkout@v4

- name: Install Packages (pip)
run: pip install -r docs/source/requirements.txt
run: pip install -r docs/requirements.txt

- name: Build Assets
run: |
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ i18n/*.qph

# Documentation
/docs/build/
/docs/source/locales/**/*.mo
/novelwriter/assets/help/
/novelwriter/assets/manual.pdf
/novelwriter/assets/manual*.pdf
*.qch
*.qhc
.~lock.*
Expand Down
9 changes: 5 additions & 4 deletions docs/source/requirements.txt → docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
docutils>=0.17.1
pygments>=2.7
sphinx-book-theme
sphinx>=5.0
sphinx-favicon
sphinx-design
pygments>=2.7
docutils>=0.17.1
sphinx-favicon
sphinx-intl
sphinx>=5.0
13 changes: 10 additions & 3 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@

# -- Imports -----------------------------------------------------------------

import datetime
import os
import time
import datetime

# -- Project Information -----------------------------------------------------

project = "novelWriter"
copyright = f"{datetime.date.today().year}"
author = "Veronica Berglyd Olsen"

tmp_authors = ["Veronica Berglyd Olsen"]
if additional := os.environ.get("SPHINX_I18N_AUTHORS"):
tmp_authors.extend(a.strip() for a in additional.split(","))

author = ", ".join(tmp_authors)

initFile = os.path.join(
os.path.dirname(__file__), os.pardir, os.pardir,
Expand Down Expand Up @@ -41,6 +46,8 @@
master_doc = "index"
today_fmt = "%A, %d %B %Y at %H:%M"
language = "en"
locale_dirs = ["locales/"]
gettext_compact = False
exclude_patterns = []

# -- Options for HTML Output -------------------------------------------------
Expand Down Expand Up @@ -80,5 +87,5 @@
}
latex_logo = "_static/novelwriter-pdf.png"
latex_documents = [(
master_doc, "manual.tex", "User Guide", author, "manual"
master_doc, "manual.tex", None, author, "manual"
)]
6 changes: 3 additions & 3 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
######################
novelWriter User Guide
######################
##########
User Guide
##########

| **Release Version:** |release|
| **Updated:** |today|
Expand Down
2 changes: 2 additions & 0 deletions docs/source/locales/authors_fr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# French translation authors, one name per line
Karduin
2 changes: 1 addition & 1 deletion docs/source/tech_source.rst
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ packages from PyPi:

.. code-block:: bash

pip install -r docs/source/requirements.txt
pip install -r docs/requirements.txt

The documentation can then be built from the root folder in the source code by running:

Expand Down
Binary file removed novelwriter/assets/manual_fr_FR.pdf
Binary file not shown.
18 changes: 18 additions & 0 deletions pkgutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,24 @@ def genMacOSPlist(args: argparse.Namespace) -> None:
)
cmdBuildQM.set_defaults(func=utils.assets.buildTranslationAssets)

# Update Docs i18n Sources
cmdUpdateDocsPo = parsers.add_parser(
"docs-lupdate", help=(
"Update translation files for internationalisation of the docs. "
"The langauges to be updated can be added as arguments, "
"or set to all to update all existing translations."
)
)
cmdUpdateDocsPo.add_argument("lang", nargs="+")
cmdUpdateDocsPo.set_defaults(func=utils.assets.updateDocsTranslationSources)

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

# Build Manual
cmdBuildManual = parsers.add_parser(
"manual", help="Build the help documentation as a PDF (requires LaTeX)."
Expand Down
2 changes: 1 addition & 1 deletion setup/make_pip.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ if [ ! -d $ENVPATH ]; then
python3 -m venv $ENVPATH
fi
source $ENVPATH/bin/activate
pip3 install -r docs/source/requirements.txt
pip3 install -r docs/requirements.txt
python3 pkgutils.py build-assets
deactivate

Expand Down
2 changes: 1 addition & 1 deletion setup/make_release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ if [ ! -d $ENVPATH ]; then
python3 -m venv $ENVPATH
fi
source $ENVPATH/bin/activate
pip3 install -r docs/source/requirements.txt
pip3 install -r docs/requirements.txt
python3 pkgutils.py build-assets
deactivate

Expand Down
79 changes: 79 additions & 0 deletions utils/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@
from __future__ import annotations

import argparse
import os
import subprocess
import sys
import zipfile

from pathlib import Path

from PyQt6.QtCore import QLocale

from utils.common import ROOT_DIR, writeFile


Expand Down Expand Up @@ -248,6 +251,82 @@ 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."""
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
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 Down