From b50132e255f81594bf7615e1c7f4f6577601a587 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Tue, 16 Feb 2021 22:02:59 +0100 Subject: [PATCH 1/7] Add support for project language file --- nw/assets/lang/project_en.json | 105 +++++++++++++++++++++++++++++++++ nw/config.py | 2 + nw/core/project.py | 30 ++++++++++ 3 files changed, 137 insertions(+) create mode 100644 nw/assets/lang/project_en.json diff --git a/nw/assets/lang/project_en.json b/nw/assets/lang/project_en.json new file mode 100644 index 000000000..e1bfbb372 --- /dev/null +++ b/nw/assets/lang/project_en.json @@ -0,0 +1,105 @@ +{ + "Synopsis": "Synopsis", + "Comment": "Comment", + "Notes": "Notes", + "0": "Zero", + "1": "One", + "2": "Two", + "3": "Three", + "4": "Four", + "5": "Five", + "6": "Six", + "7": "Seven", + "8": "Eight", + "9": "Nine", + "10": "Ten", + "11": "Eleven", + "12": "Twelve", + "13": "Thirteen", + "14": "Fourteen", + "15": "Fifteen", + "16": "Sixteen", + "17": "Seventeen", + "18": "Eighteen", + "19": "Nineteen", + "20": "Twenty", + "21": "Twenty-One", + "22": "Twenty-Two", + "23": "Twenty-Three", + "24": "Twenty-Four", + "25": "Twenty-Five", + "26": "Twenty-Six", + "27": "Twenty-Seven", + "28": "Twenty-Eight", + "29": "Twenty-Nine", + "30": "Thirty", + "31": "Thirty-One", + "32": "Thirty-Two", + "33": "Thirty-Three", + "34": "Thirty-Four", + "35": "Thirty-Five", + "36": "Thirty-Six", + "37": "Thirty-Seven", + "38": "Thirty-Eight", + "39": "Thirty-Nine", + "40": "Forty", + "41": "Forty-One", + "42": "Forty-Two", + "43": "Forty-Three", + "44": "Forty-Four", + "45": "Forty-Five", + "46": "Forty-Six", + "47": "Forty-Seven", + "48": "Forty-Eight", + "49": "Forty-Nine", + "50": "Fifty", + "51": "Fifty-One", + "52": "Fifty-Two", + "53": "Fifty-Three", + "54": "Fifty-Four", + "55": "Fifty-Five", + "56": "Fifty-Six", + "57": "Fifty-Seven", + "58": "Fifty-Eight", + "59": "Fifty-Nine", + "60": "Sixty", + "61": "Sixty-One", + "62": "Sixty-Two", + "63": "Sixty-Three", + "64": "Sixty-Four", + "65": "Sixty-Five", + "66": "Sixty-Six", + "67": "Sixty-Seven", + "68": "Sixty-Eight", + "69": "Sixty-Nine", + "70": "Seventy", + "71": "Seventy-One", + "72": "Seventy-Two", + "73": "Seventy-Three", + "74": "Seventy-Four", + "75": "Seventy-Five", + "76": "Seventy-Six", + "77": "Seventy-Seven", + "78": "Seventy-Eight", + "79": "Seventy-Nine", + "80": "Eighty", + "81": "Eighty-One", + "82": "Eighty-Two", + "83": "Eighty-Three", + "84": "Eighty-Four", + "85": "Eighty-Five", + "86": "Eighty-Six", + "87": "Eighty-Seven", + "88": "Eighty-Eight", + "89": "Eighty-Nine", + "90": "Ninety", + "91": "Ninety-One", + "92": "Ninety-Two", + "93": "Ninety-Three", + "94": "Ninety-Four", + "95": "Ninety-Five", + "96": "Ninety-Six", + "97": "Ninety-Seven", + "98": "Ninety-Eight", + "99": "Ninety-Nine" +} \ No newline at end of file diff --git a/nw/config.py b/nw/config.py index 58229ea5c..1f5799b99 100644 --- a/nw/config.py +++ b/nw/config.py @@ -73,6 +73,7 @@ def __init__(self): self.themeRoot = None # The full path to the nw/assets/themes folder self.dictPath = None # The full path to the nw/assets/dict folder self.iconPath = None # The full path to the nw/assets/icons folder + self.langPath = None # The full path to the nw/assets/lang folder self.helpPath = None # The full path to the novelwriter .qhc help file # Runtime Settings and Variables @@ -288,6 +289,7 @@ def initConfig(self, confPath=None, dataPath=None): self.themeRoot = os.path.join(self.assetPath, "themes") self.dictPath = os.path.join(self.assetPath, "dict") self.iconPath = os.path.join(self.assetPath, "icons") + self.langPath = os.path.join(self.assetPath, "lang") self.appIcon = os.path.join(self.iconPath, "novelwriter.svg") logger.verbose("App path: %s" % self.appPath) diff --git a/nw/core/project.py b/nw/core/project.py index fcb675ae8..bd31f1eae 100644 --- a/nw/core/project.py +++ b/nw/core/project.py @@ -27,6 +27,7 @@ import nw import logging import os +import json import shutil from lxml import etree @@ -58,6 +59,7 @@ def __init__(self, theParent): # Core Elements self.optState = OptionState(self) # Project-specific GUI options self.projTree = NWTree(self) # The project tree + self.langData = {} # Localisation data # Project Status self.projOpened = 0 # The time stamp of when the project file was opened @@ -605,6 +607,10 @@ def openProject(self, fileName, overrideLock=False): self.theParent.setStatus("Opened Project: %s" % self.projName) self._scanProjectFolder() + if self.projLang is None: + self._loadProjectLocalisation(self.mainConf.guiLang) + else: + self._loadProjectLocalisation(self.projLang) self.currWCount = self.lastWCount self.projOpened = time() @@ -1201,6 +1207,30 @@ def countStatus(self): # Internal Functions ## + def _loadProjectLocalisation(self, theLang): + """Load the language data for the current project language. + """ + lngShort = theLang.split("_")[0] + loadFile = os.path.join(self.mainConf.langPath, "project_en.json") + chkFile1 = os.path.join(self.mainConf.langPath, "project_%s.json" % theLang) + chkFile2 = os.path.join(self.mainConf.langPath, "project_%s.json" % lngShort) + if os.path.isfile(chkFile1): + loadFile = chkFile1 + elif os.path.isfile(chkFile2): + loadFile = chkFile2 + + try: + with open(loadFile, mode="r", encoding="utf8") as inFile: + self.langData = json.load(inFile) + logger.debug("Loaded project language file: %s" % os.path.basename(loadFile)) + + except Exception: + logger.error("Failed to load index file") + nw.logException() + return False + + return True + def _readLockFile(self): """Reads the lock file in the project folder. """ From 4699d9404b4bf4f9d96567c5e8366c959d5d0473 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Tue, 16 Feb 2021 22:18:14 +0100 Subject: [PATCH 2/7] Add the project localisation to the converter classes --- nw/core/project.py | 8 ++++++++ nw/core/tohtml.py | 10 ++++++---- nw/core/tokenizer.py | 12 ++++++++---- nw/core/tomd.py | 4 ++-- nw/core/toodt.py | 12 +++++++----- 5 files changed, 31 insertions(+), 15 deletions(-) diff --git a/nw/core/project.py b/nw/core/project.py index bd31f1eae..2b75227d5 100644 --- a/nw/core/project.py +++ b/nw/core/project.py @@ -1203,6 +1203,14 @@ def countStatus(self): self.importItems.countEntry(nwItem.itemStatus) return + def localLookup(self, theWord): + """Look up a word in the translation map for the project and + return it. The variable is cast to a string before lookup. If + the word does not exist, it returns itself. + """ + theValue = str(theWord) + return self.langData.get(theValue, theValue) + ## # Internal Functions ## diff --git a/nw/core/tohtml.py b/nw/core/tohtml.py index 67ebcc0fc..242554bf3 100644 --- a/nw/core/tohtml.py +++ b/nw/core/tohtml.py @@ -405,18 +405,20 @@ def getStyleSheet(self): def _formatSynopsis(self, tText): """Apply HTML formatting to synopsis. """ + sSynop = self._localLookup("Synopsis") if self.genMode == self.M_PREVIEW: - return "

