Skip to content

Commit

Permalink
Update first line indentation (#1898)
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo authored May 28, 2024
2 parents b387150 + dc6fe77 commit 931aed6
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 77 deletions.
10 changes: 5 additions & 5 deletions novelwriter/core/tohtml.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
from pathlib import Path
from time import time

from novelwriter import CONFIG
from novelwriter.common import formatTimeStamp
from novelwriter.constants import nwHeadFmt, nwHtmlUnicode, nwKeyWords, nwLabels
from novelwriter.core.project import NWProject
Expand Down Expand Up @@ -184,7 +183,6 @@ def doConvert(self) -> None:

if tStyle & self.A_PBB:
aStyle.append("page-break-before: always;")

if tStyle & self.A_PBA:
aStyle.append("page-break-after: always;")

Expand All @@ -194,11 +192,13 @@ def doConvert(self) -> None:
aStyle.append("margin-top: 0;")

if tStyle & self.A_IND_L:
aStyle.append(f"margin-left: {CONFIG.tabWidth:d}px;")
aStyle.append(f"margin-left: {self._blockIndent:.2f}em;")
if tStyle & self.A_IND_R:
aStyle.append(f"margin-right: {CONFIG.tabWidth:d}px;")
aStyle.append(f"margin-right: {self._blockIndent:.2f}em;")
if tStyle & self.A_IND_T:
aStyle.append(f"text-indent: {self._firstWidth:.2f}em;")

if len(aStyle) > 0:
if aStyle:
stVals = " ".join(aStyle)
hStyle = f" style='{stVals}'"
else:
Expand Down
34 changes: 32 additions & 2 deletions novelwriter/core/tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ class Tokenizer(ABC):
A_Z_BTMMRG = 0x0080 # Zero bottom margin
A_IND_L = 0x0100 # Left indentation
A_IND_R = 0x0200 # Right indentation
A_IND_T = 0x0400 # Text indentation

# Masks
M_ALIGNED = A_LEFT | A_RIGHT | A_CENTRE | A_JUSTIFY

# Lookups
L_HEADINGS = [T_TITLE, T_HEAD1, T_HEAD2, T_HEAD3, T_HEAD4]
Expand Down Expand Up @@ -839,13 +843,20 @@ def tokenizeText(self) -> None:
pLines: list[T_Token] = []

tCount = len(tokens)
pIndent = True
for n, cToken in enumerate(tokens):

if n > 0:
pToken = tokens[n-1] # Look behind
if n < tCount - 1:
nToken = tokens[n+1] # Look ahead

if not self._indentFirst and cToken[0] in self.L_SKIP_INDENT:
# Unless the indentFirst flag is set, we set up the next
# paragraph to not be indented if we see a block of a
# specific type
pIndent = False

if cToken[0] == self.T_EMPTY:
# We don't need to keep the empty lines after this pass
pass
Expand All @@ -864,21 +875,40 @@ def tokenizeText(self) -> None:
elif cToken[0] == self.T_TEXT:
# Combine lines from the same paragraph
pLines.append(cToken)

if nToken[0] != self.T_TEXT:
# Next token is not text, so we add the buffer to tokens
nLines = len(pLines)
cStyle = pLines[0][4]
if self._firstIndent and pIndent and not cStyle & self.M_ALIGNED:
# If paragraph indentation is enabled, not temporarily
# turned off, and the block is not aligned, we add the
# text indentation flag
cStyle |= self.A_IND_T

if nLines == 1:
self._tokens.append(pLines[0])
# The paragraph contains a single line, so we just
# save that directly to the token list
self._tokens.append((
self.T_TEXT, pLines[0][1], pLines[0][2], pLines[0][3], cStyle
))
elif nLines > 1:
# The paragraph contains multiple lines, so we need to
# join them according to the line break policy, and
# recompute all the formatting markers
tTxt = ""
tFmt: T_Formats = []
for aToken in pLines:
tLen = len(tTxt)
tTxt += f"{aToken[2]}{lineSep}"
tFmt.extend((p+tLen, fmt, key) for p, fmt, key in aToken[3])
self._tokens.append((
self.T_TEXT, pLines[0][1], tTxt[:-1], tFmt, pLines[0][4]
self.T_TEXT, pLines[0][1], tTxt[:-1], tFmt, cStyle
))

# Reset buffer and make sure text indent is on for next pass
pLines = []
pIndent = True

else:
self._tokens.append(cToken)
Expand Down
10 changes: 3 additions & 7 deletions novelwriter/core/toodt.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,6 @@ def doConvert(self) -> None:
self._result = "" # Not used, but cleared just in case

xText = self._xText
pIndent = True
for tType, _, tText, tFormat, tStyle in self._tokens:

# Styles
Expand All @@ -455,7 +454,6 @@ def doConvert(self) -> None:

if tStyle & self.A_PBB:
oStyle.setBreakBefore("page")

if tStyle & self.A_PBA:
oStyle.setBreakAfter("page")

Expand All @@ -469,16 +467,14 @@ def doConvert(self) -> None:
if tStyle & self.A_IND_R:
oStyle.setMarginRight(self._fBlockIndent)

if not self._indentFirst and tType in self.L_SKIP_INDENT:
pIndent = False

# Process Text Types
if tType == self.T_TEXT:
if self._firstIndent and pIndent and oStyle.isUnaligned():
# Text indentation is processed here because there is a
# dedicated pre-defined style for it
if tStyle & self.A_IND_T:
self._addTextPar(xText, S_FIND, oStyle, tText, tFmt=tFormat)
else:
self._addTextPar(xText, S_TEXT, oStyle, tText, tFmt=tFormat)
pIndent = True

elif tType == self.T_TITLE:
# Title must be text:p
Expand Down
3 changes: 3 additions & 0 deletions novelwriter/core/toqdoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ def initDocument(self, font: QFont, theme: TextDocumentTheme) -> None:
self._mSep = (mScale * self._marginSep[0], mScale * self._marginSep[1])

self._mIndent = mScale * 2.0
self._tIndent = mScale * self._firstWidth

# Block Format
# ============
Expand Down Expand Up @@ -224,6 +225,8 @@ def doConvert(self) -> None:
bFmt.setLeftMargin(self._mIndent)
if tStyle & self.A_IND_R:
bFmt.setRightMargin(self._mIndent)
if tStyle & self.A_IND_T:
bFmt.setTextIndent(self._tIndent)

if tType == self.T_TEXT:
newBlock(cursor, bFmt)
Expand Down
4 changes: 4 additions & 0 deletions novelwriter/tools/manuscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ def _generatePreview(self) -> None:
if not (build := self._getSelectedBuild()):
return

start = time()

# Make sure editor content is saved before we start
SHARED.saveDocument()

Expand Down Expand Up @@ -358,6 +360,8 @@ def _generatePreview(self) -> None:
self.docStats.updateStats(buildObj.textStats)
self.buildOutline.updateOutline(buildObj.textOutline)

logger.debug("Build completed in %.3f ms", 1000*(time()-start))

return

@pyqtSlot()
Expand Down
6 changes: 3 additions & 3 deletions sample/nwProject.nwx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="2.5b1" hexVersion="0x020500b1" fileVersion="1.5" fileRevision="4" timeStamp="2024-05-26 16:42:34">
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1932" autoCount="274" editTime="87817">
<novelWriterXML appVersion="2.5b1" hexVersion="0x020500b1" fileVersion="1.5" fileRevision="4" timeStamp="2024-05-27 12:11:38">
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1948" autoCount="277" editTime="90871">
<name>Sample Project</name>
<author>Jane Smith</author>
</project>
Expand Down Expand Up @@ -58,7 +58,7 @@
<name status="sf24ce6" import="ia857f0" active="yes">Chapter One</name>
</item>
<item handle="636b6aa9b697b" parent="6a2d6d5f4f401" root="7031beac91f75" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="no" heading="H3" charCount="2953" wordCount="520" paraCount="15" cursorPos="19" />
<meta expanded="no" heading="H3" charCount="2953" wordCount="520" paraCount="15" cursorPos="0" />
<name status="s90e6c9" import="ia857f0" active="yes">Making a Scene</name>
</item>
<item handle="bc0cbd2a407f3" parent="6a2d6d5f4f401" root="7031beac91f75" order="1" type="FILE" class="NOVEL" layout="DOCUMENT">
Expand Down
Loading

0 comments on commit 931aed6

Please sign in to comment.