Add converter support for the new formats
This commit is contained in:
@@ -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'"
|
||||
|
||||
@@ -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 = ""
|
||||
|
||||
@@ -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
|
||||
##
|
||||
|
||||
Reference in New Issue
Block a user