Add text paragraph formatting

This commit is contained in:
Veronica Berglyd Olsen
2024-05-23 19:43:32 +02:00
parent 6d84942746
commit c8017a1f42
3 changed files with 72 additions and 24 deletions
@@ -26,8 +26,8 @@ from __future__ import annotations
import logging import logging
from PyQt5.QtGui import ( from PyQt5.QtGui import (
QFont, QFontMetrics, QTextBlockFormat, QTextCharFormat, QTextCursor, QColor, QFont, QFontMetrics, QTextBlockFormat, QTextCharFormat,
QTextDocument QTextCursor, QTextDocument
) )
from novelwriter import SHARED from novelwriter import SHARED
@@ -36,13 +36,13 @@ from novelwriter.core.project import NWProject
from novelwriter.core.tokenizer import T_Formats, Tokenizer from novelwriter.core.tokenizer import T_Formats, Tokenizer
from novelwriter.types import ( from novelwriter.types import (
QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight, QtPageBreakAfter, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight, QtPageBreakAfter,
QtPageBreakBefore QtPageBreakBefore, QtTransparent, QtVAlignNormal, QtVAlignSub,
QtVAlignSuper
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
T_TextStyle = tuple[QTextBlockFormat, QTextCharFormat] T_TextStyle = tuple[QTextBlockFormat, QTextCharFormat]
T_TextParFormat = tuple[str, QTextCharFormat]
class ToQTextDocument(Tokenizer): class ToQTextDocument(Tokenizer):
@@ -58,7 +58,11 @@ class ToQTextDocument(Tokenizer):
self._document.setUndoRedoEnabled(False) self._document.setUndoRedoEnabled(False)
self._styles: dict[int, T_TextStyle] = {} self._styles: dict[int, T_TextStyle] = {}
self._usedNotes: dict[str, int] = {}
self._init = False self._init = False
self._bold = QFont.Weight.Bold
self._normal = QFont.Weight.Normal
return return
@@ -166,8 +170,7 @@ class ToQTextDocument(Tokenizer):
if tType == self.T_TEXT: if tType == self.T_TEXT:
newBlock(bFmt) newBlock(bFmt)
tTemp, cFmt = self._formatText(tText, tFormat, self._defaultChar) self._insertFragments(tText, tFormat, cursor, self._defaultChar)
cursor.insertText(tTemp, cFmt)
elif tType in self.L_HEADINGS: elif tType in self.L_HEADINGS:
bFmt, cFmt = self._genHeadStyle(tType, bFmt) bFmt, cFmt = self._genHeadStyle(tType, bFmt)
@@ -222,23 +225,64 @@ class ToQTextDocument(Tokenizer):
# Internal Functions # Internal Functions
## ##
def _formatText(self, text: str, tFmt: T_Formats, dFmt: QTextCharFormat) -> T_TextParFormat: def _insertFragments(
self, text: str, tFmt: T_Formats, cursor: QTextCursor,
dFmt: QTextCharFormat, bgCol: QColor = QtTransparent
) -> None:
"""Apply formatting tags to text.""" """Apply formatting tags to text."""
temp = text cFmt = QTextCharFormat(dFmt)
fmt = QTextCharFormat(dFmt) start = 0
# for pos, fmt, data in reversed(tFmt): for pos, fmt, data in tFmt:
# md = ""
# if fmt == self.FMT_FNOTE: # Insert buffer with previous format
# if data in self._footnotes: cursor.insertText(text[start:pos], cFmt)
# index = len(self._usedNotes) + 1
# self._usedNotes[data] = index # Construct next format
# md = f"[{index}]" if fmt == self.FMT_B_B:
# else: cFmt.setFontWeight(self._bold)
# md = "[ERR]" elif fmt == self.FMT_B_E:
# else: cFmt.setFontWeight(self._normal)
# md = tags.get(fmt, "") elif fmt == self.FMT_I_B:
# temp = f"{temp[:pos]}{md}{temp[pos:]}" cFmt.setFontItalic(True)
return temp, fmt elif fmt == self.FMT_I_E:
cFmt.setFontItalic(False)
elif fmt == self.FMT_D_B:
cFmt.setFontStrikeOut(True)
elif fmt == self.FMT_D_E:
cFmt.setFontStrikeOut(False)
elif fmt == self.FMT_U_B:
cFmt.setFontUnderline(True)
elif fmt == self.FMT_U_E:
cFmt.setFontUnderline(False)
elif fmt == self.FMT_M_B:
cFmt.setBackground(SHARED.theme.colMark)
elif fmt == self.FMT_M_E:
cFmt.setBackground(bgCol)
elif fmt == self.FMT_SUP_B:
cFmt.setVerticalAlignment(QtVAlignSuper)
elif fmt == self.FMT_SUP_E:
cFmt.setVerticalAlignment(QtVAlignNormal)
elif fmt == self.FMT_SUB_B:
cFmt.setVerticalAlignment(QtVAlignSub)
elif fmt == self.FMT_SUB_E:
cFmt.setVerticalAlignment(QtVAlignNormal)
elif fmt == self.FMT_FNOTE:
cFmt.setVerticalAlignment(QtVAlignSuper)
if data in self._footnotes:
index = len(self._usedNotes) + 1
self._usedNotes[data] = index
cursor.insertText(f"[{index}]", cFmt)
else:
cursor.insertText("[ERR]", cFmt)
cFmt.setVerticalAlignment(QtVAlignNormal)
# Move pos for next pass
start = pos
# Insert whatever is left in the buffer
cursor.insertText(text[start:], cFmt)
return
def _formatKeywords(self, text: str, style: int) -> str: def _formatKeywords(self, text: str, style: int) -> str:
"""Apply Markdown formatting to keywords.""" """Apply Markdown formatting to keywords."""
+1 -1
View File
@@ -40,7 +40,7 @@ from PyQt5.QtWidgets import (
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.common import cssCol from novelwriter.common import cssCol
from novelwriter.constants import nwHeaders, nwUnicode from novelwriter.constants import nwHeaders, nwUnicode
from novelwriter.core.toqdocument import ToQTextDocument from novelwriter.core.toqdoc import ToQTextDocument
from novelwriter.enum import nwDocAction, nwDocMode, nwItemType from novelwriter.enum import nwDocAction, nwDocMode, nwItemType
from novelwriter.error import logException from novelwriter.error import logException
from novelwriter.extensions.eventfilters import WheelEventFilter from novelwriter.extensions.eventfilters import WheelEventFilter
+5 -1
View File
@@ -24,7 +24,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
from __future__ import annotations from __future__ import annotations
from PyQt5.QtCore import QRegularExpression, Qt from PyQt5.QtCore import QRegularExpression, Qt
from PyQt5.QtGui import QColor, QFont, QPainter, QTextCursor, QTextFormat from PyQt5.QtGui import QColor, QFont, QPainter, QTextCharFormat, QTextCursor, QTextFormat
from PyQt5.QtWidgets import QDialogButtonBox, QSizePolicy, QStyle from PyQt5.QtWidgets import QDialogButtonBox, QSizePolicy, QStyle
# Qt Alignment Flags # Qt Alignment Flags
@@ -44,6 +44,10 @@ QtAlignRightMiddle = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter
QtAlignRightTop = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop QtAlignRightTop = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop
QtAlignTop = Qt.AlignmentFlag.AlignTop QtAlignTop = Qt.AlignmentFlag.AlignTop
QtVAlignNormal = QTextCharFormat.VerticalAlignment.AlignNormal
QtVAlignSub = QTextCharFormat.VerticalAlignment.AlignSubScript
QtVAlignSuper = QTextCharFormat.VerticalAlignment.AlignSuperScript
# Qt Page Break # Qt Page Break
QtPageBreakBefore = QTextFormat.PageBreakFlag.PageBreak_AlwaysBefore QtPageBreakBefore = QTextFormat.PageBreakFlag.PageBreak_AlwaysBefore