Merge pull request #764 from vkbo/i18n_pip

I18n and PyPi
This commit is contained in:
Veronica Berglyd Olsen
2021-05-02 15:05:21 +02:00
committed by GitHub
15 changed files with 98 additions and 79 deletions
+4
View File
@@ -8,6 +8,10 @@
setup.iss setup.iss
novelwriter.desktop novelwriter.desktop
novelWriter.pyw novelWriter.pyw
# Translations
/nw/assets/i18n/*.qm
.qmake.stash
i18n/*.qm i18n/*.qm
i18n/*.qph i18n/*.qph
+4
View File
@@ -39,6 +39,10 @@ Contributions to this project are welcome. However, please read the
[Contributing Guide](https://github.com/vkbo/novelWriter/blob/main/CONTRIBUTING.md) before [Contributing Guide](https://github.com/vkbo/novelWriter/blob/main/CONTRIBUTING.md) before
submitting larger additions or changes. submitting larger additions or changes.
If you want to help translating novelWriter into another language, please see the
[README](https://github.com/vkbo/novelWriter/blob/main/i18n/README.md) in the `nw/assets/i18n`
folder.
## Key Features ## Key Features
Some key features of novelWriter are listed below. Consult the Some key features of novelWriter are listed below. Consult the
+32 -34
View File
@@ -1,58 +1,56 @@
# novelWriter Internationalisation # novelWriter Internationalisation
The `i18n` folder contains the internationalisation files for novelWriter. The `i18n` folder contains the translation files for the Qt5 GUI. There are two types of files
There are two types of files. The `nw_XX.ts` / `nw_XX.qm` files are for involved: the `nw_XX.ts` and the `nw_XX.qm` files. The `nw_XX.ts` files are located in the `i18n`
localisation of the main GUI, and the `project_XX.json` files are JSON files folder at the root of the repository, and the `nw_XX.qm` together with the `project_XX.json` files
with translation maps for the novelWriter projects, used by the Build Novel are located in `nw/assets/i18n`. The latter are JSON files translation maps for the novelWriter
Project tool. projects, used by the Build Novel Project tool.
## GUI Localisation ## Qt GUI Localisation
The `.qm` files are the actual files used by the application to translate the The `.qm` files are the actual files used by the application to translate the GUI into another
GUI into another language other than the default British English. The files are language other than the default British English. The files are not generated by default. They can
not generated by default. They can be built with: be built with:
```bash ```bash
python3 setup.py qtlrelease python3 setup.py qtlrelease
``` ```
To add a new translation file, first add a new entry in the `novelWriter.pro` To add a new translation file, first add a new entry in the `novelWriter.pro` file under the
file under the `TRANSLATIONS` variable. Please use the underscore syntax for `TRANSLATIONS` variable. Please use the underscore syntax for file names as the importer expects
file names as the importer expects this format. this format.
After adding the entry in the `.pro` file, run: After adding the entry in the `.pro` file, run:
```bash ```bash
python3 setup.py qtlupdate python3 setup.py qtlupdate
``` ```
This will build a new `nw_XX.ts` file for the language you just added. The file This will build a new `i18n/nw_XX.ts` file for the language you just added. The file can then be
can then be edited with the Qt 5 Linguist application provided by Qt. This is edited with the Qt 5 Linguist application provided by Qt. This is by far easier than manually
by far easier than manually editing the `.ts` file. Please select "English" and editing the `.ts` file. Please select "English" and "United Kingdom" as the source langauge when
"United Kingdom" as the source langauge when prompted by Qt 5 Linguist. prompted by Qt 5 Linguist.
When you're done editing, you can build the `nw_XX.qm` file and test it in When you're done editing, you can build the `nw/assets/i18n/nw_XX.qm` file and test it in
novelWriter. The Preferences dialog should list the newly added language, and novelWriter. The Preferences dialog should list the newly added language, and you can select it and
you can select it and test it. test it.
Please do not submit the `.qm` files to the repository. Only the `.ts` files Please do not submit the `.qm` files to the repository. Only the `.ts` files in the `i18n` folder
are needed. are needed.
**Note:** This requires that you have the tools Qt 5 Linguist and `pylupdate5` **Note:** This requires that you have the tools Qt 5 Linguist and the PyQt5 tool `pylupdate5`
installed on your system. installed on your system.
## Project Localisation ## Project Localisation
Projects can have a different language setting than the GUI itself. The files Projects can have a different language setting than the GUI itself. The files with format
with format `project_XX.json` are simple translation maps for text that goes `project_XX.json` in `nw/assets/i18n` are simple translation maps for text that goes into the
into the exported documents generated by the Build Novel Project tool. exported documents generated by the Build Novel Project tool.
The files are loaded based on the language setting on the build tool. At the The files are loaded based on the language setting in the build tool. At the present time, no other
present time, no other parts of the application use these files. Since these parts of the application use these files. Since these are used as replacement lookups, they are
are used as replacement lookups, they are maintained as plain JSON files. The maintained as plain JSON files. The main usage is to generate chapter headers as number words.
main usage is to generate chapter headers as number words.
There is no trick to using these files. Just copy the `project_en.json` file, Adding new translations for these files is easy. Just copy the `project_en.json` file, rename it to
rename it to the appropriate language coded filename, and edit it. Please use the appropriate language coded filename, and edit it. Please use the underscore as separator if a
the underscore as separator if a language needs to be localised to a specific language needs to be localised to a specific country under a language. The importer will for
country under a language. The importer will for instance look for `en_US` instance look for `en_US` first, then use `en` if it is not found. If there are no matching files,
first, then use `en` if it is not found. If there are no matching files, the the project falls back to using English.
project falls back to using English.
+6 -11
View File
@@ -757,22 +757,17 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="860"/> <location filename="../nw/tools/build.py" line="858"/>
<source>Save Document As</source> <source>Save Document As</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="998"/> <location filename="../nw/tools/build.py" line="1001"/>
<source>Unknown format</source>
<translation></translation>
</message>
<message>
<location filename="../nw/tools/build.py" line="1002"/>
<source>{0} file successfully written to:</source> <source>{0} file successfully written to:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1009"/> <location filename="../nw/tools/build.py" line="1008"/>
<source>Failed to write {0} file. {1}</source> <source>Failed to write {0} file. {1}</source>
<translation></translation> <translation></translation>
</message> </message>
@@ -780,17 +775,17 @@
<context> <context>
<name>GuiBuildNovelDocView</name> <name>GuiBuildNovelDocView</name>
<message> <message>
<location filename="../nw/tools/build.py" line="1209"/> <location filename="../nw/tools/build.py" line="1208"/>
<source>This area will show the content of the document to be exported or printed. Press the &quot;Build Preview&quot; button to generate content.</source> <source>This area will show the content of the document to be exported or printed. Press the &quot;Build Preview&quot; button to generate content.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1358"/> <location filename="../nw/tools/build.py" line="1357"/>
<source>Unknown</source> <source>Unknown</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1360"/> <location filename="../nw/tools/build.py" line="1359"/>
<source>&lt;b&gt;Build Time:&lt;/b&gt; {0}</source> <source>&lt;b&gt;Build Time:&lt;/b&gt; {0}</source>
<translation></translation> <translation></translation>
</message> </message>
+6 -11
View File
@@ -757,22 +757,17 @@
<translation>PDF</translation> <translation>PDF</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="860"/> <location filename="../nw/tools/build.py" line="858"/>
<source>Save Document As</source> <source>Save Document As</source>
<translation>Enregistrer le document sous</translation> <translation>Enregistrer le document sous</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="998"/> <location filename="../nw/tools/build.py" line="1001"/>
<source>Unknown format</source>
<translation>Format inconnu</translation>
</message>
<message>
<location filename="../nw/tools/build.py" line="1002"/>
<source>{0} file successfully written to:</source> <source>{0} file successfully written to:</source>
<translation>Fichier {0} écrit dans :</translation> <translation>Fichier {0} écrit dans :</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1009"/> <location filename="../nw/tools/build.py" line="1008"/>
<source>Failed to write {0} file. {1}</source> <source>Failed to write {0} file. {1}</source>
<translation>Erreur lors de l&apos;écriture du fichier {0}. {1}</translation> <translation>Erreur lors de l&apos;écriture du fichier {0}. {1}</translation>
</message> </message>
@@ -780,17 +775,17 @@
<context> <context>
<name>GuiBuildNovelDocView</name> <name>GuiBuildNovelDocView</name>
<message> <message>
<location filename="../nw/tools/build.py" line="1209"/> <location filename="../nw/tools/build.py" line="1208"/>
<source>This area will show the content of the document to be exported or printed. Press the &quot;Build Preview&quot; button to generate content.</source> <source>This area will show the content of the document to be exported or printed. Press the &quot;Build Preview&quot; button to generate content.</source>
<translation>Dans cette zone s&apos;affichera le contenu du document à exporter ou à imprimer. Utilisez le bouton &quot;Construire l&apos;aperçu&quot; pour générer le contenu.</translation> <translation>Dans cette zone s&apos;affichera le contenu du document à exporter ou à imprimer. Utilisez le bouton &quot;Construire l&apos;aperçu&quot; pour générer le contenu.</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1358"/> <location filename="../nw/tools/build.py" line="1357"/>
<source>Unknown</source> <source>Unknown</source>
<translation>Inconnu</translation> <translation>Inconnu</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1360"/> <location filename="../nw/tools/build.py" line="1359"/>
<source>&lt;b&gt;Build Time:&lt;/b&gt; {0}</source> <source>&lt;b&gt;Build Time:&lt;/b&gt; {0}</source>
<translation>&lt;b&gt;Durée de construction :&lt;/b&gt; {0}</translation> <translation>&lt;b&gt;Durée de construction :&lt;/b&gt; {0}</translation>
</message> </message>
+6 -11
View File
@@ -742,22 +742,17 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="860"/> <location filename="../nw/tools/build.py" line="858"/>
<source>Save Document As</source> <source>Save Document As</source>
<translation>Lagre dokumentet som</translation> <translation>Lagre dokumentet som</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="998"/> <location filename="../nw/tools/build.py" line="1001"/>
<source>Unknown format</source>
<translation>Ukjent format</translation>
</message>
<message>
<location filename="../nw/tools/build.py" line="1002"/>
<source>{0} file successfully written to:</source> <source>{0} file successfully written to:</source>
<translation>Lagring av {0} var vellykket, og filen ble skrevet til:</translation> <translation>Lagring av {0} var vellykket, og filen ble skrevet til:</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1009"/> <location filename="../nw/tools/build.py" line="1008"/>
<source>Failed to write {0} file. {1}</source> <source>Failed to write {0} file. {1}</source>
<translation>Misslykkes i å skrive {0} til. {1}</translation> <translation>Misslykkes i å skrive {0} til. {1}</translation>
</message> </message>
@@ -780,17 +775,17 @@
<context> <context>
<name>GuiBuildNovelDocView</name> <name>GuiBuildNovelDocView</name>
<message> <message>
<location filename="../nw/tools/build.py" line="1209"/> <location filename="../nw/tools/build.py" line="1208"/>
<source>This area will show the content of the document to be exported or printed. Press the &quot;Build Preview&quot; button to generate content.</source> <source>This area will show the content of the document to be exported or printed. Press the &quot;Build Preview&quot; button to generate content.</source>
<translation>Dette området vil vise innholdet av dokumentet som skal eksporteres. Trykk knappen merket med &quot;Lag forhåndsvisning&quot; for å oppdatere innholdet.</translation> <translation>Dette området vil vise innholdet av dokumentet som skal eksporteres. Trykk knappen merket med &quot;Lag forhåndsvisning&quot; for å oppdatere innholdet.</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1358"/> <location filename="../nw/tools/build.py" line="1357"/>
<source>Unknown</source> <source>Unknown</source>
<translation>Ukjent</translation> <translation>Ukjent</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1360"/> <location filename="../nw/tools/build.py" line="1359"/>
<source>&lt;b&gt;Build Time:&lt;/b&gt; {0}</source> <source>&lt;b&gt;Build Time:&lt;/b&gt; {0}</source>
<translation>&lt;b&gt;Generert den:&lt;/b&gt; {0}</translation> <translation>&lt;b&gt;Generert den:&lt;/b&gt; {0}</translation>
</message> </message>
+6 -11
View File
@@ -451,11 +451,6 @@
<source>Plain HTML</source> <source>Plain HTML</source>
<translation>HTML Simples</translation> <translation>HTML Simples</translation>
</message> </message>
<message>
<location filename="../nw/tools/build.py" line="998"/>
<source>Unknown format</source>
<translation>Formato desconhecido</translation>
</message>
<message> <message>
<location filename="../nw/tools/build.py" line="450"/> <location filename="../nw/tools/build.py" line="450"/>
<source>novelWriter HTML (.htm)</source> <source>novelWriter HTML (.htm)</source>
@@ -592,17 +587,17 @@
<translation>Fechar</translation> <translation>Fechar</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="860"/> <location filename="../nw/tools/build.py" line="858"/>
<source>Save Document As</source> <source>Save Document As</source>
<translation>Salvar Documento Como</translation> <translation>Salvar Documento Como</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1002"/> <location filename="../nw/tools/build.py" line="1001"/>
<source>{0} file successfully written to:</source> <source>{0} file successfully written to:</source>
<translation>Arquivo {0} escrito com sucesso para:</translation> <translation>Arquivo {0} escrito com sucesso para:</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1009"/> <location filename="../nw/tools/build.py" line="1008"/>
<source>Failed to write {0} file. {1}</source> <source>Failed to write {0} file. {1}</source>
<translation>Falhou para escrever o arquivo {0}. {1}</translation> <translation>Falhou para escrever o arquivo {0}. {1}</translation>
</message> </message>
@@ -780,17 +775,17 @@
<context> <context>
<name>GuiBuildNovelDocView</name> <name>GuiBuildNovelDocView</name>
<message> <message>
<location filename="../nw/tools/build.py" line="1358"/> <location filename="../nw/tools/build.py" line="1357"/>
<source>Unknown</source> <source>Unknown</source>
<translation>Desconhecido</translation> <translation>Desconhecido</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1209"/> <location filename="../nw/tools/build.py" line="1208"/>
<source>This area will show the content of the document to be exported or printed. Press the &quot;Build Preview&quot; button to generate content.</source> <source>This area will show the content of the document to be exported or printed. Press the &quot;Build Preview&quot; button to generate content.</source>
<translation>Esta área vai mostrar o conteúdo do documento a ser exportado ou impresso. Clique no botão &quot;Construir Prévia&quot; para gerar o conteúdo.</translation> <translation>Esta área vai mostrar o conteúdo do documento a ser exportado ou impresso. Clique no botão &quot;Construir Prévia&quot; para gerar o conteúdo.</translation>
</message> </message>
<message> <message>
<location filename="../nw/tools/build.py" line="1360"/> <location filename="../nw/tools/build.py" line="1359"/>
<source>&lt;b&gt;Build Time:&lt;/b&gt; {0}</source> <source>&lt;b&gt;Build Time:&lt;/b&gt; {0}</source>
<translation>&lt;b&gt;Tempo de Construção:&lt;/b&gt; {0}</translation> <translation>&lt;b&gt;Tempo de Construção:&lt;/b&gt; {0}</translation>
</message> </message>
+1 -1
View File
@@ -307,7 +307,7 @@ class Config:
self.appIcon = os.path.join(self.iconPath, "novelwriter.svg") self.appIcon = os.path.join(self.iconPath, "novelwriter.svg")
# Internationalisation # Internationalisation
self.nwLangPath = os.path.join(self.appRoot, "i18n") self.nwLangPath = os.path.join(self.assetPath, "i18n")
logger.verbose("App path: %s" % self.appPath) logger.verbose("App path: %s" % self.appPath)
logger.verbose("Last path: %s" % self.lastPath) logger.verbose("Last path: %s" % self.lastPath)
+33
View File
@@ -217,12 +217,36 @@ def buildQtDocs():
def buildQtI18n(): def buildQtI18n():
"""Build the lang.qm files for Qt Linguist. """Build the lang.qm files for Qt Linguist.
""" """
print("")
print("Building Qt Localisation Files")
print("==============================")
print("")
try: try:
subprocess.call(["lrelease", "-verbose", "novelWriter.pro"]) subprocess.call(["lrelease", "-verbose", "novelWriter.pro"])
except Exception as e: except Exception as e:
print("QtI18n Release Error:") print("QtI18n Release Error:")
print(str(e)) print(str(e))
print("")
print("Moving QM Files to Assets")
print("")
langDir = os.path.join("nw", "assets", "i18n")
for langFile in os.listdir("i18n"):
langPath = os.path.join("i18n", langFile)
if not os.path.isfile(langPath):
continue
if langFile.endswith(".qm"):
destPath = os.path.join(langDir, langFile)
os.rename(langPath, destPath)
print("Moved: %s -> %s" % (langPath, destPath))
print("")
return
## ##
# Qt Linguist TS Builder (qtlupdate) # Qt Linguist TS Builder (qtlupdate)
## ##
@@ -230,12 +254,21 @@ def buildQtI18n():
def buildQtI18nTS(): def buildQtI18nTS():
"""Build the lang.ts files for Qt Linguist. """Build the lang.ts files for Qt Linguist.
""" """
print("")
print("Building Qt Translation Files")
print("=============================")
print("")
try: try:
subprocess.call(["pylupdate5", "-verbose", "-noobsolete", "novelWriter.pro"]) subprocess.call(["pylupdate5", "-verbose", "-noobsolete", "novelWriter.pro"])
except Exception as e: except Exception as e:
print("QtI18n Release Error:") print("QtI18n Release Error:")
print(str(e)) print(str(e))
print("")
return
## ##
# Sample Project ZIP File Builder (sample) # Sample Project ZIP File Builder (sample)
## ##