8

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}

pdf output

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.

update 4 pdf output

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

\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\printunit{\bibsentence}\addspace}

\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}
\addbibresource{example.bib}

\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}
\addbibresource{example.bib}

\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}

pdf output update

  • 2
    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. – ebosi May 10 '17 at 14:41
  • It's indeed a good package, but unfortunately I cannot find anything about my issue in the documentation. – svenper May 10 '17 at 14:50
  • 1
    Does tex.stackexchange.com/questions/10455/… help? – Paul Stanley May 10 '17 at 15:29
  • So this is really more of a font issue? They're definitely on to something, but they use {Lua,Xe}LaTeX which makes it incompatible with microtype. I should have specified this in the question. – svenper May 10 '17 at 15:48
  • 1
    Maybe csquotes might help. Maybe tex.stackexchange.com/questions/115883/… can be adjusted? – user36296 May 10 '17 at 16:22
8

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

\documentclass{minimal}
\directlua{
fonts.handlers.otf.addfeature {
    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:

period-quote kerns

6

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

\documentclass{article}
\usepackage{fontspec}
\directlua
{
  fonts.handlers.otf.addfeature
  {
    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}

output of example

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

5

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}

enter image description here

1

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}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.