Replace characters in string based on preceding and following character
Here is a solution using LaTeX packages (works with l3regex
, xparse
and the expl3
bundle from 2011-10-09
onwards).
\RequirePackage{l3regex,xparse}
\ExplSyntaxOn
\tl_new:N \l_removedots_tl
\tl_new:N \l_removedots_str
\DeclareDocumentCommand{\removedots}{+v}
{
% Store the verbatim argument into a macro.
\str_set:Nn \l_removedots_str {#1}
% Remove all dots followed by a non-digit.
\regex_replace_all:nnN { \.(\D) } { \1 } \l_removedots_str
% Replace "non-digit--dot--digit" by "non-digit--space-digit".
\regex_replace_all:nnN { (\D)\.(\d) } { \1\ \2 } \l_removedots_str
% Re-tokenize the result, storing it into `\l_removedots_tl`
\tl_set_rescan:Nno \l_removedots_tl
{
\int_set:Nn \tex_newlinechar:D { `\^^M }
\int_set:Nn \tex_endlinechar:D { `\^^M }
}
\l_removedots_str
% Then simply typeset that, but you could do other things to it.
\tl_use:N \l_removedots_tl
}
\ExplSyntaxOff
\documentclass{article}
\begin{document}
\removedots |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|
\end{document}
Under the hood, this is doing a lot of work, because TeX is not well suited to regular expression parsing. It will be difficult to do the same directly in TeX primitives.
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.