Skip to content

Commit

Permalink
Merge 43ae9da into 0c91cbc
Browse files Browse the repository at this point in the history
  • Loading branch information
Omikhleia committed Jan 23, 2024
2 parents 0c91cbc + 43ae9da commit cd019aa
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
5 changes: 5 additions & 0 deletions documentation/c07-settings.sil
Expand Up @@ -189,6 +189,11 @@ Note that non-breaking spaces (U+00A0), following the guidelines of Unicode Anne

If you want to disable this behavior, the \autodoc:setting{languages.fixedNbsp} setting may be set to \code{true} to enforce fixed-width non-breaking spaces.

Some typography conventions use an em-dash at the start of a paragraph line to denote a speaker change in a dialogue.
This is the case in particular in French and Turkish typography.
By default, all spaces following an em-dash at the beginning of a paragraph in your input are replaced by a single \em{fixed} inter-word space, so that subsequent dialogue lines all start identically, while other inter-word spaces may still be variable for justification purposes.
To cancel this behavior, the \autodoc:setting{typesetter.fixedSpacingAfterInitialEmdash} setting may be set to \code{false}.

\subsection{Letter spacing settings}

You can also put spaces in between \em{letters} with the \autodoc:setting{document.letterspaceglue} setting.
Expand Down
70 changes: 70 additions & 0 deletions tests/feat-emdash-dialogue.expected
@@ -0,0 +1,70 @@
Set paper size 209.7637818 297.6377985
Begin page
Mx 10.4882
My 31.5323
Set font Gentium Plus;22;400;;normal;;;LTR
T 179 w=16.8545 (—)
Mx 33.1564
T 47 82 85 72 80 w=58.0830 (Lorem)
Mx 102.5788
T 76 83 86 88 80 w=55.4404 (ipsum)
Mx 169.3586
T 71 82 w=22.5049 (do)
Mx 191.8635
T 16 w=7.4121 (-)
Mx 10.4882
My 57.9323
T 79 82 85 w=25.7383 (lor)
Mx 49.1531
T 86 76 87 w=22.0322 (sit)
Mx 71.1853
T 17 w=5.0381 (.)
Mx 89.1500
T 179 w=16.8545 (—)
Mx 118.9310
T 54 72 71 w=32.0762 (Sed)
Mx 163.9338
T 81 82 81 w=35.3418 (non)
Mx 10.4882
My 84.3323
T 85 76 86 88 86 w=43.3232 (risus)
Mx 53.8114
T 17 w=5.0381 (.)
Mx 10.4882
My 110.7323
T 179 w=16.8545 (—)
Mx 33.1564
T 49 82 81 w=37.4795 (Non)
Mx 70.6358
T 17 w=5.0381 (.)
Mx 10.4882
My 137.1323
T 179 w=16.8545 (—)
Mx 36.8402
T 47 82 85 72 80 w=58.0830 (Lorem)
Mx 104.4207
T 76 83 86 88 80 w=55.4404 (ipsum)
Mx 169.3586
T 71 82 w=22.5049 (do)
Mx 191.8635
T 16 w=7.4121 (-)
Mx 10.4882
My 163.5323
T 79 82 85 w=25.7383 (lor)
Mx 49.1531
T 86 76 87 w=22.0322 (sit)
Mx 71.1853
T 17 w=5.0381 (.)
Mx 89.1500
T 179 w=16.8545 (—)
Mx 118.9310
T 54 72 71 w=32.0762 (Sed)
Mx 163.9338
T 81 82 81 w=35.3418 (non)
Mx 10.4882
My 189.9323
T 85 76 86 88 86 w=43.3232 (risus)
Mx 53.8114
T 17 w=5.0381 (.)
End page
Finish
16 changes: 16 additions & 0 deletions tests/feat-emdash-dialogue.sil
@@ -0,0 +1,16 @@
\begin[papersize=a7]{document}
\nofolios
\neverindent
\font[size=22pt]
\set[parameter=linebreak.emergencyStretch, value=50pt]

% Affect paragraph-leading em-dash but not later...
— Lorem ipsum dolor sit. — Sed non risus.

— Non.

\set[parameter=typesetter.fixedSpacingAfterInitialEmdash, value=false]

— Lorem ipsum dolor sit. — Sed non risus.

\end{document}
45 changes: 45 additions & 0 deletions typesetters/base.lua
Expand Up @@ -145,6 +145,13 @@ function typesetter.declareSettings(_)
default = false,
help = "When true, a warning is issued when a soft hyphen is encountered"
})

SILE.settings:declare({
parameter = "typesetter.fixedSpacingAfterInitialEmdash",
type = "boolean",
default = true,
help = "When true, em-dash starting a paragraph is considered as a speaker change in a dialogue"
})
end

function typesetter:initState ()
Expand Down Expand Up @@ -330,6 +337,31 @@ function typesetter:endline ()
SILE.documentState.documentClass.endPar(self)
end

-- Just compute once, to avoid unicode characters in source code.
local speakerChangePattern = "^"
.. luautf8.char(0x2014) -- emdash
.. "[ " .. luautf8.char(0x00A0) .. luautf8.char(0x202F) -- regular space or NBSP or NNBSP
.. "]+"
local speakerChangeReplacement = luautf8.char(0x2014) .. " "

-- Special unshaped node subclass to handle space after a speaker change in dialogues
-- introduced by an em-dash.
local speakerChangeNode = pl.class(SILE.nodefactory.unshaped)
function speakerChangeNode:shape()
local node = self._base.shape(self)
local spc = node[2]
if spc and spc.is_glue then
-- Switch the variable space glue to a fixed kern
node[2] = SILE.nodefactory.kern({ width = spc.width.length })
node[2].parent = self.parent
else
-- Should not occur:
-- How could it possibly be shaped differently?
SU.warn("Speaker change logic met an unexpected case, this might be a bug.")
end
return node
end

-- Takes string, writes onto self.state.nodes
function typesetter:setpar (text)
text = text:gsub("\r?\n", " "):gsub("\t", " ")
Expand All @@ -338,6 +370,19 @@ function typesetter:setpar (text)
text = text:gsub("^%s+", "")
end
self:initline()

if SILE.settings:get("typesetter.fixedSpacingAfterInitialEmdash") and not SILE.settings:get("typesetter.obeyspaces") then
local speakerChange = false
local dialogue = luautf8.gsub(text, speakerChangePattern, function ()
speakerChange = true
return speakerChangeReplacement
end)
if speakerChange then
local node = speakerChangeNode({ text = dialogue, options = SILE.font.loadDefaults({})})
self:pushHorizontal(node)
return -- done here: speaker change space handling is done after nnode shaping
end
end
end
if #text >0 then
self:pushUnshaped({ text = text, options= SILE.font.loadDefaults({})})
Expand Down

0 comments on commit cd019aa

Please sign in to comment.