# Overlapping quotes with periods and commas

I am looking for a way to automatically overlap quotes with periods and commas, as shown in the last two rows of the example image below. The methods I have found so far do this via macros; I want to do it completely automatically, without adding anything inside \begin and \end {document}, and ideally also work on automatically generated text like bibliographies.

Is there a package for this? Or a way to implement a dumb find/replace function in plain LaTeX macros?

\documentclass{minimal}

\begin{document}

quoted.''

quoted''.

quoted\rlap{.}''

quoted\rlap{''}.

\end{document}


# Update 4

Now I found a way to not rely on any arbitrary lengths for anything. The period/comma and quotes are perfectly overlapped, and the space after the construct seems to be the same as after the quote (double or single).

The initial case of the next bibliography field is uppercased without adding another period with \nopunct\printunit{\bibsentence}. This is trial and error, to me black magic, but it has worked for my purposes thus far.

\documentclass{article}
\usepackage[american]{babel}
\usepackage[autostyle=true,autopunct=true]{csquotes}
\usepackage{biblatex}

\begin{filecontents}{example.bib}
@incollection{smith:title,
title = {The Title of the Part},
author = {Smith, John},
year = {2017},
booktitle = {The Containing Book},
publisher = {Some Publisher},
}

\end{filecontents}

\makeatletter

\DeclareQuotePunctuation{.,}
\DeclareAutoPunct{,.}

\DeclareFieldFormat%
[article,inbook,incollection,inproceedings,patent,thesis,unpublished]%

