From c20d5fcc392f52198bf5fde22f76f2807b5272d8 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Thu, 31 Oct 2019 21:45:00 +0100 Subject: [PATCH] The preview now generates clickable links --- nw/convert/text/tohtml.py | 53 +++++++++++++++++++++++++++-- nw/gui/elements/docviewer.py | 64 ++++++++++++++++++++++++++++++++---- nw/project/index.py | 7 ++++ 3 files changed, 115 insertions(+), 9 deletions(-) diff --git a/nw/convert/text/tohtml.py b/nw/convert/text/tohtml.py index 64ddbbb7..3a67df48 100644 --- a/nw/convert/text/tohtml.py +++ b/nw/convert/text/tohtml.py @@ -23,6 +23,18 @@ class ToHtml(Tokenizer): def __init__(self, theProject, theParent): Tokenizer.__init__(self, theProject, theParent) + self.forPreview = False + return + + def setPreview(self, forPreview): + """If we're using this class to generate markdown preview, we need to make a few changes to + formatting, which is selected by this flag. + """ + + self.forPreview = forPreview + if forPreview: + self.doKeywords = True + return def doAutoReplace(self): @@ -103,10 +115,45 @@ class ToHtml(Tokenizer): self.theResult += "
%s
\n" % tText elif tType == self.T_KEYWORD and self.doKeywords: - self.theResult += "
@%s
\n" % tText - - # print(self.theResult) + self.theResult += self._formatTags(tText) return + ## + # Internal Functions + ## + + def _formatTags(self, tText): + + if not self.forPreview: + return "
@%s
\n" % tText + + theLabel = { + "@tag" : "Tag", + "@pov" : "Point of View", + "@char" : "Character(s)", + "@plot" : "Plot", + "@time" : "Time", + "@location" : "Location(s)", + "@object" : "Object(s)", + "@custom" : "Custom", + } + + tText = "@"+tText + isValid, theBits, thePos = self.theParent.theIndex.scanThis(tText) + if not isValid or not theBits: + return "" + + retText = "" + refTags = [] + if theBits[0] in theLabel: + retText += "%s: " % theLabel[theBits[0]] + for tTag in theBits[1:]: + refTags.append("%s" % ( + theBits[0][1:], tTag, tTag + )) + retText += ", ".join(refTags) + + return "
%s
" % retText + # END Class ToHtml diff --git a/nw/gui/elements/docviewer.py b/nw/gui/elements/docviewer.py index 3ae4d40c..b669b2d2 100644 --- a/nw/gui/elements/docviewer.py +++ b/nw/gui/elements/docviewer.py @@ -19,7 +19,7 @@ from PyQt5.QtGui import QTextOption, QFont, QPalette, QColor from nw.convert.tokenizer import Tokenizer from nw.convert.text.tohtml import ToHtml -from nw.enum import nwItemType +from nw.enum import nwAlert, nwItemType logger = logging.getLogger(__name__) @@ -46,6 +46,8 @@ class GuiDocViewer(QTextBrowser): theOpt.setAlignment(Qt.AlignJustify) self.qDocument.setDefaultTextOption(theOpt) + self.anchorClicked.connect(self._linkClicked) + logger.debug("DocViewer initialisation complete") return @@ -102,6 +104,7 @@ class GuiDocViewer(QTextBrowser): logger.debug("Generating preview for item %s" % tHandle) sPos = self.verticalScrollBar().value() aDoc = ToHtml(self.theProject, self.theParent) + aDoc.setPreview(True) aDoc.setText(tHandle) aDoc.doAutoReplace() aDoc.tokenizeText() @@ -139,22 +142,59 @@ class GuiDocViewer(QTextBrowser): # Internal Functions ## + def _linkClicked(self, theURL): + + theLink = theURL.url() + tHandle = None + onLine = 0 + theTag = "" + if len(theLink) > 0: + theBits = theLink.split("=") + if len(theBits) == 2: + theTag = theBits[1] + tHandle, onLine = self.theParent.theIndex.getTagSource(theBits[1]) + + if tHandle is None: + self.theParent.makeAlert(( + "Could not find the reference for tag '%s'. It either doesn't exist, or the index " + "is out of date. The index can be updated from the Tools menu.") % theTag, + nwAlert.ERROR + ) + return + else: + self.loadText(tHandle) + + return + def _makeStyleSheet(self): - self.qDocument.setDefaultStyleSheet(( + styleSheet = ( "body {{" - " font-size: {textSize}pt;" + " font-size: {textSize:.1f}pt;" " color: rgb({tColR},{tColG},{tColB});" "}}\n" - "h1, h2, h3, h4 {{" + "h1 {{" " color: rgb({hColR},{hColG},{hColB});" + " font-size: {h1Size:.1f}pt;" + "}}\n" + "h2 {{" + " color: rgb({hColR},{hColG},{hColB});" + " font-size: {h2Size:.1f}pt;" + "}}\n" + "h3 {{" + " color: rgb({hColR},{hColG},{hColB});" + " font-size: {h3Size:.1f}pt;" + "}}\n" + "h4 {{" + " color: rgb({hColR},{hColG},{hColB});" + " font-size: {h4Size:.1f}pt;" "}}\n" "a {{" " color: rgb({aColR},{aColG},{aColB});" "}}\n" "pre {{" " color: rgb({cColR},{cColG},{cColB});" - " font-size: {preSize}pt;" + " font-size: {preSize:.1f}pt;" "}}\n" "mark {{" " color: rgb({eColR},{eColG},{eColB});" @@ -165,9 +205,17 @@ class GuiDocViewer(QTextBrowser): "td {{" " padding: 0px 4px;" "}}\n" + ".tags {{" + " color: rgb({kColR},{kColG},{kColB});" + " font-wright: bold;" + "}}\n" ).format( textSize = self.mainConf.textSize, preSize = self.mainConf.textSize*0.9, + h1Size = self.mainConf.textSize*1.8, + h2Size = self.mainConf.textSize*1.6, + h3Size = self.mainConf.textSize*1.4, + h4Size = self.mainConf.textSize*1.2, tColR = self.theTheme.colText[0], tColG = self.theTheme.colText[1], tColB = self.theTheme.colText[2], @@ -183,7 +231,11 @@ class GuiDocViewer(QTextBrowser): aColR = self.theTheme.colLink[0], aColG = self.theTheme.colLink[1], aColB = self.theTheme.colLink[2], - )) + kColR = self.theTheme.colKey[0], + kColG = self.theTheme.colKey[1], + kColB = self.theTheme.colKey[2], + ) + self.qDocument.setDefaultStyleSheet(styleSheet) return True diff --git a/nw/project/index.py b/nw/project/index.py index a5b6968c..86236a61 100644 --- a/nw/project/index.py +++ b/nw/project/index.py @@ -341,6 +341,13 @@ class NWIndex(): return theRefs + def getTagSource(self, theTag): + if theTag in self.tagIndex: + theRef = self.tagIndex[theTag] + if len(theRef) == 3: + return theRef[1], theRef[0] + return None, 0 + def buildTagNovelMap(self, theTags, theFilters=None): tagMap = {}