Add internationalisation support for docs (#2224)
This commit is contained in:
@@ -21,7 +21,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Packages (pip)
|
- name: Install Packages (pip)
|
||||||
run: pip install -r docs/source/requirements.txt
|
run: pip install -r docs/requirements.txt
|
||||||
|
|
||||||
- name: Build Assets
|
- name: Build Assets
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
+2
-1
@@ -22,8 +22,9 @@ i18n/*.qph
|
|||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
/docs/build/
|
/docs/build/
|
||||||
|
/docs/source/locales/**/*.mo
|
||||||
/novelwriter/assets/help/
|
/novelwriter/assets/help/
|
||||||
/novelwriter/assets/manual.pdf
|
/novelwriter/assets/manual*.pdf
|
||||||
*.qch
|
*.qch
|
||||||
*.qhc
|
*.qhc
|
||||||
.~lock.*
|
.~lock.*
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
sphinx-book-theme
|
|
||||||
sphinx>=5.0
|
|
||||||
sphinx-favicon
|
|
||||||
sphinx-design
|
|
||||||
pygments>=2.7
|
|
||||||
docutils>=0.17.1
|
docutils>=0.17.1
|
||||||
|
pygments>=2.7
|
||||||
|
sphinx-book-theme
|
||||||
|
sphinx-design
|
||||||
|
sphinx-favicon
|
||||||
|
sphinx-intl
|
||||||
|
sphinx>=5.0
|
||||||
+10
-3
@@ -5,15 +5,20 @@ Documentation: http://www.sphinx-doc.org/en/master/config
|
|||||||
|
|
||||||
# -- Imports -----------------------------------------------------------------
|
# -- Imports -----------------------------------------------------------------
|
||||||
|
|
||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import datetime
|
|
||||||
|
|
||||||
# -- Project Information -----------------------------------------------------
|
# -- Project Information -----------------------------------------------------
|
||||||
|
|
||||||
project = "novelWriter"
|
project = "novelWriter"
|
||||||
copyright = f"{datetime.date.today().year}"
|
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(
|
initFile = os.path.join(
|
||||||
os.path.dirname(__file__), os.pardir, os.pardir,
|
os.path.dirname(__file__), os.pardir, os.pardir,
|
||||||
@@ -41,6 +46,8 @@ source_suffix = ".rst"
|
|||||||
master_doc = "index"
|
master_doc = "index"
|
||||||
today_fmt = "%A, %d %B %Y at %H:%M"
|
today_fmt = "%A, %d %B %Y at %H:%M"
|
||||||
language = "en"
|
language = "en"
|
||||||
|
locale_dirs = ["locales/"]
|
||||||
|
gettext_compact = False
|
||||||
exclude_patterns = []
|
exclude_patterns = []
|
||||||
|
|
||||||
# -- Options for HTML Output -------------------------------------------------
|
# -- Options for HTML Output -------------------------------------------------
|
||||||
@@ -80,5 +87,5 @@ latex_elements = {
|
|||||||
}
|
}
|
||||||
latex_logo = "_static/novelwriter-pdf.png"
|
latex_logo = "_static/novelwriter-pdf.png"
|
||||||
latex_documents = [(
|
latex_documents = [(
|
||||||
master_doc, "manual.tex", "User Guide", author, "manual"
|
master_doc, "manual.tex", None, author, "manual"
|
||||||
)]
|
)]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
######################
|
##########
|
||||||
novelWriter User Guide
|
User Guide
|
||||||
######################
|
##########
|
||||||
|
|
||||||
| **Release Version:** |release|
|
| **Release Version:** |release|
|
||||||
| **Updated:** |today|
|
| **Updated:** |today|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# French translation authors, one name per line
|
||||||
|
Karduin
|
||||||
@@ -138,7 +138,7 @@ packages from PyPi:
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. 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:
|
The documentation can then be built from the root folder in the source code by running:
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
+18
@@ -202,6 +202,24 @@ if __name__ == "__main__":
|
|||||||
)
|
)
|
||||||
cmdBuildQM.set_defaults(func=utils.assets.buildTranslationAssets)
|
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
|
# Build Manual
|
||||||
cmdBuildManual = parsers.add_parser(
|
cmdBuildManual = parsers.add_parser(
|
||||||
"manual", help="Build the help documentation as a PDF (requires LaTeX)."
|
"manual", help="Build the help documentation as a PDF (requires LaTeX)."
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ if [ ! -d $ENVPATH ]; then
|
|||||||
python3 -m venv $ENVPATH
|
python3 -m venv $ENVPATH
|
||||||
fi
|
fi
|
||||||
source $ENVPATH/bin/activate
|
source $ENVPATH/bin/activate
|
||||||
pip3 install -r docs/source/requirements.txt
|
pip3 install -r docs/requirements.txt
|
||||||
python3 pkgutils.py build-assets
|
python3 pkgutils.py build-assets
|
||||||
deactivate
|
deactivate
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ if [ ! -d $ENVPATH ]; then
|
|||||||
python3 -m venv $ENVPATH
|
python3 -m venv $ENVPATH
|
||||||
fi
|
fi
|
||||||
source $ENVPATH/bin/activate
|
source $ENVPATH/bin/activate
|
||||||
pip3 install -r docs/source/requirements.txt
|
pip3 install -r docs/requirements.txt
|
||||||
python3 pkgutils.py build-assets
|
python3 pkgutils.py build-assets
|
||||||
deactivate
|
deactivate
|
||||||
|
|
||||||
|
|||||||
@@ -21,12 +21,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from PyQt6.QtCore import QLocale
|
||||||
|
|
||||||
from utils.common import ROOT_DIR, writeFile
|
from utils.common import ROOT_DIR, writeFile
|
||||||
|
|
||||||
|
|
||||||
@@ -248,6 +251,82 @@ def buildTranslationAssets(args: argparse.Namespace | None = None) -> None:
|
|||||||
return
|
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:
|
def cleanBuiltAssets(args: argparse.Namespace | None = None) -> None:
|
||||||
"""Remove assets built by this script."""
|
"""Remove assets built by this script."""
|
||||||
print("")
|
print("")
|
||||||
|
|||||||
Reference in New Issue
Block a user