\renewcommand*{\mktextquote}[6]{#1#2#4{%
\ifx#5.%
\ifpunct{}{\rlap{#5}}%
\else%
\ifx#5,%
\ifpunct{}{\rlap{#5}}%
\else%
\fi%
\fi%
}#3#6%
}

\makeatother

\begin{document}

here are the \verb+\textquote+'s

Hello. A kerning test.

Hello'' A kerning test.

\textquote{Hello}. A kerning test.

\textquote{Hello.} A kerning test.

Hello, A kerning test.

Hello'' A kerning test.

\textquote{Hello}, A kerning test.

\textquote{Hello,} A kerning test.

\textcite{smith:title} is saying \textquote{a thing}.

\printbibliography

\end{document}


# Update 3

I'm getting even closer. The only caveat I found so far is that you need to use \textquote{} instead of  '' for normal text. Exclamation marks and such seem to work now.

\documentclass{article}
\usepackage[american]{babel}
\usepackage[autostyle=true,autopunct=true]{csquotes}
\usepackage{biblatex}

\begin{filecontents}{example.bib}
@incollection{smith:title,
title = {The Title of the Part},
author = {Smith, John},
year = {2017},
booktitle = {The Containing Book},
publisher = {Some Publisher},
}

\end{filecontents}

\makeatletter

\DeclareQuotePunctuation{.,}
\DeclareAutoPunct{,.}

\DeclareFieldFormat
[article,inbook,incollection,inproceedings,patent,thesis,unpublished]
{title}{\textquote{#1}.\nopunct}

\renewcommand{\mktextquote}[6]{#1#2#4{%
\ifx#5.%
\ifpunct{}{\rlap{#5}}%
\else%
\ifx#5,%
\ifpunct{}{\rlap{#5}}%
\else%
\fi%
\fi%
}#3#6%
}

\makeatother

\begin{document}

here are the \verb+\textquote+'s

Hello. A kerning test.

Hello'' A kerning test.

\textquote{Hello}. A kerning test.

\textquote{Hello.} A kerning test.

Hello, A kerning test.

Hello'' A kerning test.

\textquote{Hello}, A kerning test.

\textquote{Hello,} A kerning test.

\textcite{smith:title} is saying \textquote{a thing}.

\printbibliography

\end{document}


# Update 2

I'm getting somewhere with this, though it has some weird errors with the \adddot and similar commands defined at line 153 in biblatex.def.

\documentclass{article}
\usepackage[brazilian]{babel}
\usepackage[autostyle=true,autopunct=true]{csquotes}
\usepackage{biblatex}

\begin{filecontents}{example.bib}
@inbook{smith2017,
title = {The Title of the Part},
author = {Smith, John},
booktitle = {The Containing Book},
}
\end{filecontents}

\makeatletter

% original definition of textquote from csquotes, applied to enquote as well
\renewrobustcmd*{\enquote}{%
\@ifstar
{\csq@getcargs{\csq@tquote{}{}{\csq@iqopen@i}}}
{\csq@getcargs{\csq@tquote{}{}{\csq@oqopen@i}}}}

% from biblatex.sty but replaced enquote with textquote
\renewrobustcmd*{\mkbibquote}{\textquote}
\protected\def\blx@imc@mkbibquote{%
\blx@ifuspunct\blx@usquote\textquote}

\newcommand\EatDot[2]{}
\DeclareFieldFormat[inbook]{title}{\textquote{#1}.\printunit{\space}}

\uspunctuation
\DeclareAutoPunct{.,}
\DeclareQuotePunctuation{.,}
\renewcommand{\mktextquote}[6]{#1#2#4{%
\ifx#5.%
\rlap{#5}%
\else%
\ifx#5,%
\rlap{#5}%
\else%
\fi%
\fi%
}#3#6%
}

\makeatother

\begin{document}

here are the \verb+\textquote+'s

Hello. A kerning test.

Hello'' A kerning test.

\textquote{Hello}. A kerning test.

\textquote{Hello.} A kerning test.

Hello, A kerning test.

Hello'' A kerning test.

\textquote{Hello}, A kerning test.

\textquote{Hello,} A kerning test.

\textcite{smith2017} is saying \textquote{a thing}.

\printbibliography

here are the \verb+\enquote+'s

Hello. A kerning test.

Hello'' A kerning test.

\enquote{Hello}. A kerning test.

\enquote{Hello.} A kerning test.

Hello, A kerning test.

Hello'' A kerning test.

\enquote{Hello}, A kerning test.

\enquote{Hello,} A kerning test.

\end{document}


# Update 1

Aside from some confusing spacing errors on the single quotes, and row 4 and 8 in the example image below not working, I'm getting closer. The tricky part is the double quote, as it consists of not two but three characters, making \@ifnextchar useless(?).

\documentclass{minimal}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\makeatletter

\let\normalperiod=.%
\catcode\.=\active
\let\normalcomma=,%
\catcode\,=\active
\let\normalquote='%
\catcode\'=\active

\let\tqdr=\textquotedblright%

\def.{\@ifnextchar'{\rlap{\normalperiod{}}}{\normalperiod{}}}
\def,{\@ifnextchar'{\rlap{\normalcomma{}}}{\normalcomma{}}}

\def¶#1{}% removes the character following it, useful to remove the extraneous
% single quote after the double quote gets substituted

\def'{%
\@ifnextchar.{%
\rlap{\textquoteright{}}%
} {%
\@ifnextchar,{%
\rlap{\textquoteright{}}%
} {%
\@ifnextchar'{%
\textquotedblright{}¶%
} {%
\textquoteright{}%
}%
}%
}%
}%

\makeatother

\begin{document}

This is a quote.' and this is some text

This is a quote'. and this is some text

This is a quote.'' and this is some text

This is a quote''. and this is some text

This is a quote,' and this is some text

This is a quote', and this is some text

This is a quote,'' and this is some text

This is a quote'', and this is some text

This is a quote?' and this is some text

This is a quote'? and this is some text

This is a quote?'' and this is some text

This is a quote''? and this is some text

This is a quote'' and this is some text

This is a quote' and this is some text

\end{document}


• You might want to have a look at the microtype package: I'm not sure it will fully solve your issue but it will at least make it look better. May 10, 2017 at 14:41
• It's indeed a good package, but unfortunately I cannot find anything about my issue in the documentation. May 10, 2017 at 14:50
• May 10, 2017 at 15:29
• Maybe csquotes might help. Maybe tex.stackexchange.com/questions/115883/… can be adjusted? May 10, 2017 at 16:22
• @murray I don’t think they enhance the reader’s experience. I showed how to get them, but I’m more likely to use the technique in order to loosen excessively tight quotes (as found in many Adobe typefaces). May 23, 2017 at 0:52

The following example works for me with LuaLaTeX (version 0.95 in TeXlive 2016):

\documentclass{minimal}
\directlua{
name = "kern1",
{
type = "pair",
data = {
[0x002E] = {
[0x201D] = { false, { -45, 0, -45, 0 } },
[0x2019] = { false, { -45, 0, -45, 0 } },
},
}
}
}
}
\usepackage{fontspec}
\setmainfont{Latin Modern Roman}[Ligatures=TeX,RawFeature=+kern1]
\begin{document}
quoted.''
quoted.'
\end{document}


It's based on this question and adds some negative kerning between the period and closing quotes. I don't know if I can use some relative dimensions like the width of a character, so -45 is selected by some trial and error. The result looks like this:

If you have updated luaotfload (to version 2.8), this will give the desired outcome:

\documentclass{article}
\usepackage{fontspec}
\directlua
{
{
name = "pkrn",
type = "kern",
data =
{
["comma"] = { ["quotedblright"] = -250 , ["quoteright"] = -250 },
["period"] = { ["quotedblright"] = -100 , ["quoteright"] = -100 },
},
}
}
\setmainfont{Latin Modern Roman}[
RawFeature={+pkrn}]
\begin{document}
“quoted,” “quoted.” ‘quoted,’ ‘quoted.’
\end{document}


In the standalone class, and perhaps others, this will produce errors unless you add \RequirePackage{luatex85}.

Caution notice: Use at your own risk, it might break other, potentially nice features of the csquotes package and I think something with the spacing after the quote might be off...

\documentclass{article}

\usepackage[english]{babel}
\usepackage[autostyle=true,autopunct=true]{csquotes}

\DeclareAutoPunct{.,}

% {<qopen>}{<text>}{<qclose>}{<punct>}{<apunct>}{<cite>}
\renewcommand{\mktextquote}[6]{#1#2#4#5%
\if#5.
\kern-0.75em%
\fi%
\if#5,
\kern-0.65em%
\fi%
#3#6}

\begin{document}

\textquote{quoted} normal text

\textquote{quoted}, next sentance

\textquote{quoted}. Next sentance

\end{document}


This uses the less used " as an active character to trigger the overlay with the next character. Thus, it has several limitations: it must go as ". and not ."; and it must go as ", not as '',.

\documentclass{article}
\usepackage{stackengine}
\let\svdq"
\catcode"=\active
\def"#1{\stackengine{0pt}{#1}{''}{O}{l}{F}{F}{L}}
\begin{document}
quoted".

quoted",
\end{document}