Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update first line indentation #1898

Merged
merged 6 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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