Add converter support for the new formats

This commit is contained in:
Veronica Berglyd Olsen
2023-10-20 00:05:17 +02:00
parent 0115f1e343
commit ae1ed10f25
3 changed files with 107 additions and 16 deletions
+9
View File
@@ -131,6 +131,8 @@ class ToHtml(Tokenizer):
self.FMT_I_E: "</i>",
self.FMT_D_B: "<span style='text-decoration: line-through;'>",
self.FMT_D_E: "</span>",
self.FMT_U_B: "<u>",
self.FMT_U_E: "</u>",
}
else:
htmlTags = { # HTML5 (for export)
@@ -140,8 +142,15 @@ class ToHtml(Tokenizer):
self.FMT_I_E: "</em>",
self.FMT_D_B: "<del>",
self.FMT_D_E: "</del>",
self.FMT_U_B: "<span style='text-decoration: underline;'>",
self.FMT_U_E: "</span>",
}
htmlTags[self.FMT_SUP_B] = "<sup>"
htmlTags[self.FMT_SUP_E] = "</sup>"
htmlTags[self.FMT_SUB_B] = "<sub>"
htmlTags[self.FMT_SUB_E] = "</sub>"
if self._isNovel and self._genMode != self.M_PREVIEW:
# For story files, we bump the titles one level up
h1Cl = " class='title'"
+20 -8
View File
@@ -38,12 +38,12 @@ class ToMarkdown(Tokenizer):
"""Core: Markdown Document Writer
Extend the Tokenizer class to writer Markdown output. It supports
both Standard Markdown and GitHub Flavour Markdown (Extended). The
class also supports concatenating novelWriter markup files.
both Standard Markdown and Extended Markdown. The class also
supports concatenating novelWriter markup files.
"""
M_STD = 0 # Standard Markdown
M_GH = 1 # GitHub Markdown
M_EXT = 1 # Extended Markdown
def __init__(self, project: NWProject) -> None:
super().__init__(project)
@@ -69,9 +69,9 @@ class ToMarkdown(Tokenizer):
self._genMode = self.M_STD
return
def setGitHubMarkdown(self) -> None:
"""Set the converter to use GitHub Markdown formatting."""
self._genMode = self.M_GH
def setExtendedMarkdown(self) -> None:
"""Set the converter to use Extended Markdown formatting."""
self._genMode = self.M_EXT
return
##
@@ -85,7 +85,7 @@ class ToMarkdown(Tokenizer):
def doConvert(self) -> None:
"""Convert the list of text tokens into a Markdown document."""
if self._genMode == self.M_STD:
# Standard
# Standard Markdown
mdTags = {
self.FMT_B_B: "**",
self.FMT_B_E: "**",
@@ -93,9 +93,15 @@ class ToMarkdown(Tokenizer):
self.FMT_I_E: "_",
self.FMT_D_B: "",
self.FMT_D_E: "",
self.FMT_U_B: "",
self.FMT_U_E: "",
self.FMT_SUP_B: "",
self.FMT_SUP_E: "",
self.FMT_SUB_B: "",
self.FMT_SUB_E: "",
}
else:
# GitHub
# Extended Markdown
mdTags = {
self.FMT_B_B: "**",
self.FMT_B_E: "**",
@@ -103,6 +109,12 @@ class ToMarkdown(Tokenizer):
self.FMT_I_E: "_",
self.FMT_D_B: "~~",
self.FMT_D_E: "~~",
self.FMT_U_B: "",
self.FMT_U_E: "",
self.FMT_SUP_B: "^",
self.FMT_SUP_E: "^",
self.FMT_SUB_B: "~",
self.FMT_SUB_E: "~",
}
self._result = ""
+78 -8
View File
@@ -82,11 +82,17 @@ TAG_STNM = _mkTag("text", "style-name")
X_BLD = 0x01 # Bold format
X_ITA = 0x02 # Italic format
X_DEL = 0x04 # Strikethrough format
X_UND = 0x08 # Underline format
X_SUP = 0x10 # Superscript
X_SUB = 0x20 # Subscript
# Formatting Masks
M_BLD = ~X_BLD
M_ITA = ~X_ITA
M_DEL = ~X_DEL
M_UND = ~X_UND
M_SUP = ~X_SUP
M_SUB = ~X_SUB
class ToOdt(Tokenizer):
@@ -386,12 +392,18 @@ class ToOdt(Tokenizer):
self._result = "" # Not used, but cleared just in case
odtTags = {
self.FMT_B_B: "_B", # Bold open format
self.FMT_B_E: "b_", # Bold close format
self.FMT_I_B: "I", # Italic open format
self.FMT_I_E: "i", # Italic close format
self.FMT_D_B: "_S", # Strikethrough open format
self.FMT_D_E: "s_", # Strikethrough close format
self.FMT_B_B: "B", # Bold open format
self.FMT_B_E: "b", # Bold close format
self.FMT_I_B: "I", # Italic open format
self.FMT_I_E: "i", # Italic close format
self.FMT_D_B: "S", # Strikethrough open format
self.FMT_D_E: "s", # Strikethrough close format
self.FMT_U_B: "U", # Underline open format
self.FMT_U_E: "u", # Underline close format
self.FMT_SUP_B: "P", # Superscript open format
self.FMT_SUP_E: "p", # Superscript close format
self.FMT_SUB_B: "D", # Subscript open format
self.FMT_SUB_E: "d", # Subscript close format
}
fmt = []
@@ -480,7 +492,10 @@ class ToOdt(Tokenizer):
tFmt = " "*len(tText)
for xPos, xLen, xFmt in tFormat:
tFmt = tFmt[:xPos] + odtTags[xFmt] + tFmt[xPos+xLen:]
if xFmt%2 == 0: # Even number: End
tFmt = tFmt[:xPos] + odtTags[xFmt].ljust(xLen, "_") + tFmt[xPos+xLen:]
else: # Odd number: Begin
tFmt = tFmt[:xPos] + odtTags[xFmt].rjust(xLen, "_") + tFmt[xPos+xLen:]
tTxt = tText.rstrip()
tFmt = tFmt[:len(tTxt)]
@@ -650,6 +665,18 @@ class ToOdt(Tokenizer):
xFmt |= X_DEL
elif tFmt[i] == "s":
xFmt &= M_DEL
elif tFmt[i] == "U":
xFmt |= X_UND
elif tFmt[i] == "u":
xFmt &= M_UND
elif tFmt[i] == "P":
xFmt |= X_SUP
elif tFmt[i] == "p":
xFmt &= M_SUP
elif tFmt[i] == "D":
xFmt |= X_SUB
elif tFmt[i] == "d":
xFmt &= M_SUB
else:
pErr += 1
@@ -713,6 +740,14 @@ class ToOdt(Tokenizer):
if hFmt & X_DEL:
newStyle.setStrikeStyle("solid")
newStyle.setStrikeType("single")
if hFmt & X_UND:
newStyle.setUnderlineStyle("solid")
newStyle.setUnderlineWidth("auto")
newStyle.setUnderlineColour("font-color")
if hFmt & X_SUP:
newStyle.setTextPosition("super")
if hFmt & X_SUB:
newStyle.setTextPosition("sub")
self._autoText[hFmt] = (newName, newStyle)
@@ -1256,16 +1291,23 @@ class ODTTextStyle:
"""
VALID_WEIGHT = ["normal", "inherit", "bold"]
VALID_STYLE = ["normal", "inherit", "italic"]
VALID_POS = ["super", "sub"]
VALID_LSTYLE = ["none", "solid"]
VALID_LTYPE = ["none", "single", "double"]
VALID_LTYPE = ["single", "double"]
VALID_LWIDTH = ["auto"]
VALID_LCOL = ["font-color"]
def __init__(self) -> None:
# Text Attributes
self._tAttr = {
"font-weight": ["fo", None],
"font-style": ["fo", None],
"text-position": ["style", None],
"text-line-through-style": ["style", None],
"text-line-through-type": ["style", None],
"text-underline-style": ["style", None],
"text-underline-width": ["style", None],
"text-underline-color": ["style", None],
}
return
@@ -1287,6 +1329,13 @@ class ODTTextStyle:
self._tAttr["font-style"][1] = None
return
def setTextPosition(self, value: str | None) -> None:
if value in self.VALID_POS:
self._tAttr["text-position"][1] = f"{value} 58%"
else:
self._tAttr["text-position"][1] = None
return
def setStrikeStyle(self, value: str | None) -> None:
if value in self.VALID_LSTYLE:
self._tAttr["text-line-through-style"][1] = value
@@ -1301,6 +1350,27 @@ class ODTTextStyle:
self._tAttr["text-line-through-type"][1] = None
return
def setUnderlineStyle(self, value: str | None) -> None:
if value in self.VALID_LSTYLE:
self._tAttr["text-underline-style"][1] = value
else:
self._tAttr["text-underline-style"][1] = None
return
def setUnderlineWidth(self, value: str | None) -> None:
if value in self.VALID_LWIDTH:
self._tAttr["text-underline-width"][1] = value
else:
self._tAttr["text-underline-width"][1] = None
return
def setUnderlineColour(self, value: str | None) -> None:
if value in self.VALID_LCOL:
self._tAttr["text-underline-color"][1] = value
else:
self._tAttr["text-underline-color"][1] = None
return
##
# Methods
##