Manchmal lohnt es sich, die log-Datei aufmerksam zu lesen. Dein Code liefert die Fehlermeldung
! Package xesearch Error: You can't use `.' in `Bd.',
(xesearch) it's already a string delimiter.
(xesearch) `Bd.' won't be searched .
Mein erster Gedanke war: „vielleicht hat das Paket ja Möglichkeiten zur Anpassung“ und in der Tat:
> So when does [XeSearch] stop
> searching? There are two main cases:
>
> 1. It encounters a space, or any primitive control sequence. The former
> case is quite natural: you want spaces
> to delimit words (including `\skip`s
> and associates). But the latter is
> less obvious: as soon as TeX does
> something that is not typesetting
> letters, XeSearch gives up. And this
> includes something as seemingly
> innocuous as a `\relax` [...]. That’s
> the reason why, for instance, XeSearch
> will never find `TeX` in `\TeX`: the
> definition contains many operations
> that aren’t strictly speaking putting
> letters in the stream. Fortunately,
> the bulk of a manuscript is made of
> letters and spaces, and one seldom
> inserts `\relax`es in the middle of
> words.
> 2. XeSearch encounters a character that you’ve declared as a non-letter,
> that is a word boundary. This leads us
> to the following macro:
>
> \MakeBoundary{⟨characters⟩}
> \UndoBoundary{⟨characters⟩}
>
> The basic set of such characters is as follows
>
> .,;:!?-`'()[]{}
Wenn man `\UndoBoundary{.}` zu Deinem Beispiel hinzufügt, geht es denn auch:
% arara: xelatex
\documentclass[11pt]{article}
\usepackage[ngerman]{babel}
\usepackage{xltxtra,libertine,xesearch,xspace}
\newcommand{\spat}{\kern .12em}
\newcommand{\bd}{Bd.\spat}
\newcommand{\ff}{\spat{}ff.\xspace}
\newcommand{\pag}{S.\spat}
\UndoBoundary{.}
\SearchList{bd}{\bd}{Bd.}
\SearchList{ff}{\ff}{ff.}
\SearchList{S}{\pag}{S.}
\begin{document}
Text (vgl. Werke \bd 1, \pag 12\ff) % Formatierung: Spationierung über \newcommand
Text (vgl. Werke Bd. 1, S. 12 ff.) % Autoformatierung über xesearch
\end{document}
Die beiden Zeilen sehen trotzdem nicht identisch aus, aber das liegt daran, dass die Leerzeichen nach `\bd` und `\pag` ignoriert werden also effektiv nicht da sind, während die Leerzeichen nach `Bd.` und `S.` nicht ignoiert werden und daher auch im Output landen. Durch geeignete Definitionen der Suchlisten lässte sich das aber korrigieren:
% arara: xelatex
\documentclass[11pt]{article}
\usepackage[ngerman]{babel}
\usepackage{xltxtra,libertine,xesearch,xspace}
\newcommand*{\spat}{\kern.12em\relax}
\UndoBoundary{.}
\begin{document}
% Formatierung: Spationierung über Befehle:
\newcommand*{\bd}{Bd.\spat}
\newcommand*{\ff}{\spat ff.}
\newcommand*{\pag}{S.\spat}
Text (vgl. Werke \bd 1, \pag 12\ff)
% Autoformatierung über xesearch --
% Listen im Beispiel erst hier, damit vorher inm vorigen Beispiel keine
% Doppel-Anwendung stattfindet und den Vergleich unmöglich macht:
\SearchList*!{bd}{\spat\ignorespaces}{Bd.}
\SearchList*{ff}{\unskip\spat#1}{ff.}
\SearchList*!{S}{\spat\ignorespaces}{S.}
Text (vgl. Werke Bd. 1, S. 12 ff.)
\end{document}
![alt text][1]
Ein bisschen Erklärung:
\SearchList{<Name>}{<ersetze>}{<Liste von Suchbegriffen>}
`\SearchList` sucht und ersetzt normalerweise unabhängig von Groß- und Kleinschreibung (*case-insensitive*). Bei `\SearchList*` wird Groß- und Kleinschreibung beachtet (*case-sensitive*).
Normalerweise gilt außerddem tatsächlich Suchen und *Ersetzen*. Möchte man nicht, dass ersetz wird, sondern formatiert, kann man den gefundenen Teil im `<ersetze>` mit `#1` wieder einfügen:
\SearchList{fett}{\textbf{#1}}{ich,bin,fett}
Bei der Version mit Ausrufezeichen wird das gefundene allerdings *nicht* ersetzt, sondern der `<ersetze>`-Teil *danach* eingefügt.
Das Makro `\ignorespaces` sorgt dafür, dass folgende Leerzeichen ignoriert werden. Dadurch kann das im Quelltext vorhandene Leerzeichen nach `Bd.` und `S.` ignoriert werden, sonst würde es hier zusätzlich zum mit `\spat` eingefügten Leerraum verwendet.
`\unskip` entfernet den *zuletzt* eingefügten Leerraum (sei er horizontal, vertikal, ...). Das wird hier verwendet, um das Leerzeichen, das im Quelltext vor `ff.` vorhanden ist, wieder zu entfernen. Sonst würde es hier zusätzlich zum mit `\spat` eingefügten Leerraum verwendet.
[1]: http://texwelt.de/wissen/upfiles/xesearch_1.png