# Closing quotes collapse leads to unbalanced quotes in some Balto-Slavic languages

The csquotes package does a very good job automatically placing quotation marks instead of dumb quotes in the input. This works well in many languages (e.g. English, or Lithuanian ), however there is a case that it does not currently handle. That is the case when to closing quotes fall together. In Balto-Slavic languages, such as Latvian, Russian, or Belarusian this leads to unbalanced quotes, e.g.

  работа В.И. Ленина «О карикатуре на марксизм
и об «империалистическом экономизме»


That is

  The paper by V.I. Lenin «A caricature of Marxism
and «Imperialist Economism»


Note two opening quotes and only one closing quote.

Here

\usepackage{csquotes}
\MakeOuterQuote{"}
...
работа В.И. Ленина "О карикатуре на марксизм
и об "империалистическом экономизме"


would cause

! Package csquotes Error: Unbalanced groups or invalid nesting.


I have come up with a small hack that seems to place the quotes correctly in my documents, however it would be nice to have a general solution.

Here is what works for me. It is based on the following observation:

Closing quotes are the ones followed by a space or a punctuation mark, and all other quotes are opening quotes

This rule can be implemented using \new@ifnextchar command from amsgen.sty that does not ignore spaces:

\usepackage{amsgen}
\makeatletter
\def\smartquote{\new@ifnextchar\@sptoken{\rightquote}{%
\@ifnextchar.{\rightquote}{%
\@ifnextchar,{\rightquote}{%
\@ifnextchar){\rightquote}{\leftquote}}}}}
\def\leftquote{<<}
\def\rightquote{>>}
\makeatother


To bind this \smartquote to the double quote character one could use a method making double quote active:

\newcommand{\setupsmartquotes}{%
\catcode\"=\active %
\begingroup
\lccode\~=\"
\lowercase{\endgroup
\def~{\smartquote}}}


Now to override babel definitions \setupsmartquotes can be used in \AtBeginDocument and after \selectlanguage for languages that make double quotes active.

\AtBeginDocument{\setupsmartquotes}
`

This would produce the expected result: