Adding non-breaking space support for editor and html, latex export

This commit is contained in:
Veronica K. B. Olsen
2019-10-29 14:49:11 +01:00
parent 146756a395
commit 489eae2e0d
10 changed files with 104 additions and 54 deletions
+38 -30
View File
@@ -149,7 +149,9 @@ class nwUnicode:
"""Suppoted unicode character constants and translation maps. """Suppoted unicode character constants and translation maps.
""" """
# Quotation Marks # Unicode Constants
## Quotation Marks
U_QUOT = "\u0022" # Quotation mark U_QUOT = "\u0022" # Quotation mark
U_APOS = "\u0027" # Apostrophe U_APOS = "\u0027" # Apostrophe
U_LAQUO = "\u00ab" # Left-pointing double angle quotation mark U_LAQUO = "\u00ab" # Left-pointing double angle quotation mark
@@ -170,38 +172,44 @@ class nwUnicode:
U_LWCQUO = "\u300e" # Left white corner bracket U_LWCQUO = "\u300e" # Left white corner bracket
U_RECQUO = "\u300f" # Right white corner bracket U_RECQUO = "\u300f" # Right white corner bracket
# Punctuation ## Punctuation
U_NDASH = "\u2013" # Short dash U_ENDASH = "\u2013" # Short dash
U_MDASH = "\u2014" # Long dash U_EMDASH = "\u2014" # Long dash
U_HELLIP = "\u2026" # Ellipsis U_HELLIP = "\u2026" # Ellipsis
# Other ## Other
U_NBSP = "\u00a0" # Non-breaking space U_NBSP = "\u00a0" # Non-breaking space
U_PARA = "\u2029" # Paragraph separator
HTML = { # HTML Equivalents
U_QUOT : """,
U_APOS : "'", ## Quotes
U_LAQUO : "«", H_QUOT = """
U_RAQUO : "»", H_APOS = "'"
U_LSQUO : "‘", H_LAQUO = "«"
U_RSQUO : "’", H_RAQUO = "»"
U_SBQUO : "‚", H_LSQUO = "‘"
U_SUQUO : "‛", H_RSQUO = "’"
U_LDQUO : "“", H_SBQUO = "‚"
U_RDQUO : "”", H_SUQUO = "‛"
U_BDQUO : "„", H_LDQUO = "“"
U_UDQUO : "‟", H_RDQUO = "”"
U_LSAQUO : "‹", H_BDQUO = "„"
U_RSAQUO : "›", H_UDQUO = "‟"
U_BDRQUO : "⹂", H_LSAQUO = "‹"
U_LCQUO : "「", H_RSAQUO = "›"
U_RCQUO : "」", H_BDRQUO = "⹂"
U_LWCQUO : "『", H_LCQUO = "「"
U_LWCQUO : "『", H_RCQUO = "」"
U_NDASH : "–", H_LWCQUO = "『"
U_MDASH : "—", H_LWCQUO = "『"
U_HELLIP : "…",
U_NBSP : " ", ## Punctuation
} H_ENDASH = "–"
H_EMDASH = "—"
H_HELLIP = "…"
## Other
H_NBSP = " "
# END Class nwUnicode # END Class nwUnicode
+13 -12
View File
@@ -38,18 +38,19 @@ class HtmlFile(TextFile):
self.outFile.write("<!DOCTYPE html>\n") self.outFile.write("<!DOCTYPE html>\n")
self.outFile.write("<html>\n") self.outFile.write("<html>\n")
self.outFile.write("<head>\n") self.outFile.write("<head>\n")
self.outFile.write("<style>\n") self.outFile.write(" <meta charset='utf-8'>\n")
self.outFile.write(" #page {\n") self.outFile.write(" <style>\n")
self.outFile.write(" margin: 40px auto;\n") self.outFile.write(" #page {\n")
self.outFile.write(" max-width: 769px;\n") self.outFile.write(" margin: 40px auto;\n")
self.outFile.write(" }\n") self.outFile.write(" max-width: 769px;\n")
self.outFile.write(" .comment {\n") self.outFile.write(" }\n")
self.outFile.write(" background-color: #fbfabd;\n") self.outFile.write(" .comment {\n")
self.outFile.write(" border: 1px solid #b4b000;\n") self.outFile.write(" background-color: #fbfabd;\n")
self.outFile.write(" margin: 10px 20px;\n") self.outFile.write(" border: 1px solid #b4b000;\n")
self.outFile.write(" padding: 6px;\n") self.outFile.write(" margin: 10px 20px;\n")
self.outFile.write(" }\n") self.outFile.write(" padding: 6px;\n")
self.outFile.write("</style>\n") self.outFile.write(" }\n")
self.outFile.write(" </style>\n")
self.outFile.write("</head>\n") self.outFile.write("</head>\n")
self.outFile.write("<body>\n") self.outFile.write("<body>\n")
self.outFile.write("<article id='page'>\n") self.outFile.write("<article id='page'>\n")
+1
View File
@@ -138,6 +138,7 @@ class TextFile():
self.theConv.tokenizeText() self.theConv.tokenizeText()
self.theConv.doHeaders() self.theConv.doHeaders()
self.theConv.doConvert() self.theConv.doConvert()
self.theConv.doPostProcessing()
if self.theConv.theResult is not None and self.outFile is not None: if self.theConv.theResult is not None and self.outFile is not None:
self.outFile.write(self.theConv.theResult) self.outFile.write(self.theConv.theResult)
+8 -7
View File
@@ -15,6 +15,7 @@ import re
import nw import nw
from nw.convert.tokenizer import Tokenizer from nw.convert.tokenizer import Tokenizer
from nw.constants import nwUnicode
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -28,13 +29,13 @@ class ToHtml(Tokenizer):
Tokenizer.doAutoReplace(self) Tokenizer.doAutoReplace(self)
repDict = { repDict = {
"<" : "&lt;", "<" : "&lt;",
">" : "&gt;", ">" : "&gt;",
"&" : "&amp;", "&" : "&amp;",
"\u2013" : "&endash;", nwUnicode.U_ENDASH : nwUnicode.H_ENDASH,
"\u2014" : "$emdash;", nwUnicode.U_EMDASH : nwUnicode.H_EMDASH,
"\u2500" : "$emdash;", nwUnicode.U_HELLIP : nwUnicode.H_HELLIP,
"\u2026" : "&hellip;", nwUnicode.U_NBSP : nwUnicode.H_NBSP,
} }
xRep = re.compile("|".join([re.escape(k) for k in repDict.keys()]), flags=re.DOTALL) xRep = re.compile("|".join([re.escape(k) for k in repDict.keys()]), flags=re.DOTALL)
self.theText = xRep.sub(lambda x: repDict[x.group(0)], self.theText) self.theText = xRep.sub(lambda x: repDict[x.group(0)], self.theText)
+15
View File
@@ -16,6 +16,7 @@ import re
import nw import nw
from nw.convert.tokenizer import Tokenizer from nw.convert.tokenizer import Tokenizer
from nw.constants import nwUnicode
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -26,6 +27,20 @@ class ToLaTeX(Tokenizer):
self.texCodecFail = False self.texCodecFail = False
return return
def doPostProcessing(self):
"""The latexcodec misses dashes and non-breaking spaces, so we do those here.
"""
repDict = {
nwUnicode.U_ENDASH : "--",
nwUnicode.U_EMDASH : "---",
nwUnicode.U_NBSP : "~",
}
xRep = re.compile("|".join([re.escape(k) for k in repDict.keys()]), flags=re.DOTALL)
self.theResult = xRep.sub(lambda x: repDict[x.group(0)], self.theResult)
return
def doConvert(self): def doConvert(self):
texTags = { texTags = {
+12
View File
@@ -16,6 +16,7 @@ import re
import nw import nw
from nw.convert.tokenizer import Tokenizer from nw.convert.tokenizer import Tokenizer
from nw.constants import nwUnicode
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -25,6 +26,17 @@ class ToText(Tokenizer):
Tokenizer.__init__(self, theProject, theParent) Tokenizer.__init__(self, theProject, theParent)
return return
def doAutoReplace(self):
Tokenizer.doAutoReplace(self)
repDict = {
nwUnicode.U_NBSP : " ",
}
xRep = re.compile("|".join([re.escape(k) for k in repDict.keys()]), flags=re.DOTALL)
self.theText = xRep.sub(lambda x: repDict[x.group(0)], self.theText)
return
def doConvert(self): def doConvert(self):
"""Converts the tokenized text into plain text. """Converts the tokenized text into plain text.
""" """
+3
View File
@@ -149,6 +149,9 @@ class Tokenizer():
self.theText = xRep.sub(lambda x: repDict[x.group(0)], self.theText) self.theText = xRep.sub(lambda x: repDict[x.group(0)], self.theText)
return return
def doPostProcessing(self):
return
def tokenizeText(self): def tokenizeText(self):
"""Scan the text for either lines starting with specific characters that indicate headers, """Scan the text for either lines starting with specific characters that indicate headers,
comments, commands etc, or just contains plain text. in the case of plain text, apply the comments, commands etc, or just contains plain text. in the case of plain text, apply the
+11 -4
View File
@@ -218,7 +218,14 @@ class GuiDocEditor(QTextEdit):
return self.docChanged return self.docChanged
def getText(self): def getText(self):
theText = self.toPlainText() """Get the text content of the current document. This method uses QTextEdit->toPlainText for
Qt versions lower than 5.9, and the QDocument->toRawText for higher version. The latter
preserves non-breaking spaces, which the former does not.
"""
if self.mainConf.verQtValue >= 50900:
theText = self.qDocument.toRawText().replace(nwUnicode.U_PARA,"\n")
else:
theText = self.toPlainText()
return theText return theText
def setCursorPosition(self, thePosition): def setCursorPosition(self, thePosition):
@@ -466,11 +473,11 @@ class GuiDocEditor(QTextEdit):
elif self.mainConf.doReplaceDash and theTwo == "--": elif self.mainConf.doReplaceDash and theTwo == "--":
theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 2) theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 2)
theCursor.insertText(nwUnicode.U_NDASH) theCursor.insertText(nwUnicode.U_ENDASH)
elif self.mainConf.doReplaceDash and theTwo == nwUnicode.U_NDASH+"-": elif self.mainConf.doReplaceDash and theTwo == nwUnicode.U_ENDASH+"-":
theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 2) theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 2)
theCursor.insertText(nwUnicode.U_MDASH) theCursor.insertText(nwUnicode.U_EMDASH)
elif self.mainConf.doReplaceDots and theThree == "...": elif self.mainConf.doReplaceDots and theThree == "...":
theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 3) theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 3)
+1
View File
@@ -106,6 +106,7 @@ class GuiDocViewer(QTextBrowser):
aDoc.doAutoReplace() aDoc.doAutoReplace()
aDoc.tokenizeText() aDoc.tokenizeText()
aDoc.doConvert() aDoc.doConvert()
aDoc.doPostProcessing()
self.setHtml(aDoc.theResult) self.setHtml(aDoc.theResult)
if self.theHandle == tHandle: if self.theHandle == tHandle:
self.verticalScrollBar().setValue(sPos) self.verticalScrollBar().setValue(sPos)
+2 -1
View File
@@ -100,7 +100,8 @@ class NWDoc():
self.makeAlert(["Could not save document.",str(e)], nwAlert.ERROR) self.makeAlert(["Could not save document.",str(e)], nwAlert.ERROR)
return False return False
if path.isfile(docTemp): unlink(docTemp) if path.isfile(docTemp):
unlink(docTemp)
self.theParent.statusBar.setStatus("Saved Document: %s" % self.theItem.itemName) self.theParent.statusBar.setStatus("Saved Document: %s" % self.theItem.itemName)