Synopsis: %s

\n" % tText + return f"

{sSynop}: {tText}

\n" else: - return "

Synopsis: %s

\n" % tText + return f"

{sSynop}: {tText}

\n" def _formatComments(self, tText): """Apply HTML formatting to comments. """ if self.genMode == self.M_PREVIEW: - return "

%s

\n" % tText + return f"

{tText}

\n" else: - return "

Comment: %s

\n" % tText + sComm = self._localLookup("Comment") + return f"

{sComm}: {tText}

\n" def _formatKeywords(self, tText): """Apply HTML formatting to keywords. diff --git a/nw/core/tokenizer.py b/nw/core/tokenizer.py index 3e0474ae8..b8baeeb6e 100644 --- a/nw/core/tokenizer.py +++ b/nw/core/tokenizer.py @@ -31,7 +31,7 @@ from PyQt5.QtCore import QRegularExpression from nw.core.document import NWDoc -from nw.core.tools import numberToWord, numberToRoman +from nw.core.tools import numberToRoman from nw.constants import nwConst, nwUnicode, nwItemLayout, nwItemType, nwRegEx logger = logging.getLogger(__name__) @@ -141,6 +141,9 @@ def __init__(self, theProject, theParent): # Error Handling self.errData = [] + # Function Mapping + self._localLookup = self.theProject.localLookup + return ## @@ -249,7 +252,7 @@ def addRootHeading(self, theHandle): if theItem.itemType != nwItemType.ROOT: return False - theTitle = "Notes: %s" % theItem.itemName + theTitle = "%s: %s" % (self._localLookup("Notes"), theItem.itemName) self.theTokens = [] self.theTokens.append(( self.T_TITLE, 0, theTitle, None, self.A_PBB | self.A_CENTRE @@ -653,11 +656,12 @@ def _formatHeading(self, theTitle, theText): theTitle = theTitle.replace(r"%sc%", str(self.numChScene)) theTitle = theTitle.replace(r"%sca%", str(self.numAbsScene)) if r"%chw%" in theTitle: - theTitle = theTitle.replace(r"%chw%", numberToWord(self.numChapter, "en")) + theTitle = theTitle.replace(r"%chw%", self._localLookup(self.numChapter)) if r"%chi%" in theTitle: theTitle = theTitle.replace(r"%chi%", numberToRoman(self.numChapter, True)) if r"%chI%" in theTitle: theTitle = theTitle.replace(r"%chI%", numberToRoman(self.numChapter, False)) - return theTitle + + return theTitle[:1].upper() + theTitle[1:] # END Class Tokenizer diff --git a/nw/core/tomd.py b/nw/core/tomd.py index fe6da8fa4..b45d2e6cb 100644 --- a/nw/core/tomd.py +++ b/nw/core/tomd.py @@ -134,10 +134,10 @@ def doConvert(self): thisPar.append(tTemp.rstrip() + " ") elif tType == self.T_SYNOPSIS and self.doSynopsis: - tmpResult.append("**Synopsis:** %s\n\n" % tText) + tmpResult.append("**%s:** %s\n\n" % (self._localLookup("Synopsis"), tText)) elif tType == self.T_COMMENT and self.doComments: - tmpResult.append("**Comment:** %s\n\n" % tText) + tmpResult.append("**%s:** %s\n\n" % (self._localLookup("Comment"), tText)) elif tType == self.T_KEYWORD and self.doKeywords: tmpResult.append(self._formatKeywords(tText, tStyle)) diff --git a/nw/core/toodt.py b/nw/core/toodt.py index b9cffc3c1..0de952811 100644 --- a/nw/core/toodt.py +++ b/nw/core/toodt.py @@ -507,15 +507,17 @@ def saveOpenDocText(self, savePath): def _formatSynopsis(self, tText): """Apply formatting to synopsis lines. """ - rTxt = "**Synopsis:** %s" % tText - rFmt = "_B b_ %s" % (" "*len(tText)) + sSynop = self._localLookup("Synopsis") + rTxt = "**%s:** %s" % (sSynop, tText) + rFmt = "_B%s b_ %s" % (" "*len(sSynop), " "*len(tText)) return rTxt, rFmt def _formatComments(self, tText): """Apply formatting to comments. """ - rTxt = "**Comment:** %s" % tText - rFmt = "_B b_ %s" % (" "*len(tText)) + sComm = self._localLookup("Comment") + rTxt = "**%s:** %s" % (sComm, tText) + rFmt = "_B%s b_ %s" % (" "*len(sComm), " "*len(tText)) return rTxt, rFmt def _formatKeywords(self, tText): @@ -530,7 +532,7 @@ def _formatKeywords(self, tText): if theBits[0] in nwLabels.KEY_NAME: tText = nwLabels.KEY_NAME[theBits[0]] rTxt += "**%s:** " % tText - rFmt += "_B%s b_ " % (" "*len(tText)) + rFmt += "_B%s b_ " % (" "*len(tText)) if len(theBits) > 1: if theBits[0] == nwKeyWords.TAG_KEY: rTxt += "%s" % theBits[1] From 8aa2401134a1b22a40eeeefc0565fb89289ef9a1 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Tue, 16 Feb 2021 22:42:18 +0100 Subject: [PATCH 3/7] Make sure the project translation map is loaded correctly --- nw/core/project.py | 24 +++++++++++++++--------- nw/gui/preferences.py | 4 ++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/nw/core/project.py b/nw/core/project.py index 2b75227d5..5fd1be724 100644 --- a/nw/core/project.py +++ b/nw/core/project.py @@ -607,10 +607,7 @@ def openProject(self, fileName, overrideLock=False): self.theParent.setStatus("Opened Project: %s" % self.projName) self._scanProjectFolder() - if self.projLang is None: - self._loadProjectLocalisation(self.mainConf.guiLang) - else: - self._loadProjectLocalisation(self.projLang) + self.loadProjectLocalisation(self.projLang) self.currWCount = self.lastWCount self.projOpened = time() @@ -1016,6 +1013,7 @@ def setSpellLang(self, theLang): theLang = checkString(theLang, None, True) if self.projLang != theLang: self.projLang = theLang + self.loadProjectLocalisation(theLang) self.setProjectChanged(True) return True @@ -1211,17 +1209,21 @@ def localLookup(self, theWord): theValue = str(theWord) return self.langData.get(theValue, theValue) - ## - # Internal Functions - ## - - def _loadProjectLocalisation(self, theLang): + def loadProjectLocalisation(self, theLang): """Load the language data for the current project language. """ + if theLang is None: + theLang = self.mainConf.spellLanguage + lngShort = theLang.split("_")[0] loadFile = os.path.join(self.mainConf.langPath, "project_en.json") chkFile1 = os.path.join(self.mainConf.langPath, "project_%s.json" % theLang) chkFile2 = os.path.join(self.mainConf.langPath, "project_%s.json" % lngShort) + print(theLang) + print(lngShort) + print(loadFile) + print(chkFile1) + print(chkFile2) if os.path.isfile(chkFile1): loadFile = chkFile1 elif os.path.isfile(chkFile2): @@ -1239,6 +1241,10 @@ def _loadProjectLocalisation(self, theLang): return True + ## + # Internal Functions + ## + def _readLockFile(self): """Reads the lock file in the project folder. """ diff --git a/nw/gui/preferences.py b/nw/gui/preferences.py index 4913be256..f50447bb5 100644 --- a/nw/gui/preferences.py +++ b/nw/gui/preferences.py @@ -89,6 +89,7 @@ def _doSave(self): logger.debug("Saving new preferences") needsRestart = self.tabGeneral.saveValues() + prevSpell = self.mainConf.spellLanguage self.tabProjects.saveValues() self.tabDocs.saveValues() @@ -96,6 +97,9 @@ def _doSave(self): self.tabSyntax.saveValues() self.tabAuto.saveValues() + if prevSpell != self.mainConf.spellLanguage: + self.theProject.loadProjectLocalisation(self.mainConf.spellLanguage) + if needsRestart: self.theParent.makeAlert( "Some changes will not be applied until novelWriter has been restarted.", From 19d536ea8b5a2388e0672e8af53cf922180de34e Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Tue, 16 Feb 2021 22:45:17 +0100 Subject: [PATCH 4/7] Add norwegian project translation files --- nw/assets/lang/project_nb_NO.json | 105 ++++++++++++++++++++++++++++++ nw/assets/lang/project_nn_NO.json | 105 ++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+) create mode 100644 nw/assets/lang/project_nb_NO.json create mode 100644 nw/assets/lang/project_nn_NO.json diff --git a/nw/assets/lang/project_nb_NO.json b/nw/assets/lang/project_nb_NO.json new file mode 100644 index 000000000..06ce164bd --- /dev/null +++ b/nw/assets/lang/project_nb_NO.json @@ -0,0 +1,105 @@ +{ + "Synopsis": "Sammendrag", + "Comment": "Kommentar", + "Notes": "Notat", + "0": "null", + "1": "én", + "2": "to", + "3": "tre", + "4": "fire", + "5": "fem", + "6": "seks", + "7": "sju", + "8": "åtte", + "9": "ni", + "10": "ti", + "11": "elleve", + "12": "tolv", + "13": "tretten", + "14": "fjorten", + "15": "femten", + "16": "seksten", + "17": "sytten", + "18": "atten", + "19": "nitten", + "20": "tjue", + "21": "tjueén", + "22": "tjueto", + "23": "tjuetre", + "24": "tjuefire", + "25": "tjuefem", + "26": "tjueseks", + "27": "tjuesju", + "28": "tjueåtte", + "29": "tjueni", + "30": "tretti", + "31": "trettién", + "32": "trettito", + "33": "trettitre", + "34": "trettifire", + "35": "trettifem", + "36": "trettiseks", + "37": "trettisju", + "38": "trettiåtte", + "39": "trettini", + "40": "førti", + "41": "førtién", + "42": "førtito", + "43": "førtitre", + "44": "førtifire", + "45": "førtifem", + "46": "førtiseks", + "47": "førtisju", + "48": "førtiåtte", + "49": "førtini", + "50": "femti", + "51": "femtién", + "52": "femtito", + "53": "femtitre", + "54": "femtifire", + "55": "femtifem", + "56": "femtiseks", + "57": "femtisju", + "58": "femtiåtte", + "59": "femtini", + "60": "seksti", + "61": "sekstién", + "62": "sekstito", + "63": "sekstitre", + "64": "sekstifire", + "65": "sekstifem", + "66": "sekstiseks", + "67": "sekstisju", + "68": "sekstiåtte", + "69": "sekstini", + "70": "sytti", + "71": "syttién", + "72": "syttito", + "73": "syttitre", + "74": "syttifire", + "75": "syttifem", + "76": "syttiseks", + "77": "syttisju", + "78": "syttiåtte", + "79": "syttini", + "80": "åtti", + "81": "åttién", + "82": "åttito", + "83": "åttitre", + "84": "åttifire", + "85": "åttifem", + "86": "åttiseks", + "87": "åttisju", + "88": "åttiåtte", + "89": "åttini", + "90": "nitti", + "91": "nittién", + "92": "nittito", + "93": "nittitre", + "94": "nittifire", + "95": "nittifem", + "96": "nittiseks", + "97": "nittisju", + "98": "nittiåtte", + "99": "nittini" +} \ No newline at end of file diff --git a/nw/assets/lang/project_nn_NO.json b/nw/assets/lang/project_nn_NO.json new file mode 100644 index 000000000..1ee2f2ee7 --- /dev/null +++ b/nw/assets/lang/project_nn_NO.json @@ -0,0 +1,105 @@ +{ + "Synopsis": "Samandrag", + "Comment": "Kommentar", + "Notes": "Notat", + "0": "null", + "1": "ein", + "2": "to", + "3": "tre", + "4": "fire", + "5": "fem", + "6": "seks", + "7": "sju", + "8": "åtte", + "9": "ni", + "10": "ti", + "11": "elleve", + "12": "tolv", + "13": "tretten", + "14": "fjorten", + "15": "femten", + "16": "seksten", + "17": "sytten", + "18": "atten", + "19": "nitten", + "20": "tjue", + "21": "tjueein", + "22": "tjueto", + "23": "tjuetre", + "24": "tjuefire", + "25": "tjuefem", + "26": "tjueseks", + "27": "tjuesju", + "28": "tjueåtte", + "29": "tjueni", + "30": "tretti", + "31": "trettiein", + "32": "trettito", + "33": "trettitre", + "34": "trettifire", + "35": "trettifem", + "36": "trettiseks", + "37": "trettisju", + "38": "trettiåtte", + "39": "trettini", + "40": "førti", + "41": "førtiein", + "42": "førtito", + "43": "førtitre", + "44": "førtifire", + "45": "førtifem", + "46": "førtiseks", + "47": "førtisju", + "48": "førtiåtte", + "49": "førtini", + "50": "femti", + "51": "femtiein", + "52": "femtito", + "53": "femtitre", + "54": "femtifire", + "55": "femtifem", + "56": "femtiseks", + "57": "femtisju", + "58": "femtiåtte", + "59": "femtini", + "60": "seksti", + "61": "sekstiein", + "62": "sekstito", + "63": "sekstitre", + "64": "sekstifire", + "65": "sekstifem", + "66": "sekstiseks", + "67": "sekstisju", + "68": "sekstiåtte", + "69": "sekstini", + "70": "sytti", + "71": "syttiein", + "72": "syttito", + "73": "syttitre", + "74": "syttifire", + "75": "syttifem", + "76": "syttiseks", + "77": "syttisju", + "78": "syttiåtte", + "79": "syttini", + "80": "åtti", + "81": "åttiein", + "82": "åttito", + "83": "åttitre", + "84": "åttifire", + "85": "åttifem", + "86": "åttiseks", + "87": "åttisju", + "88": "åttiåtte", + "89": "åttini", + "90": "nitti", + "91": "nittiein", + "92": "nittito", + "93": "nittitre", + "94": "nittifire", + "95": "nittifem", + "96": "nittiseks", + "97": "nittisju", + "98": "nittiåtte", + "99": "nittini" +} \ No newline at end of file From 62cc64d91211a97105b78cb829bda0dceca32e4d Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Tue, 16 Feb 2021 23:47:49 +0100 Subject: [PATCH 5/7] Remove the old numberToWord functions and clean up the translation files --- i18n/nw_pt.ts | 395 +++++++++++++---------------- novelWriter.pro | 1 - nw/core/__init__.py | 3 +- nw/core/tools.py | 125 --------- tests/test_core/test_core_tools.py | 79 +----- 5 files changed, 183 insertions(+), 420 deletions(-) diff --git a/i18n/nw_pt.ts b/i18n/nw_pt.ts index 1d3974f32..e9060a298 100644 --- a/i18n/nw_pt.ts +++ b/i18n/nw_pt.ts @@ -2694,7 +2694,7 @@ GuiPreferences - + Some changes will not be applied until novelWriter has been restarted. Algumas alterações não serão aplicadas enquanto a aplicação não for reiniciada. @@ -2747,117 +2747,117 @@ GuiPreferencesAutomation - + Automatic Features Funcionalidades Automáticas - + Auto-select word under cursor Selecionar automaticamente a palavra sob o cursor - + Apply formatting to word under cursor if no selection is made. Aplicar a formatação à palavra sob o cursor se nenhuma seleção for feita. - + Auto-replace text as you type Substituir automaticamente o texto enquanto digita - + Allow the editor to replace symbols as you type. Permite que o editor substituia símbolos emquanto você digita. - + Replace as You Type Substituição Durante a Digitação - + Auto-replace single quotes Substituir automaticamente aspas simples - + Try to guess which is an opening or a closing single quote. Tenta adivinhar se a aspa simples é de abertura ou de fechamento. - + Auto-replace double quotes Subsitituir automaticamente aspas duplas - + Try to guess which is an opening or a closing double quote. Tenta adivinhar se a aspa dupla é de abertura ou de fechamento. - + Auto-replace dashes Substituir automaticamente os travessões - + Double and triple hyphens become short and long dashes. Hífens duplos ou triplos se tornam travessões curtos ou longos. - + Auto-replace dots Substituir automaticamente os pontos - + Three consecutive dots become ellipsis. Três pontos consecutivos se tornam uma reticência. - + Quotation Style Estilo de Aspas - + Single quote open style Estilo da aspa de abertura simples - + The symbol to use for a leading single quote. O símbolo usado para a aspa simples à esquerda. - + Single quote close style Estilo da aspa de fechamento simples - + The symbol to use for a trailing single quote. O símbolo usado para a aspa simples à esquerda. - + Double quote open style Estilo da aspa de abertura dupla - + The symbol to use for a leading double quote. O símbolo usado para a aspa dupla à esquerda. - + Double quote close style Estilo da aspa de fechamento dupla - + The symbol to use for a trailing double quote. O símbolo usado para a aspa dupla à direita. @@ -2865,107 +2865,107 @@ GuiPreferencesDocuments - + Text Style Estilo do Texto - + Font family Família da fonte - + Font for the document editor and viewer. Fonte para o editor e visualizador de documentos. - + Font size Tamanho da fonte - + Font size for the document editor and viewer. Tamanho da fonte para o editor e visualizador de documentos. - + Text Flow Fluxo do Texto - + Maximum text width in "Normal Mode" Largura máxima do texto no "Modo Normal" - + Horizontal margins are scaled automatically. Margens horizontais são redimensionadas automaticamente. - + Maximum text width in "Focus Mode" Largura máxima do texto no "Modo Foco" - + Disable maximum text width in "Normal Mode" Desabilita a largura máxima do texto no "Modo Normal" - + Text width is defined by the margins only. A largura do texto é definida apenas pelas margens. - + Hide document footer in "Focus Mode" Oculta o rodapé do documento no "Modo Foco" - + Hide the information bar at the bottom of the document. Oculta a barra de informações na parte de baixo do documento. - + Justify the text margins in editor and viewer Justifica as margens do texto no editor e visualizador - + Lay out text with straight edges in the editor and viewer. Organiza o texto com cantos retos no editor e visualizador. - + Text margin Margem do texto - + If maximum width is set, this becomes the minimum margin. Se a largura máxima for definida, esta se torna a margem mínima. - + Tab width Largura da tabulação - + The width of a tab key press in the editor and viewer. A largura de uma tabulação no editor e visualizador. - + px px - + pt pt @@ -2973,127 +2973,127 @@ GuiPreferencesEditor - + Spell Checking Correção Ortográfica - + Internal Interno - + Spell check provider Provedor de correção ortográfica - + Note that the internal spell check tool is quite slow. Note que o corretor ortográfico interno é significativamente lento. - + Spell check language Idioma do corretor ortográfico - + Available languages are determined by your system. Os idiomas disponíveis são determinados pelo seu sistema. - + Big document limit Limite de documento grande - + Full spell checking is disabled above this limit. A verificação ortográfica é desabilitada acima desse limite. - + Writing Guides Guias de Escrita - + Show tabs and spaces Mostrar tabulações e espaços - + Add symbols to indicate tabs and spaces in the editor. Adiciona símbolos para indicar tabulações e espaços no editor. - + Show line endings Mostrar terminações de linha - + Add a symbol to indicate line endings in the editor. Adiciona um símbolo para indicar a terminação de linha no editor. - + Scroll Behaviour Comportamento da Rolagem - + Scroll past end of the document Rolar após o final do documento - + Also improves trypewriter scrolling for short documents. Também melhora a rolagem de máquina de escrever em documentos curtos. - + Typewriter style scrolling when you type Rolagem no estilo de máquina de escrever quando digita - + Try to keep the cursor at a fixed vertical position. Tenta manter o cursor em uma posição vertical fixa. - + Minimum position for Typewriter scrolling Posição máxima da rolagem de máquina de escrever - + Percentage of the editor height from the top. Porcentagem da altura do editor desde o topo. - + kB kB - + Word Count Contagem de Palavras - + Word count interval Intervalo de contagem de palavras - + How often the word count is updated. Com qual frequência a contagem de palavras é atualizada. - + seconds segundos @@ -3101,77 +3101,77 @@ GuiPreferencesGeneral - + Look and Feel Aparência - + Main GUI theme Tema da interface - + Changing this requires restarting novelWriter. Alterações nessa configuração exigem reinício da aplicação. - + Main icon theme Tema dos ícones - + Prefer icons for dark backgrounds Preferir ícones para fundos escuros - + May improve the look of icons on dark themes. Pode melhorar a aparência dos ícones em temas escuros. - + Font family Família da fonte - + Font size Tamanho da fonte - + GUI Settings Configurações da Interface - + Show full path in document header Mostrar o caminho completo do documento no cabeçalho - + Add the parent folder names to the header. Adiciona o nome dos diretórios-pai ao cabeçalho. - + Hide vertical scroll bars in main windows Ocultar a barra de rolagem vertical nas janelas principais - + Scrolling available with mouse wheel and keys only. A rolagem de tela estará diponível apenas com o mouse ou teclado. - + Hide horizontal scroll bars in main windows Ocultar a barra de rolagem horizontal nas janelas principais - + pt pt @@ -3179,107 +3179,107 @@ GuiPreferencesProjects - + Automatic Save Salvamento Automático - + Save document interval Intervalo de salvamento do documento - + How often the open document is automatically saved. Com qual frequência o documento aberto é salvo automaticamente. - + Save project interval Intervalo de salvamento do projeto - + How often the open project is automatically saved. Com qual frequencia o projeto aberto é salvo automaticamente. - + Project Backup Cópia de Segurança - + Browse Procurar - + Backup storage location Localização da cópia de segurança - + Run backup when the project is closed Executar a cópia de segurança quando o projeto é fechado - + Can be overridden for individual projects in project settings. Pode ser sobrescrito para projetos individuais nas configurações do projeto. - + Ask before running backup Perguntar antes de executar a cópia de segurança - + If off, backups will run in the background. Se desativado, cópias de segurança serão executadas em segundo plano. - + Backup Directory Diretório das Cópias de Segurança - + seconds segundos - + Session Timer Temporizador da Sessão - + Pause the session timer when not writing Pausa o temporizador da sessão quando não estiver escrevendo - + Also pauses when the application window does not have focus. Também pausa quando a janela da aplicação não estiver em foco. - + Editor inactive time before pausing timer Tempo inativo do editor antes de pausar o temporizador - + User activity includes typing and changing the content. Atividades de usuário incluem escrever e alterar o conteúdo. - + minutes minutos - + Path: {0} Caminho: {0} @@ -3287,67 +3287,67 @@ GuiPreferencesSyntax - + Highlighting Theme Tema do Destaque - + Highlighting theme Tema do destaque - + Colour theme to apply to the editor and viewer. Tema de cores para aplicar ao editor e visualizador. - + Quotes & Dialogue Citações e Diálogos - + Highlight text wrapped in quotes Destaca o texto em citações - + Applies to single, double and straight quotes. Aplica-se a citações com aspas simples, duplas e retas. - + Allow open-ended single quotes Permite citações com aspas simples sem fechamento - + Highlight single-quoted line with no closing quote. Destaca a linha com citação de aspas simples sem aspas de fechamento. - + Allow open-ended double quotes Permite citações com aspas duplas sem fechamento - + Highlight double-quoted line with no closing quote. Destaca a linha com citação de aspas duplas sem aspas de fechamento. - + Text Emphasis Ênfase de Texto - + Add highlight colour to emphasised text Adiciona destaque de cor ao texto enfatizado - + Applies to emphasis (italic) and strong (bold). Aplica-se à ênfase (itálico) e ênfase forte (negrito). @@ -4180,312 +4180,312 @@ NWProject - + Trash Lixeira - + Chapter %ch%: %title% Capítulo %ch%: %title% - + New Novo - + Note Nota - + Draft Rascunho - + Finished Finalizado - + Minor Menor - + Major Maior - + Main Principal - + New Project Novo Projeto - + Novel Livro - + Plot Enredo - + Characters Personagens - + World Mundo - + Title Page Página de Título - + New Chapter Novo Capítulo - + New Scene Nova Cena - + Failed to parse project xml. Houve uma falha ao interpretar o conteúdo XML do projeto. - + Attempting to open backup project file instead. Tentando abrir a cópia de segurança do projeto. - + Unknown Desconhecido - + Project file does not appear to be a novelWriterXML file. O arquivo do projeto não parece ser um arquivo XML do novelWriter. - + Old Project Version Versão Antiga de Projeto - + The project file and data is created by a novelWriter version lower than 0.7. Do you want to upgrade the project to the most recent format? O arquivo do projeto e os dados foram criados por uma versão anterior à 0.7 do novelWriter. Deseja atualizar o projeto para o formato mais recente? - + Note that after the upgrade, you cannot open the project with an older version of novelWriter any more, so make sure you have a recent backup. Observe que após a atualização, não será possível abrir o projeto com uma versão mais antiga do novelWriter, tenha certeza de ter uma cópia de segurança recente. - + Version Conflict Conflito de Versão - + Opened Project: {0} Projeto Aberto: {0} - + Project path not set, cannot save project. O caminho do projeto não foi definido, não é possível salvar o projeto. - + Failed to save project. Houve uma falha ao salvar o projeto. - + Saved Project: {0} Projeto Salvo: {0} - + Backing up project ... Realizando uma cópia de segurança do projeto... - + Cannot backup project because no backup path is set. Please set a valid backup location in Tools > Preferences. Não foi possível realizar uma cópia de segurança do projeto porquê o caminho das cópias de segurança não foi definido. Por favor, defina um caminho válido para as cópias de segurança em Ferramentas > Preferências. - + Cannot backup project because no project name is set. Please set a Working Title in Project > Project Settings. Não foi possível realizar a cópia de segurança do projeto porque o nome do projeto não está definido. Por favor defina o Nome do Projeto em Projeto > Configurações do Projeto. - + Cannot backup project because the backup path does not exist. Please set a valid backup location in Tools > Preferences. Não foi possível realizar a cópia de segurança do projeto porque o caminho das cópias de segurança não exite. Por favor, defina um cainho válido para as cópias de segurança em Ferramentas > Preferências. - + Could not create backup folder. Não foi possível ler o diretório de cópias de segurança. - + Cannot backup project because the backup path is within the project folder to be backed up. Please choose a different backup path in Tools > Preferences. Não foi possível realizar a cópia de segurança do projeto porque o caminho das cópias de segurança está em um caminho dentro do diretório do projeto. Por favor, escolha um caminho diferente para as cópias de segurança em Ferramentas> Preferências. - + Could not write backup archive. Não foi possível escrever o arquivo da cópia de segurança. - + Failed to create a new example project. Houve uma falha ao criar um novo projeto de exemplo. - + Failed to create a new example project. Could not find the necessary files. They seem to be missing from this installation. Houve uma falha ao criar um novo projeto de exemplo. Não foi possível encontrar os arquivos necessários. Eles parecem estar faltando nesta instalação. - + Could not create new project folder. Não foi possível criar o diretório do novo projeto. - + New project folder is not empty. Each project requires a dedicated project folder. O diretório do novo projeto não está vazio. Cada projeto requer um diretório dedicado. - + You must set a valid backup path in preferences to use the automatic project backup feature. Deve ser definido um caminho válido para as cópias de segurança nas preferências para usar a funcionalidade de cópias de segurança automáticas. - + You must set a valid project name in project settings to use the automatic project backup feature. Deve ser definido um nome de projeto válido nas preferências do projeto para usar a funcionalidade de cópias de segurança automáticas. - + Recovered Recuperado - + One or more orphaned files could not be added back into the project. Make sure at least a Novel root folder exists. Um ou mais arquivos-órfãos não puderam ser readicionados ao projeto. Verifique que pelo menos um diretório-raiz de Livro exista. - + Could not move: {0} Não foi possível mover: {0} - + Could not delete: {0} Não foi possível remover: {0} - + Could not make folder: {0} Não foi possível criar o diretório: {0} - + Chapter {0} Capítulo {0} - + Scene {0} Cena {0} - + File not found: {0} Arquivo não encontrado: {0} - + Backup from {0} Cópia de segurança de {0} - + Backup archive file written to: {0} Arquivo da cópia de segurança escrito em: {0} - + Project backed up to '{0}' Cópia de segurança realizada para '{0}' - + Found {0} orphaned file(s) in project folder. Foram encontrados {0} arquivos-órfãos no diretório do projeto. - + Recovered File {0} Arquivo Recuperado {0} - + Not a folder: {0} Não é um diretório: {0} - + Unknown or unsupported novelWriter project file format. The project cannot be opened by this version of novelWriter. The file was saved with novelWriter version {0}. Format de arquivo de projeto do novelWriter desconhecido ou não-suportado. O projeto não pode ser aberto por essa versão do novelWriter. O arquivo foi salvo com a versão {0} do novelWriter. - + [{0}] {1} - + Could not move item {0} to {1}. Não foi possível mover o item {0} para {1}. - + This project was saved by a newer version of novelWriter, version {0}. This is version {1}. If you continue to open the project, some attributes and settings may not be preserved, but the overall project should be fine. Continue opening the project? O projeto foi salvo por uma versão mais nova do novelWriter, versão {0}. Esta é a versão {1}. Caso deseje continuar a abrir o projeto, alguns atributos e configurações podem não ser preservados, o restante do projeto, porém, deve funcionar. Continuar a abrir o projeto? - + By Por - + and e @@ -4673,37 +4673,4 @@ Cancelar - - Tokenizer - - - Notes - Notas - - - - ERROR - ERRO - - - - {0}: {1} - - - - - Synopsis - Sinopse - - - - Comment - Comentário - - - - Document '{0}' is too big ({1} MB). Skipping. - O documento '{0}' é muito grande ({1} MB). Ignorando. - - diff --git a/novelWriter.pro b/novelWriter.pro index b2da58006..92ba7def6 100644 --- a/novelWriter.pro +++ b/novelWriter.pro @@ -2,7 +2,6 @@ SOURCES += \ nw/constants/constants.py \ nw/core/document.py \ nw/core/project.py \ - nw/core/tokenizer.py \ nw/gui/about.py \ nw/gui/build.py \ nw/gui/custom.py \ diff --git a/nw/core/__init__.py b/nw/core/__init__.py index 61046eec1..be0aeeb29 100644 --- a/nw/core/__init__.py +++ b/nw/core/__init__.py @@ -7,12 +7,11 @@ from nw.core.tohtml import ToHtml from nw.core.toodt import ToOdt from nw.core.tomd import ToMarkdown -from nw.core.tools import countWords, numberToRoman, numberToWord +from nw.core.tools import countWords, numberToRoman __all__ = [ "countWords", "numberToRoman", - "numberToWord", "NWDoc", "NWIndex", "NWProject", diff --git a/nw/core/tools.py b/nw/core/tools.py index 7e538d6d5..a3dff45b7 100644 --- a/nw/core/tools.py +++ b/nw/core/tools.py @@ -6,8 +6,6 @@ File History: Created: 2019-04-22 [0.0.1] countWords -Created: 2019-10-13 [0.2.3] numberToWord, _numberToWordEN -Merged: 2020-05-08 [0.4.5] All of the above into this file Created: 2020-07-05 [0.10.0] numberToRoman This file is a part of novelWriter @@ -118,126 +116,3 @@ def numberToRoman(numVal, isLower=False): break return romNum.lower() if isLower else romNum - -# =============================================================================================== # -# Convert an Integer to a Number String -# =============================================================================================== # - -def numberToWord(numVal, theLang): - """Wrapper for converting numbers to words for chapter headings. - """ - if not isinstance(numVal, int): - return "[NaN]" - - if numVal < 0: - return "[<0]" - - if numVal > 999: - return "[>999]" - - numWord = "" - theCode = theLang.split("_")[0] - if theCode == "en": - numWord = _numberToWord_EN(numVal) - elif theCode in ("nb", "nn"): - numWord = _numberToWord_NO(numVal, theCode) - else: - # Default to return the number as a string - numWord = str(numVal) - - return numWord - -def _numberToWord_EN(numVal): - """Convert numbers to English words. - """ - oneWord = "" - tenWord = "" - hunWord = "" - - if numVal == 0: - return "Zero" - - oneVal = numVal % 10 - tenVal = (numVal - oneVal) % 100 - hunVal = (numVal - tenVal - oneVal) % 1000 - - theWords = { - 0: "", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five", - 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine", 10: "Ten", - 11: "Eleven", 12: "Twelve", 13: "Thirteen", 14: "Fourteen", - 15: "Fifteen", 16: "Sixteen", 17: "Seventeen", 18: "Eighteen", - 19: "Nineteen", 20: "Twenty", 30: "Thirty", 40: "Forty", - 50: "Fifty", 60: "Sixty", 70: "Seventy", 80: "Eighty", - 90: "Ninety", 100: "One Hundred", 200: "Two Hundred", - 300: "Three Hundred", 400: "Four Hundred", 500: "Five Hundred", - 600: "Six Hundred", 700: "Seven Hundred", 800: "Eight Hundred", - 900: "Nine Hundred", - } - - retVal = "" - hunWord = theWords.get(hunVal, "") - if tenVal == 10: - oneWord = theWords.get(oneVal+10, "") - retVal = f"{hunWord} {oneWord}".strip() - else: - oneWord = theWords.get(oneVal, "") - if tenVal == 0: - retVal = f"{hunWord} {oneWord}".strip() - else: - tenWord = theWords.get(tenVal, "") - if oneVal == 0: - retVal = f"{hunWord} {tenWord}".strip() - else: - retVal = f"{hunWord} {tenWord}-{oneWord}".strip() - - return retVal - -def _numberToWord_NO(numVal, theCode): - """Convert numbers to Norwegian words. - """ - oneWord = "" - tenWord = "" - hunWord = "" - - if numVal == 0: - return "null" - - oneVal = numVal % 10 - tenVal = (numVal - oneVal) % 100 - hunVal = (numVal - tenVal - oneVal) % 1000 - - theWords = { - 0: "", 1: "én", 2: "to", 3: "tre", 4: "fire", 5: "fem", 6: "seks", - 7: "sju", 8: "åtte", 9: "ni", 10: "ti", 11: "elleve", 12: "tolv", - 13: "tretten", 14: "fjorten", 15: "femten", 16: "seksten", 17: "sytten", - 18: "atten", 19: "nitten", 20: "tjue", 30: "tretti", 40: "førti", - 50: "femti", 60: "seksti", 70: "sytti", 80: "åtti", 90: "nitti", - 100: "ett hundre", 200: "to hundre", 300: "tre hundre", 400: "fire hundre", - 500: "fem hundre", 600: "seks hundre", 700: "sju hundre", - 800: "åtte hundre", 900: "ni hundre", - } - - if theCode == "nn": - theWords[1] = "ein" - theWords[100] = "eitt hundre" - - retVal = "" - hunWord = theWords.get(hunVal, "") - if tenVal == 10: - oneWord = theWords.get(oneVal+10, "") - sepVal = " og " if hunWord and oneWord else " " - retVal = f"{hunWord}{sepVal}{oneWord}" - else: - oneWord = theWords.get(oneVal, "") - if tenVal == 0: - sepVal = " og " if hunWord and oneWord else " " - retVal = f"{hunWord}{sepVal}{oneWord}".strip() - else: - tenWord = theWords.get(tenVal, "") - sepVal = " og " if hunWord and tenWord else " " - if oneVal == 0: - retVal = f"{hunWord}{sepVal}{tenWord}".strip() - else: - retVal = f"{hunWord}{sepVal}{tenWord}{oneWord}".strip() - - return retVal.strip() diff --git a/tests/test_core/test_core_tools.py b/tests/test_core/test_core_tools.py index 802eb94f0..77faf4441 100644 --- a/tests/test_core/test_core_tools.py +++ b/tests/test_core/test_core_tools.py @@ -22,7 +22,7 @@ import pytest -from nw.core.tools import countWords, numberToRoman, numberToWord +from nw.core.tools import countWords, numberToRoman @pytest.mark.core def testCoreTools_CountWords(): @@ -81,80 +81,3 @@ def testCoreTools_RomanNumbers(): assert numberToRoman(999, True) == "cmxcix" # END Test testCoreTools_RomanNumbers - -@pytest.mark.core -def testCoreTools_NumberWords(): - """Test the conversion of integer to English words. - """ - # English - assert numberToWord(0, "en") == "Zero" - assert numberToWord(1, "en") == "One" - assert numberToWord(2, "en") == "Two" - assert numberToWord(3, "en") == "Three" - assert numberToWord(4, "en") == "Four" - assert numberToWord(5, "en") == "Five" - assert numberToWord(6, "en") == "Six" - assert numberToWord(7, "en") == "Seven" - assert numberToWord(8, "en") == "Eight" - assert numberToWord(9, "en") == "Nine" - assert numberToWord(10, "en") == "Ten" - assert numberToWord(11, "en") == "Eleven" - assert numberToWord(12, "en") == "Twelve" - assert numberToWord(13, "en") == "Thirteen" - assert numberToWord(14, "en") == "Fourteen" - assert numberToWord(15, "en") == "Fifteen" - assert numberToWord(16, "en") == "Sixteen" - assert numberToWord(17, "en") == "Seventeen" - assert numberToWord(18, "en") == "Eighteen" - assert numberToWord(19, "en") == "Nineteen" - assert numberToWord(20, "en") == "Twenty" - assert numberToWord(21, "en") == "Twenty-One" - assert numberToWord(29, "en") == "Twenty-Nine" - assert numberToWord(42, "en") == "Forty-Two" - assert numberToWord(114, "en") == "One Hundred Fourteen" - assert numberToWord(142, "en") == "One Hundred Forty-Two" - assert numberToWord(999, "en") == "Nine Hundred Ninety-Nine" - - # Norwegian - assert numberToWord(0, "nb") == "null" - assert numberToWord(1, "nb") == "én" - assert numberToWord(10, "nb") == "ti" - assert numberToWord(20, "nb") == "tjue" - assert numberToWord(21, "nb") == "tjueén" - assert numberToWord(29, "nb") == "tjueni" - assert numberToWord(42, "nb") == "førtito" - assert numberToWord(60, "nb") == "seksti" - assert numberToWord(100, "nb") == "ett hundre" - assert numberToWord(114, "nb") == "ett hundre og fjorten" - assert numberToWord(142, "nb") == "ett hundre og førtito" - assert numberToWord(999, "nb") == "ni hundre og nittini" - - assert numberToWord(0, "nn") == "null" - assert numberToWord(1, "nn") == "ein" - assert numberToWord(10, "nn") == "ti" - assert numberToWord(20, "nn") == "tjue" - assert numberToWord(21, "nn") == "tjueein" - assert numberToWord(29, "nn") == "tjueni" - assert numberToWord(42, "nn") == "førtito" - assert numberToWord(60, "nn") == "seksti" - assert numberToWord(100, "nn") == "eitt hundre" - assert numberToWord(114, "nn") == "eitt hundre og fjorten" - assert numberToWord(142, "nn") == "eitt hundre og førtito" - assert numberToWord(999, "nn") == "ni hundre og nittini" - - # Check complex language setting - assert numberToWord(1, "en_GB") == "One" - assert numberToWord(2, "en_GB") == "Two" - assert numberToWord(3, "en_GB") == "Three" - - # Check a few with a nonsense language setting - assert numberToWord(1, "foo") == "1" - assert numberToWord(2, "foo") == "2" - assert numberToWord(3, "foo") == "3" - - # Test out of range values - assert numberToWord(12345, "en") == "[>999]" - assert numberToWord(-2345, "en") == "[<0]" - assert numberToWord("234", "en") == "[NaN]" - -# END Test testCoreTools_NumberWords From 4033f7a47daacdce0ef5877e16f1c22328fe7779 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Tue, 16 Feb 2021 23:58:25 +0100 Subject: [PATCH 6/7] Fix tests --- novelWriter.pro | 1 + nw/core/project.py | 8 +++----- nw/core/tokenizer.py | 4 +++- tests/test_core/test_core_tokenizer.py | 9 +++++++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/novelWriter.pro b/novelWriter.pro index 92ba7def6..b2da58006 100644 --- a/novelWriter.pro +++ b/novelWriter.pro @@ -2,6 +2,7 @@ SOURCES += \ nw/constants/constants.py \ nw/core/document.py \ nw/core/project.py \ + nw/core/tokenizer.py \ nw/gui/about.py \ nw/gui/build.py \ nw/gui/custom.py \ diff --git a/nw/core/project.py b/nw/core/project.py index dd55c1733..02fa3fd35 100644 --- a/nw/core/project.py +++ b/nw/core/project.py @@ -1250,16 +1250,14 @@ def loadProjectLocalisation(self, theLang): """ if theLang is None: theLang = self.mainConf.spellLanguage + if theLang is None: + theLang = "en" lngShort = theLang.split("_")[0] loadFile = os.path.join(self.mainConf.langPath, "project_en.json") chkFile1 = os.path.join(self.mainConf.langPath, "project_%s.json" % theLang) chkFile2 = os.path.join(self.mainConf.langPath, "project_%s.json" % lngShort) - print(theLang) - print(lngShort) - print(loadFile) - print(chkFile1) - print(chkFile2) + if os.path.isfile(chkFile1): loadFile = chkFile1 elif os.path.isfile(chkFile2): diff --git a/nw/core/tokenizer.py b/nw/core/tokenizer.py index fecb87676..260a230e5 100644 --- a/nw/core/tokenizer.py +++ b/nw/core/tokenizer.py @@ -28,8 +28,9 @@ import re from operator import itemgetter +from functools import partial -from PyQt5.QtCore import QRegularExpression +from PyQt5.QtCore import QCoreApplication, QRegularExpression from nw.core.document import NWDoc from nw.core.tools import numberToRoman @@ -144,6 +145,7 @@ def __init__(self, theProject, theParent): # Function Mapping self._localLookup = self.theProject.localLookup + self.tr = partial(QCoreApplication.translate, "Tokenizer") return diff --git a/tests/test_core/test_core_tokenizer.py b/tests/test_core/test_core_tokenizer.py index 8f8604f96..cad615fd0 100644 --- a/tests/test_core/test_core_tokenizer.py +++ b/tests/test_core/test_core_tokenizer.py @@ -112,11 +112,14 @@ def testCoreToken_Setters(dummyGUI): # END Test testCoreToken_Setters @pytest.mark.core -def testCoreToken_TextOps(monkeypatch, nwMinimal, dummyGUI): +def testCoreToken_TextOps(monkeypatch, nwMinimal, dummyGUI, tmpConf): """Test handling files and text in the Tokenizer class. """ theProject = NWProject(dummyGUI) + theProject.mainConf = tmpConf theProject.projTree.setSeed(42) + theProject.loadProjectLocalisation("en") + theToken = Tokenizer(theProject, dummyGUI) theToken.setKeepMarkdown(True) @@ -408,10 +411,12 @@ def testCoreToken_Tokenize(dummyGUI): # END Test testCoreToken_Tokenize @pytest.mark.core -def testCoreToken_Headers(dummyGUI): +def testCoreToken_Headers(dummyGUI, tmpConf): """Test the header and page parser of the Tokenizer class. """ theProject = NWProject(dummyGUI) + theProject.mainConf = tmpConf + theProject.loadProjectLocalisation("en") theToken = Tokenizer(theProject, dummyGUI) # Nothing From 8a050810c1f456b6f8c0d2dddd29b4d8e4684b26 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Wed, 17 Feb 2021 00:01:07 +0100 Subject: [PATCH 7/7] Update translation file after removing no longer needed Tokenizer translations --- i18n/nw_pt.ts | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/i18n/nw_pt.ts b/i18n/nw_pt.ts index e9060a298..cce1aeca3 100644 --- a/i18n/nw_pt.ts +++ b/i18n/nw_pt.ts @@ -4390,27 +4390,27 @@ Deve ser definido um nome de projeto válido nas preferências do projeto para usar a funcionalidade de cópias de segurança automáticas. - + Recovered Recuperado - + One or more orphaned files could not be added back into the project. Make sure at least a Novel root folder exists. Um ou mais arquivos-órfãos não puderam ser readicionados ao projeto. Verifique que pelo menos um diretório-raiz de Livro exista. - + Could not move: {0} Não foi possível mover: {0} - + Could not delete: {0} Não foi possível remover: {0} - + Could not make folder: {0} Não foi possível criar o diretório: {0} @@ -4445,17 +4445,17 @@ Cópia de segurança realizada para '{0}' - + Found {0} orphaned file(s) in project folder. Foram encontrados {0} arquivos-órfãos no diretório do projeto. - + Recovered File {0} Arquivo Recuperado {0} - + Not a folder: {0} Não é um diretório: {0} @@ -4465,12 +4465,12 @@ Format de arquivo de projeto do novelWriter desconhecido ou não-suportado. O projeto não pode ser aberto por essa versão do novelWriter. O arquivo foi salvo com a versão {0} do novelWriter. - + [{0}] {1} - + Could not move item {0} to {1}. Não foi possível mover o item {0} para {1}. @@ -4673,4 +4673,17 @@ Cancelar + + Tokenizer + + + ERROR + ERRO + + + + Document '{0}' is too big ({1} MB). Skipping. + O documento '{0}' é muito grande ({1} MB). Ignorando. + +