diff --git a/novelwriter/constants.py b/novelwriter/constants.py index 9567c3bb..5579e8a3 100644 --- a/novelwriter/constants.py +++ b/novelwriter/constants.py @@ -70,6 +70,24 @@ class nwRegEx: # END Class nwRegEx +class nwShortcode: + + BOLD_O = "[b]" + BOLD_C = "[/b]" + ITALIC_O = "[i]" + ITALIC_C = "[/i]" + STRIKE_O = "[s]" + STRIKE_C = "[/s]" + ULINE_O = "[u]" + ULINE_C = "[/u]" + SUP_O = "[sup]" + SUP_C = "[/sup]" + SUB_O = "[sub]" + SUB_C = "[/sub]" + +# END Class nwShortcode + + class nwHeaders: H_VALID = ("H0", "H1", "H2", "H3", "H4") diff --git a/novelwriter/core/tokenizer.py b/novelwriter/core/tokenizer.py index c1a51181..63518ca7 100644 --- a/novelwriter/core/tokenizer.py +++ b/novelwriter/core/tokenizer.py @@ -37,7 +37,7 @@ from PyQt5.QtCore import QCoreApplication, QRegularExpression from novelwriter.enum import nwItemLayout from novelwriter.common import formatTimeStamp, numberToRoman, checkInt -from novelwriter.constants import nwHeadFmt, nwRegEx, nwUnicode +from novelwriter.constants import nwHeadFmt, nwRegEx, nwShortcode, nwUnicode from novelwriter.core.project import NWProject logger = logging.getLogger(__name__) @@ -180,12 +180,12 @@ class Tokenizer(ABC): self._rxShortCodeVals = QRegularExpression(nwRegEx.FMT_SV) self._shortCodeFmt = { - "[i]": self.FMT_I_B, "[/i]": self.FMT_I_E, - "[b]": self.FMT_B_B, "[/b]": self.FMT_B_E, - "[s]": self.FMT_D_B, "[/s]": self.FMT_D_E, - "[u]": self.FMT_U_B, "[/u]": self.FMT_U_E, - "[sup]": self.FMT_SUP_B, "[/sup]": self.FMT_SUP_E, - "[sub]": self.FMT_SUB_B, "[/sub]": self.FMT_SUB_E, + nwShortcode.ITALIC_O: self.FMT_I_B, nwShortcode.ITALIC_C: self.FMT_I_E, + nwShortcode.BOLD_O: self.FMT_B_B, nwShortcode.BOLD_C: self.FMT_B_E, + nwShortcode.STRIKE_O: self.FMT_D_B, nwShortcode.STRIKE_C: self.FMT_D_E, + nwShortcode.ULINE_O: self.FMT_U_B, nwShortcode.ULINE_C: self.FMT_U_E, + nwShortcode.SUP_O: self.FMT_SUP_B, nwShortcode.SUP_C: self.FMT_SUP_E, + nwShortcode.SUB_O: self.FMT_SUB_B, nwShortcode.SUB_C: self.FMT_SUB_E, } return diff --git a/novelwriter/enum.py b/novelwriter/enum.py index 86849af3..3d652266 100644 --- a/novelwriter/enum.py +++ b/novelwriter/enum.py @@ -109,6 +109,12 @@ class nwDocAction(Enum): ALIGN_R = 26 INDENT_L = 27 INDENT_R = 28 + SC_ITALIC = 29 + SC_BOLD = 30 + SC_STRIKE = 31 + SC_ULINE = 32 + SC_SUP = 33 + SC_SUB = 34 # END Enum nwDocAction diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 4d2e4556..e9094c8b 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -53,7 +53,7 @@ from PyQt5.QtWidgets import ( from novelwriter import CONFIG, SHARED from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwItemClass, nwTrinary from novelwriter.common import minmax, transferCase -from novelwriter.constants import nwKeyWords, nwLabels, nwUnicode, trConst +from novelwriter.constants import nwKeyWords, nwLabels, nwShortcode, nwUnicode, trConst from novelwriter.core.item import NWItem from novelwriter.core.index import countWords from novelwriter.core.document import NWDocument @@ -713,6 +713,18 @@ class GuiDocEditor(QPlainTextEdit): self._formatBlock(nwDocAction.INDENT_L) elif action == nwDocAction.INDENT_R: self._formatBlock(nwDocAction.INDENT_R) + elif action == nwDocAction.SC_ITALIC: + self._wrapSelection(nwShortcode.ITALIC_O, nwShortcode.ITALIC_C) + elif action == nwDocAction.SC_BOLD: + self._wrapSelection(nwShortcode.BOLD_O, nwShortcode.BOLD_C) + elif action == nwDocAction.SC_STRIKE: + self._wrapSelection(nwShortcode.STRIKE_O, nwShortcode.STRIKE_C) + elif action == nwDocAction.SC_ULINE: + self._wrapSelection(nwShortcode.ULINE_O, nwShortcode.ULINE_C) + elif action == nwDocAction.SC_SUP: + self._wrapSelection(nwShortcode.SUP_O, nwShortcode.SUP_C) + elif action == nwDocAction.SC_SUB: + self._wrapSelection(nwShortcode.SUB_O, nwShortcode.SUB_C) else: logger.debug("Unknown or unsupported document action '%s'", str(action)) self._allowAutoReplace(True) diff --git a/novelwriter/gui/mainmenu.py b/novelwriter/gui/mainmenu.py index 45374ada..7fe5a48d 100644 --- a/novelwriter/gui/mainmenu.py +++ b/novelwriter/gui/mainmenu.py @@ -637,6 +637,36 @@ class GuiMainMenu(QMenuBar): # Format > Separator self.fmtMenu.addSeparator() + # Shortcodes + self.mShortcodes = self.fmtMenu.addMenu(self.tr("More Options ...")) + + # Shortcode Italic + self.aScItalic = self.mShortcodes.addAction(self.tr("Italics Shortcode")) + self.aScItalic.triggered.connect(lambda: self._docAction(nwDocAction.SC_ITALIC)) + + # Shortcode Bold + self.aScBold = self.mShortcodes.addAction(self.tr("Bold Shortcode")) + self.aScBold.triggered.connect(lambda: self._docAction(nwDocAction.SC_BOLD)) + + # Shortcode Underline + self.aScULine = self.mShortcodes.addAction(self.tr("Underline Shortcode")) + self.aScULine.triggered.connect(lambda: self._docAction(nwDocAction.SC_ULINE)) + + # Shortcode Strikethrough + self.aScStrike = self.mShortcodes.addAction(self.tr("Strikethrough Shortcode")) + self.aScStrike.triggered.connect(lambda: self._docAction(nwDocAction.SC_STRIKE)) + + # Shortcode Superscript + self.aScSuper = self.mShortcodes.addAction(self.tr("Superscript")) + self.aScSuper.triggered.connect(lambda: self._docAction(nwDocAction.SC_SUP)) + + # Shortcode Subscript + self.aScSub = self.mShortcodes.addAction(self.tr("Subscript")) + self.aScSub.triggered.connect(lambda: self._docAction(nwDocAction.SC_SUB)) + + # Format > Separator + self.fmtMenu.addSeparator() + # Format > Header 1 (Partition) self.aFmtHead1 = QAction(self.tr("Header 1 (Partition)"), self) self.aFmtHead1.setShortcut("Ctrl+1")