[Tex/LaTex] Replace characters in string based on preceding and following character

biblatexstringstex-core

The following two strings are the result of the expansion of a biblatex citation command:

Unicom Computer Corp. (in re), 13 F.3d 321, 30 Collier Bankr. Cas. 2d 655, 25 Bankr. Ct. Dec. 152 (9th Cir. 1994)

Personal Property Security Act (P.E.I.), R.S.P.E.I. 1988, c. P-3.1

What I want to do is wrap the biblatex citation command in a macro that will replace all dots, with a replacement character determined by the following condition set:

  1. If the character to the right of the dot is not a number, the dot should be removed entirely.

  2. If the character to the right of the dot is a number, and the character to the left of the dot is a number, the dot should be replaced by a dot, that is the dot should be kept in place.

  3. If the character to the right of the dot is a number, and the character to the left of the dot is not a number, the dot should be replaced by a space.

Applying the conditions on the example strings above, the macro should yield the following results:

Unicom Computer Corp (in re), 13 F 3d 321, 30 Collier Bankr Cas 2d 655, 25 Bankr Ct Dec 152 (9th Cir 1994)

Personal Property Security Act (PEI), RSPEI 1988, c P-3.1

It should be noted that the dots in the examples are already in the entries in the bibtex file. The reason that the dots are in there are that certain legal citation styles require the punctuations, whereas others require they are not present, the biblatex style I am writing should have an option to turn punctuation on or off, and it seems way easier to remove dots automatically but to add them automatically.

I have looked into the xstring package, but I was not able to find an appropriate macro in there. Furthermore, I would prefer being able to do that in plain TeX, so that the resulting style can be used without too many dependencies.

Best Answer

With a simple loop, xstring is also able to do such things:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{xstring}
\def\removedot#1{%
    \def\citation{#1}%
    \loop
        \StrPosition\citation.[\dotpos]%
        \ifnum\dotpos>0
        \StrMid\citation1{\number\numexpr\dotpos-1}%
        \StrChar\citation{\number\numexpr\dotpos-1}[\antechar]%
        \StrChar\citation{\number\numexpr\dotpos+1}[\postchar]%
        \antechar
        \IfInteger\postchar{\IfInteger\antechar.{\unless\ifx\postchar\space\space\fi}}{}%
        \postchar
        \StrGobbleLeft\citation{\number\numexpr\dotpos+1}[\citation]%
    \repeat
    \citation
}
\begin{document}
\removedot{Unicom Computer Corp. (in re), 13 F.3d 321, 30 Collier Bankr. Cas. 2d 655, 25 Bankr. Ct. Dec. 152 (9th Cir. 1994)\endgraf
Personal Property Security Act (P.E.I.), R.S.P.E.I. 1988, c. P-3.1}
\end{document}

EDIT: sorry for the bug. Here is a code in which the bug is fixed and the result is stored in the macro \newcitation:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{xstring}
\def\expaddtocs#1#2{%
    \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter
    #1\expandafter\expandafter\expandafter{\expandafter#1#2}}
\def\removedot#1{%
    \def\citation{#1}\def\newcitation{}%
    \loop
        \StrPosition\citation.[\dotpos]%
        \ifnum\dotpos>0
        \StrLeft\citation{\number\numexpr\dotpos-2}[\temp]\expaddtocs\newcitation\temp
        \StrGobbleLeft\citation{\number\numexpr\dotpos-2}[\citation]%
        \StrChar\citation1[\antechar]\expaddtocs\newcitation\antechar
        \StrChar\citation3[\postchar]%
        \IfInteger\postchar
            {\IfInteger\antechar{\expaddtocs\newcitation.}{\unless\ifx\postchar\space\expaddtocs\newcitation\space\fi}}
            \relax
        \StrGobbleLeft\citation2[\citation]%
    \repeat
    \expaddtocs\newcitation\citation
    \newcitation% use the \newcitation macro
}
\begin{document}
\removedot{Unicom Computer Corp. (in re), 13 F.3d 321, 30 Collier Bankr. Cas. 2d 655, 25 Bankr. Ct. Dec. 152 (9th Cir. 1994)\endgraf
Personal Property Security Act (P.E.I.), R.S.P.E.I. 1988, c. P-3.1}
\end{document}

For sure, none of the codes shown in this thread are written with pure plain-TeX macros. It would be so hard that it is much better to use a package, either latex3 parser or xstring, both written in plain-teX.

Related Question