%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% file name: balancedquotes.sty (for plain TeX and LaTeX) %% Ole Michael Selberg, 25.8.1994 %% E-mail: O.M.Selberg@easteur-orient.uio.no %%------------------------------------------------------------------- %% Description: %% This file contains macros that simplify the management of quotes. %% The input: %% "...*....*..." %% will be typeset as: %% <<...<...>...>> (default) %% %% (or as: %% ,,...,...'...'' %% etc., depending on your choices.). %% %% TeX keeps track of whether full quotes (written as ") and half %% quotes (written as *) are balanced, When a quote has been omitted, %% as in: %% --- text "text in quotes more text "text in quotes" --- %% an error message is written to the screen, and a mark is put in %% the margin to the left of the line in which a final full or half %% quote followed by a letter was discovered. %% %% The macros can be used both with plain TeX and LaTeX. You can test %% them and learn how to use the commands by running the test file %% which is included in this file, after \endinput. %% Just copy all the stuff after \endinput to a new file, %% which you should name balancedquotestest.tex, and then delete it %% from this file. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \catcode`\@=11 \catcode`\_=11 \newif\ifapostrophe \newlinechar=`^^J % \def\definequotes #1#2#3#4{% \def\bquote_char{#1}\def\equote_char{#2}% \def\bhquote_char{#3}\def\ehquote_char{#4}} % \def\setquotes{\futurelet\test_token\CheckForOptArg} \def\CheckForOptArg{\ifx\test_token[ \let\next\OptArgPresent \else \let\next\OptArgAbsent \fi \next} \def\OptArgPresent[#1]#2{\csname #2#1q\endcsname} \def\OptArgAbsent #1{\csname #1q\endcsname} %--------------------------------------- % Norwegian: % \def\Nq{% Output: <<...<...>...>> \def\bquote_char {\char"13 }\def\equote_char {\char"14 }% \def\bhquote_char {\char"0E}\def\ehquote_char {\char"0F}% } \def\NCq{% Output: ,,...,...'...'' \def\bquote_char {\char"12 \apostrophe_check}% \def\equote_char {\char"11 }% \def\bhquote_char {\char"0D}\def\ehquote_char {\char"27}% \apostrophetrue} \let\NGq=\Nq \let\norwegianquotes=\Nq \let\norwegianguillemetsq=\Nq \let\norwegiancommasq=\NCq %----------------------------------------- % German: % \def\DGq{% Output: >>...>...<...<< \def\bquote_char {\char"14 }\def\equote_char {\char"13 }% \def\bhquote_char {\char"0F}\def\ehquote_char {\char"0E}% } \def\DCq{% Output: ,,...,...`...`` \def\bquote_char{\char"12 \apostrophe_check}% \def\equote_char {\char"10 }% \def\bhquote_char {\char"0D}\def\ehquote_char {\char"60}% \apostrophetrue} \let\Dq=\DCq \let\germanquotes=\DCq \let\germanguillemetsq=\DGq \let\germancommasq=\DCq %------------------------------------------ % French: % \def\Fq{% Output: <<...<<...>>...>> \def\bquote_char {\char"13\ }% \def\equote_char {\thinspace\char"14 }% \def\bhquote_char {\char"13\thinspace }% \def\ehquote_char { \char"14 }% } \def\FCq{\message{French doesn't use comma quotes! I shall choose guillemets instead.}} \let\frenchquotes=\Fq \let\FGq=\Fq \let\frenchguillemetsq=\Fq \let\frenchcommasq=\FCq %------------------------------------------ % English: % \def\GBq{% Output: `...``...''...' \def\bquote_char {\char"60 }\def\equote_char {\char"27 }% \def\bhquote_char {\char"10 }\def\ehquote_char {\char"11 }% } \def\USq{% Output: ``...`...'...'' \def\bquote_char {\char"10 }\def\equote_char {\char"11 }% \def\bhquote_char {\char"60 }\def\ehquote_char {\char"27 }% } \def\EQM{\message{English doesn't use guillmets! I shall choose normal English quotes instead.}} \let\USquotes=\USq \let\GBquotes=\GBq \let\USCq=\USq \let\GBCq=\GBq \def\GBguillemetsq{\EQM\GBq} \def\USguillemetsq{\EQM\USq} \let\englishquotes=\USq \let\englishcommasq=\USq \let\Eq=\USq \let\ECq=\USq \let\englishguillemetsq=\USguillemetsq %------------------------------------------- \def\bquote{\global\advance\quotecount by1 \bquote_char}% \def\equote{\penalty 10000 {\equote_char }\global\advance\quotecount by1 }% \def\bhquote{\bhquote_char \global\advance\hquotecount by1 }% \def\ehquote{\penalty 10000 \ehquote_char \global\advance\hquotecount by1 }% \newcount\quoteflag \newcount\quotecount \newcount\hquoteflag \newcount\hquotecount \def\hex{"} \let\star=* \catcode`\"=\active \catcode`\*=\active \def"{\begingroup\ifnum\quoteflag=0 \aftergroup\bquote\global\quoteflag=1 \else \equote\global\quoteflag=0 \aftergroup\equote_check \fi \endgroup} \def*{\begingroup\ifmmode \else\ifnum\hquoteflag=0 \bhquote\global\hquoteflag=1 \else \ehquote\global\hquoteflag=0 \aftergroup\ehquote_check \fi \fi \endgroup} \def\equote_check{\futurelet\next\equote_test} \def\ehquote_check{\futurelet\next\ehquote_test} \def\equote_test{\ifcat\noexpand\next a% \immediate\write16{^^J--->> Final full quote followed by a letter!!}\equote_warning\fi} \def\ehquote_test{\ifcat\noexpand\next a% \immediate\write16{^^J---> Final half quote followed by a letter!!}\ehquote_warning\fi} \def\quotesnumbertest{\ifodd\quotecount\immediate\write16{!! Odd number of full quotes.}\fi \ifodd\hquotecount\immediate\write16{!! Odd number of half quotes.}\fi} \def\apostrophe_check{\futurelet\next\apostrophe_test} \def\apostrophe_test{\if\next j\thinspace\fi} \def\l_note{\strut\vadjust{\kern-\dp\strutbox \vtop to 0pt{% \vss\llap{{\box0}\ \quad}} \dimen0=-\prevdepth\advance\dimen0by\dp\strutbox \penalty0\kern\dimen0 }} \def\equote_warning{{\setbox0=\hbox{\equote_char\thinspace !\quad}\l_note}} \def\ehquote_warning{{\setbox0=\hbox{\ehquote_char\thinspace !\quad}\l_note}} % %\catcode`\@=12 \catcode`\_=8 \Nq \endinput % Copy this to a new file: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% file name: balancedquotestest.tex %% Ole Michael Selberg, 25.8.1994 %% E-mail: O.M.Selberg@easteur-orient.uio.no %%------------------------------------------------------------------- %% Description: %% This file inputs the file balancedquotes.sty and tests %% the quote macros defined there. %% It works with both plain TeX and LaTeX. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newif\ifLaTeX % Is this LaTeX? \ifx\protect\undefined \else \LaTeXtrue \fi % We presuppose Cork-encoding: \def\"{\accent4}\def\\{$\backslash$}\def\<{$\lbrace$} \def\>{$\rbrace$} \overfullrule=0pt \ifLaTeX \documentstyle [balancedquotes] {article} \begin{document} \else \input balancedquotes.sty \fi \message{^^JType the name of a font with Cork encoding, ^^Je.g. dcr10:} \read16 to \dvifontname \font\dvifont=\dvifontname at 10pt \message{^^J} \dvifont \hsize=10cm \hoffset=2cm \parindent=0pt \hyphenation{Af-ten-pos-ten} \centerline{Test of {\tt balancedquotes.sty}\hfill Date:\enspace \the\month/\the\day/\the\year} \vglue 1cm %\Nq \definequotes{\char19}{\char20}{\char14}{\char15} \moveleft 10pt\vbox{\bf The command {\tt \\Nq} (\dvifont Norwegian: "...*...*..."):} \smallskip "Det er sant," sa han, "jeg har nettopp avbestilt *Aftenposten*!" "Har du det?" svarte hun forbauset. "Hvorfor spurte du ikke meg f{\o}rst?" \medskip {\leftskip20pt Equivalent commands: \smallskip \tt \\norwegianquotes ({\dvifont This is the default for Norwegian.}) \\NGq \\setquotes \ \\setquotes \ \\setquotes [guillemets]\ \\setquotes [G]\ \\norwegianguillemetsq \\definequotes \<\\char19\>\<\\char20\>\<\\char14\>\<\\char15\> } \bigskip \setquotes [commas]{norwegian} \moveleft 10pt\vbox{\bf The command {\tt \\NCq} \dvifont (Norwegian: "...*...*..."):} \smallskip "Det er sant," sa han, "jeg har nettopp avbestilt *Aftenposten*!" "Har du det?" svarte hun forbauset. "Hvorfor spurte du ikke meg f{\o}rst?" \medskip {\leftskip20pt Equivalent commands: \tt \smallskip \\setquotes [commas]\ \\setquotes [C]\ \\norwegiancommasq \\definequotes \<\\char18\>\<\\char17\>\<\\char13\>\<\\char39\> } \bigskip \Dq \moveleft 10pt\vbox{\bf The command {\tt \\Dq} \dvifont (German: "...*...*..."):} \smallskip Goethe schrieb: "Wielands *Oberon* wird als ein Meisterst\"uck angesehen." \medskip {\leftskip20pt Equivalent commands: \smallskip \tt \\germanquotes ({\dvifont This is the default for German}) \\DCq \\setquotes [commas]\ \\setquotes [C]\ \\germancommasq \\definequotes \<\\char18\>\<\\char17\>\<\\char13\>\<\\char39\> } \bigskip \DGq \moveleft 10pt\vbox{\bf The command {\tt \\DGq} \dvifont (German: "...*...*..."):} \smallskip Goethe schrieb: "Wielands *Oberon* wird als ein Meisterst\"uck angesehen." \medskip {\leftskip20pt Equivalent commands: \smallskip \tt \\setquotes [guillemets]\ \\setquotes [G]\ \\germanguillmetsq \\definequotes \<\\char20\>\<\\char19\>\<\\char15\>\<\\char14\> } \ifLaTeX \else\filbreak\fi \USq \moveleft 10pt\vbox{\bf The command {\tt \\USq} \dvifont (US English: "...*...*..."):} \smallskip Goethe wrote: "Wieland's *Oberon* is considered a masterpiece." \medskip {\leftskip20pt Equivalent commands: \smallskip \tt \\setquotes \ \\setquotes [commas]\ \\setquotes [C]\ \\UScommasq \\definequotes \<\\char16\>\<\\char17\>\<\\char96\>\<\\char39\> \\setquotes [guillmets]\ {\dvifont etc.\ will generate an error message and call} \\USq } \bigskip \GBq \moveleft 10pt\vbox{\bf The command {\tt \\GBq} \dvifont (GB English: "...*...*..."):} \smallskip Goethe wrote: "Wieland's *Oberon* is considered a masterpiece." \medskip {\leftskip20pt Equivalent commands: \smallskip \tt \\setquotes \ \\setquotes [commas]\ \\setquotes [C]\ \\GBcommasq \\definequotes \<\\char96\>\<\\char39\>\<\\char16\>\<\\char17\> \\setquotes [guillmets]\ {\dvifont etc.\ will generate an error message and call} \\GBq } \bigskip \Fq \moveleft 10pt\vbox{\bf The command {\tt \\Fq} \dvifont (French: "...*...*..."):} \smallskip On dit couramment {\it nic nie wiem\/} "je ne sais rien". \medskip {\leftskip20pt Equivalent commands: \smallskip \tt \\frenchquotes {\dvifont This is the default.} \\setquotes \ \\setquotes [guillemets]\ \\setquotes [G]\ \\frenchguillemetsq \\definequotes \<\\char19\ \>\<\\ \\char20\>\<\\char19\ \>\<\\ \\char20\> \\setquotes [commas]\ {\dvifont etc.\ will generate an error message and call} \\Fq } \bigskip \NCq \moveleft 10pt\vbox{\bf Test of error detection when quotes are unbalanced:} \smallskip "Det er sant," sa han, "jeg har nettopp avbestilt *Aftenposten*!" "Har du det? svarte hun forbauset. "Hvorfor spurte du ikke meg f{\o}rst?" \bigskip \moveleft 10pt\vbox{\bf Test of {\tt \\hex} og {\tt \\star}} \smallskip The command {\tt \\hex} is used instead of {\tt \\char\hex22} whenever {\tt \\char\hex22} does not denote a quote sign. For instance, we can write: {\tt \\char\hex41} in order to get an `A'. Here we test that the macro {\tt \\hex} works as it should: `{\tt \\char\\hex4F\\char\\hex4B}' is output as `\char\hex4F\char\hex4B'. \smallskip Instead of {\char \hex2A} we write {\tt \\star}. \def\slutt{\end{document}} {\ifLaTeX \aftergroup\slutt \fi} \bye