diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/stex/omtext/omtext.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/stex/omtext/omtext.dtx | 850 |
1 files changed, 850 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/stex/omtext/omtext.dtx b/Master/texmf-dist/source/latex/stex/omtext/omtext.dtx new file mode 100644 index 00000000000..032d8190a8c --- /dev/null +++ b/Master/texmf-dist/source/latex/stex/omtext/omtext.dtx @@ -0,0 +1,850 @@ +% \iffalse meta-comment +% A LaTeX Class and Package for OMDoc Text Fragments +% Copyright (c) 2010 Michael Kohlhase, all rights reserved +% this file is released under the +% LaTeX Project Public License (LPPL) +% +% The development version of this file can be found at +% $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/omtext/omtext.dtx $ +% \fi +% +% \iffalse +%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01] +%<package>\ProvidesPackage{omtext}[2012/01/28 v1.0 OMDoc Text Fragments] +% +%<*driver> +\documentclass{ltxdoc} +\usepackage{url,array,omdoc,float} +\usepackage{omtext} +\usepackage[show]{ed} +\usepackage[hyperref=auto,style=alphabetic]{biblatex} +\bibliography{kwarc} +\usepackage[eso-foot,today]{svninfo} +\svnInfo $Id: omtext.dtx 1999 2012-01-28 07:32:11Z kohlhase $ +\svnKeyword $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/omtext/omtext.dtx $ +\usepackage{stex-logo} +\usepackage{../ctansvn} +\usepackage{hyperref} +\makeindex +\floatstyle{boxed} +\newfloat{exfig}{thp}{lop} +\floatname{exfig}{Example} +\def\tracissue#1{\cite{sTeX:online}, \hyperlink{http://trac.kwarc.info/sTeX/ticket/#1}{issue #1}} +\begin{document}\DocInput{omtext.dtx}\end{document} +%</driver> +% \fi +% +%\CheckSum{375} +% +% \changes{v0.4}{2008/07/22}{added index markup} +% \changes{v0.4}{2008/09/29}{augmenting the index macros with optional values} +% \changes{v0.6}{2009/07/08}{removing {\texttt{ttin}} {\texttt{{emin}}} and friends, +% they were almost never used.} +% \changes{v0.6}{2009/07/08}{renmanig {\texttt{myindex}} to {\texttt{omdoc\@ index}}, +% {\texttt{twin}} to {\texttt{\@ twin}}, and {\texttt{atwin}} to {\texttt{\@ atwin}} to +% make them packge-local} +% \changes{v0.7}{2010/02/11}{changing blockquote to sblockquote and inlinequote similarly} +% \changes{v0.9}{2010/05/25}{separated out from \texttt{omdoc.dtx}} +% \changes{v1.0}{2010/06/18}{fixing typos} +% +% \GetFileInfo{omtext.sty} +% +% \MakeShortVerb{\|} +% +% \def\omdoc{OMDoc} +% \def\latexml{{\LaTeX}ML} +% \title{{\texttt{omtext}}: Semantic Markup for Mathematical Text Fragments in {\LaTeX}\thanks{Version {\fileversion} (last revised +% {\filedate})}} +% \author{Michael Kohlhase\\ +% Jacobs University, Bremen\\ +% \url{http://kwarc.info/kohlhase}} +% \maketitle +% +% \begin{abstract} +% The |omtext| package is part of the {\sTeX} collection, a version of {\TeX/\LaTeX} that +% allows to markup {\TeX/\LaTeX} documents semantically without leaving the document +% format, essentially turning {\TeX/\LaTeX} into a document format for mathematical +% knowledge management (MKM). +% +% This package supplies an infrastructure for writing {\omdoc} text fragments in +% {\LaTeX}. +% \end{abstract} +% +%\newpage\tableofcontents\newpage +% +%\begin{omgroup}[id=sec:STR]{Introduction} +% +% The |omtext| package supplies macros and environment that allow to mark up mathematical +% texts in {\sTeX}, a version of {\TeX/\LaTeX} that allows to markup {\TeX/\LaTeX} +% documents semantically without leaving the document format, essentially turning +% {\TeX/\LaTeX} into a document format for mathematical knowledge management (MKM). The +% package supports direct translation to the {\omdoc} format~\cite{Kohlhase:omdoc1.2} +% \end{omgroup} +% +% \begin{omgroup}[id=sec:user]{The User Interface} +% +% \begin{omgroup}[id=sec:user:options]{Package Options} +% +% The |omtext| package takes a single option: \DescribeMacro{showmeta}|showmeta|. If +% this is set, then the metadata keys are shown (see~\cite{Kohlhase:metakeys:ctan} for +% details and customization options). +% \end{omgroup} +% +% \begin{omgroup}[id=sec:user:omtext]{Mathematical Text} +% +% The \DescribeEnv{omtext}|omtext| environment is used for any text fragment that has a +% contribution to a text that needs to be marked up. It can have a title, which can be +% specified via the \DescribeMacro{title=}|title| key. Often it is also helpful to +% annotate the \DescribeMacro{type=}|type| key. The standard relations from rhetorical +% structure theory |abstract|, |introduction|, |conclusion|, |thesis|, |comment|, +% |antithesis|, |elaboration|, |motivation|, |evidence|, |transition|, | note|, |annote| +% are recommended as values. Note that some of them are unary relations like +% |introduction|, which calls for a target. In this case, a target using the +% \DescribeMacro{for=}|for| key should be specified. The |transition| relation is +% special in that it is binary (a ``transition between two statements''), so +% additionally, a source should be specified using the \DescribeMacro{from=}|from| key. +% +% Note that the values of the |title| and |type| keys are often displayed in the +% text. This can be turned off by setting the \DescribeMacro{display=}|display| key to +% the value |flow|. Sometimes we want to specify that a text is a continuation of +% another, this can be done by giving the identifier of this in the +% \DescribeMacro{continues=}|continues| key. +% +% Finally, there is a set of keys that pertain to the mathematical formulae in the +% text. The \DescribeMacro{functions=}|functions| key allows to specify a list of +% identifiers that are to be interpreted as functions in the generate content +% markup. The \DescribeMacro{theory=}|theory| specifies a module +% (see~\cite{KohAmb:smmssl:svn}) that is to be pre-loaded in this one\ednote{this is not +% implemented yet.} Finally, \DescribeMacro{verbalizes=}|verbalizes| specifies a (more) +% formal statement (see~\cite{Kohlhase:smms:svn}) that this text verbalizes. +% \end{omgroup} +% +% \begin{omgroup}[id=sec:user:phrase]{Phrase-Level Markup} +% +% \DescribeEnv{phrase} The |phrase| environment allows to mark up phrases with semantic +% information. It takes an optional |KeyVal| argument with the keys +% \DescribeMacro{verbalizes=}|verbalizes| and \DescribeMacro{type=}|type| as above and +% \DescribeMacro{style}|style,| \DescribeMacro{class}|class|, +% \DescribeMacro{index}|index| that are disregarded in the {\LaTeX}, but copied into the +% generated content markup. +% +% \DescribeMacro{\sinlinequote} The |sinlinequote| macro allows to mark up quotes inline and +% attribute them. The quote itself is given as the argument, possibly preceded by the a +% specification of the source in a an optional argument. For instance, we would quote +% Hamlet with +% \begin{verbatim} +% \sinlinequote[Hamlet, \cite{Shak:1603:Hamlet}]{To be or not to be} +% \end{verbatim} +% which would appear as \sinlinequote[Hamlet, (Shakespeare 1603)]{To be or not to be} in +% the text. The style in which inline quotations appear in the text can be adapted by +% specializing the macros \DescribeMacro{\@sinlinequote}|\@sinlinequote| --- for quotations +% without source and \DescribeMacro{\@@sinlinequote}|\@@sinlinequote| --- for quotations with +% source. +% \end{omgroup} +% +% \begin{omgroup}[id=sec:user:block]{Block-Level Markup} +% +% \DescribeEnv{sblockquote} The |sblockquote| environment is the big brother of the +% |\sinlinequote| macro. It also takes an optional argument to specify the source. Here +% the four internal macros \DescribeMacro{\begin@sblockquote}|\begin@sblockquote| to +% \DescribeMacro{\end@@sblockquote}|\end@@sblockquote| are used for styling and can be +% adapted by package integrators. Here a quote of Hamlet would marked up as +% \begin{verbatim} +% \begin{sblockquote}[Hamlet, \cite{Shak:1603:Hamlet}]\obeylines +% To be, or not to be: that is the question: +% Whether 'tis nobler in the mind to suffer +% \end{sblockquote} +% \end{verbatim} +% and would render as +% \begin{sblockquote}[Hamlet, (Shakespeare 1603)]\obeylines +% To be, or not to be: that is the question: +% Whether 'tis nobler in the mind to suffer +% \end{sblockquote} +% +% \DescribeMacro{\lec}The |\lec| macro takes one argument and sets it as a comment at the +% end of the line, making sure that if the content is too long it is pushed into a new +% line. We use it internally for placing the of source of the |sblockquote| environment +% above. The actual appearance of the line end comment is determined by the +% \DescribeMacro{\@@lec}|\@@lec| macro, which can be customized in the document class. +% \end{omgroup} +% +% \begin{omgroup}[id=sec:user:index]{Index Markup} +% +% The |omtext| package provides some extensions for the well-known indexing macros of +% {\LaTeX}. The main reason for introducing these macros is that index markup in +% {\omdoc} wraps the indexed terms rather than just marking the spot for +% cross-referencing. Furthermore the index commands only indexes words unless +% the\DescribeMacro{noindex} |noindex| option is set in the |\usepackage|. The |omtext| +% package and class make the usual |\index| macro undefined\ednote{implement this and +% issue the respective error message}. +% +% The \DescribeMacro{\indextoo}|\indextoo| macro renders a word and marks it for the +% index. Sometimes, we want to index a slightly different form of the word, e.g. for +% non-standard plurals: while |\indextoo{word}s| works fine, we cannot use this for the +% word ``datum'', which has the plural ``data''. For this we have the macro +% \DescribeMacro{\indexalt}|\indexalt|, which takes another argument for the displayed +% text, allowing us to use |\indexalt{data}{datum}|, which prints ``data'' but puts +% ``datum'' into the index. +% +% The second set of macros adds an infrastructure for two-word compounds. Take for +% instance the compound ``OMDoc document'', which we usually want to add into the index +% under ``OMDoc'' and ``document''. \DescribeMacro{\twintoo}|\twintoo{OMDoc}{document}| +% is a variant of |\indextoo| that will do just this. Again, we have a version that +% prints a variant: This is useful for situations like this the one in +% Figure~\ref{fig:index-markup}: +% \begin{exfig} +% \begin{verbatim} +% We call group \twinalt{Abelian}{Abelian}{group}, iff \ldots +% \end{verbatim} +% \vspace*{-1em}will result in the following +% \begin{quote} +% We call group \twinalt{Abelian}{Abelian}{group}, iff \ldots +% \end{quote} +% and put ``Abelian Group'' into the index. +% \caption{Index markup}\label{fig:index-markup} +% \end{exfig} +% +% The third set of macros does the same for two-word compounds with adjectives, +% e.g. ``wonderful OMDoc +% document''. \DescribeMacro{\atwintoo}|\atwin{wonderful}{OMdoc}{document}| will make the +% necessary index entries under ``wonderful'' and ``document''. Again, we have a variant +% \DescribeMacro{\atwinalt}|\atwinalt| whose first argument is the alternative text. +% +% All index macros take an optional first argument that is used for ordering the +% respective entries in the index. +% \end{omgroup} +% \end{omgroup} +% +% +% \section{Limitations}\label{sec:limitations} +% +% In this section we document known limitations. If you want to help alleviate them, +% please feel free to contact the package author. Some of them are currently discussed in +% the \sTeX TRAC~\cite{sTeX:online}. +% \begin{compactenum} +% \item none reported yet +% \end{compactenum} +% +% \StopEventually{\newpage\PrintIndex\newpage\PrintChanges\printbibliography}\newpage +% +% \begin{omgroup}[id=sec:impl]{Implementation} +% +% The |omtext| package generates two files: the {\LaTeX} package (all the code between +% {\textsf{$\langle$*package$\rangle$}} and {\textsf{$\langle$/package$\rangle$}}) and the +% {\latexml} bindings (between {\textsf{$\langle$*ltxml$\rangle$ and +% $\langle$/ltxml$\rangle$}}). We keep the corresponding code fragments together, +% since the documentation applies to both of them and to prevent them from getting out of +% sync. +% +% \begin{omgroup}[id=sec:impl:options]{Package Options} +% +% The initial setup for {\latexml}: +% +% \begin{macrocode} +%<*ltxml> +package LaTeXML::Package::Pool; +use strict; +use LaTeXML::Package; +use Cwd qw(cwd abs_path); +%</ltxml> +% \end{macrocode} +% +% We declare some switches which will modify the behavior according to the package +% options. Generally, an option |xxx| will just set the appropriate switches to true +% (otherwise they stay false).\ednote{need an implementation for {\latexml}} +% +% \begin{macrocode} +%<*package> +\DeclareOption{showmeta}{\PassOptionsToPackage{\CurrentOption}{metakeys}} +\newif\ifindex\indextrue +\DeclareOption{noindex}{\indexfalse} +\ProcessOptions +\ifindex\makeindex\fi +%</package> +%<*ltxml> +DeclareOption('noindex',''); +%</ltxml> +% \end{macrocode} +% +% Then we need to set up the packages by requiring the |sref| package to be loaded. +% +% \begin{macrocode} +%<*package> +\RequirePackage{sref} +\RequirePackage{comment} +%</package> +%<*ltxml> +RequirePackage('sref'); +%</ltxml> +% \end{macrocode} +% \end{omgroup} +% +% \begin{omgroup}[id=sec:impl:metadata]{Metadata} +% +% All the {\omdoc} elements allow to specify metadata in them, which is modeled by the +% |omdoc:metadata| element. Since the content of this element is precisely controlled +% by the Schema, we can afford to auto-open and auto-close it. Thus metadata elements +% from various sources will just be included into one |omdoc:metadata| element, even if +% they are supplied by different {\sTeX} bindings. Also we add numbering and location +% facilities. +% +% \begin{macrocode} +%<*ltxml> +Tag('omdoc:metadata',afterOpen=>\&numberIt,afterClose=>\&locateIt,autoClose=>1,autoOpen=>1); +%</ltxml> +% \end{macrocode} +% +% the |itemize|, |description|, and |enumerate| environments generate |omdoc:li|, +% |omdoc:di| with |autoclose| inside a CMP. This behavior will be overwritten later, so we +% remember that we are in a |CMP| by assigning |_LastSeenCMP|. +% +% \begin{macrocode} +%<*ltxml> +sub declareFunctions{ + my ($stomach,$whatsit) = @_; + my $keyval = $whatsit->getArg(1); + my $funval = KeyVal($keyval,'functions') if KeyVal($keyval,'functions'); + my @funsymbs = ParseKeyValList($funval); + #Unread the function declarations at the Gullet + foreach (@funsymbs) { + $stomach->getGullet->unread(Tokenize('\lxDeclare[role=FUNCTION]{$'.$_.'$}')->unlist); + } + return; +} +Tag('omdoc:CMP', afterOpen => sub {AssignValue('_LastSeenCMP', $_[1], 'global');return;});#$ +%</ltxml> +% \end{macrocode} +% +% the |itemize|, |description|, and |enumerate| environments originally introduced in the +% |omtext| package do double duty in OMDoc, outside a |CMP| they are transformed into a +% |<omgroup layout='itemize|description|enumerate'>|, where the text after the macros +% |\item| come to be the children. If that is only text, then it is enclosed in an +% |<omtext><CMP>|, otherwise it is left as it is. The optional argument of the |\item| +% is transformed into the |<metadata><dc:title>| of the generated |\item| element. +% \begin{macrocode} +%<*ltxml> +DefParameterType('IfBeginFollows', sub { + my ($gullet) = @_; + $gullet->skipSpaces; + my $next = $gullet->readToken; + $gullet->unread($next); + $next = ToString($next); + #Hm, falling back to regexp handling, the $gullet->ifNext approach didn't work properly + return 1 unless ($next=~/^\\begin/); + return; + }, + reversion=>'', optional=>1); +%</ltxml> +% \end{macrocode} +% \end{omgroup} +% +% \begin{omgroup}[id=sec:impl:mtxt]{Mathematical Text} +% +% We define the actions that are undertaken, when the keys are encountered. Here this is +% very simple, we just define an internal macro with the value, so that we can use it +% later. Note that we allow math in the |title| field, so we do not declare it to be +% |Semiverbatim| (indeed not at all, which allows it by default). +% +% \begin{macrocode} +%<*package> +\srefaddidkey{omtext} +\addmetakey[]{omtext}{functions} +\addmetakey*{omtext}{display} +\addmetakey{omtext}{for} +\addmetakey{omtext}{from} +\addmetakey{omtext}{type} +\addmetakey*{omtext}{title} +\addmetakey*{omtext}{start} +\addmetakey{omtext}{theory} +\addmetakey{omtext}{continues} +\addmetakey{omtext}{verbalizes} +\addmetakey{omtext}{subject} +%</package> +%<*ltxml> +DefKeyVal('omtext','functions','Undigested'); +DefKeyVal('omtext','display','Semiverbatim'); +DefKeyVal('omtext','for','Semiverbatim'); +DefKeyVal('omtext','from','Semiverbatim'); +DefKeyVal('omtext','type','Semiverbatim'); +DefKeyVal('omtext','title','Plain'); #Math mode in titles. +DefKeyVal('omtext','start','Plain'); #Math mode in start phrases +DefKeyVal('omtext','theory','Semiverbatim'); +DefKeyVal('omtext','continues','Semiverbatim'); +DefKeyVal('omtext','verbalizes','Semiverbatim'); +%</ltxml> +% \end{macrocode} +% +% \begin{macro}{\st@flow} +% We define this macro, so that we can test whether the |display| key has the value |flow| +% \begin{macrocode} +%<*package> +\def\st@flow{flow} +%</package> +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{omtext} +% The |omtext| environment is different, it does not have a keyword that marks +% it. Instead, it can have a title, which is used in a similar way. We redefine the +% |\lec| macro so the trailing |\par| does not get into the way. +% \begin{macrocode} +%<*package> +\def\omtext@pre@skip{\smallskip} +\def\omtext@post@skip{} +\providecommand{\stDMemph}[1]{\textbf{#1}} +\newenvironment{omtext}[1][]{\bgroup\metasetkeys{omtext}{#1}\sref@label@id{this paragraph}% +\def\lec##1{\@lec{##1}} +\ifx\omtext@display\st@flow\else\omtext@pre@skip\par\noindent% +\ifx\omtext@title\@empty\else\stDMemph{\omtext@title}: \fi\fi\ignorespaces} +{\egroup\omtext@post@skip} +%</package> +%<*ltxml> +DefEnvironment('{omtext} OptionalKeyVals:omtext', + "<omdoc:omtext " + . "?&KeyVal(#1,'id')(xml:id='&KeyVal(#1,'id')')() " + . "?&KeyVal(#1,'type')(type='&KeyVal(#1,'type')')() " + . "?&KeyVal(#1,'for')(for='&KeyVal(#1,'for')')() " + . "?&KeyVal(#1,'from')(from='&KeyVal(#1,'from')')()>" + . "?&KeyVal(#1,'title')(<dc:title>&KeyVal(#1,'title')</dc:title>)()" + . "<omdoc:CMP>" + . "?&KeyVal(#1,'start')(<ltx:text class='startemph'>&KeyVal(#1,'start')</ltx:text>)()" + . "#body" + ."</omdoc:omtext>"); +%</ltxml> +% \end{macrocode} +% \end{environment} +% +% We also make our life easier If defining an environment that is +% turned into something that contains |<CMP>|\meta{body}|</CMP>|, use this method instead +% \begin{macrocode} +%<*ltxml> +sub DefCMPEnvironment { + my ($proto, $replacement, %options) = @_; + my @before = $options{beforeDigest} ? ($options{beforeDigest}) : (); + push(@before, \&useCMPItemizations); + $options{beforeDigest} = \@before; + my @after = $options{afterDigestBegin} ? ($options{afterDigestBegin}) : (); + push(@after, \&declareFunctions); + $options{afterDigestBegin} = \@after; + DefEnvironment($proto, $replacement, %options); +} +sub DefCMPConstructor { + my ($proto, $replacement, %options) = @_; + my @before = $options{beforeDigest} ? ($options{beforeDigest}) : (); + push(@before, \&useCMPItemizations); + $options{beforeDigest} = \@before; + DefConstructor($proto, $replacement, %options); +}#$ +%</ltxml> +% \end{macrocode} +% \end{omgroup} +% +% \begin{omgroup}[id=sec:impl:phrase]{Phrase-level Markup} +% +% \begin{environment}{phrase} +% For the moment, we do disregard the most of the keys +% \begin{macrocode} +%<*package> +\srefaddidkey{phrase} +\addmetakey{phrase}{style} +\addmetakey{phrase}{class} +\addmetakey{phrase}{index} +\addmetakey{phrase}{verbalizes} +\addmetakey{phrase}{type} +\newenvironment{phrase}[1][]{\metasetkeys{phrase}{#1}}{} +%</package> +%<*ltxml> +DefKeyVal('phrase','id','Semiverbatim'); +DefKeyVal('phrase','style','Semiverbatim'); +DefKeyVal('phrase','class','Semiverbatim'); +DefKeyVal('phrase','index','Semiverbatim'); +DefKeyVal('phrase','verbalizes','Semiverbatim'); +DefKeyVal('phrase','type','Semiverbatim'); +DefConstructor('\phrase OptionalKeyVals:phrase {}', + "<ltx:text %&KeyVals(#1)>#2</ltx:text>"); +%</ltxml> +% \end{macrocode} +% \end{environment} +% +% \begin{environment}{nlex} +% For the moment, we do disregard the most of the keys +% \begin{macrocode} +%<*package> +\def\nlex#1{\green{\sl{#1}}} +\def\nlcex#1{*\green{\sl{#1}}} +%</package> +%<*ltxml> +DefConstructor('\nlex{}', + "<ltx:text class='nlex'>#1</ltx:text>"); +DefConstructor('\nlcex{}', + "<ltx:text type='nlcex'>#1</ltx:text>"); +%</ltxml> +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{sinlinequote} +% \begin{macrocode} +%<*package> +\def\@sinlinequote#1{``{\sl{#1}}''} +\def\@@sinlinequote#1#2{\@sinlinequote{#2}~#1} +\newcommand{\sinlinequote}[2][] +{\def\@opt{#1}\ifx\@opt\@empty\@sinlinequote{#2}\else\@@sinlinequote\@opt{#2}\fi} +%</package> +%<*ltxml> +DefConstructor('\sinlinequote [] {}', + "<ltx:quote type='inlinequote'>" + . "?#1(<dc:source>#1</dc:source>\n)()" + . "#2" + . "</ltx:quote>"); +%</ltxml> +% \end{macrocode} +% \end{macro} +% \end{omgroup} +% +% \begin{omgroup}[id=sec:impl:block]{Block-Level Markup} +% +% \begin{environment}{sblockquote} +% \ednote{describe above} +% \begin{macrocode} +%<*package> +\def\begin@sblockquote{\begin{quote}\sl} +\def\end@sblockquote{\end{quote}} +\def\begin@@sblockquote#1{\begin@sblockquote} +\def\end@@sblockquote#1{\def\@@lec##1{{\rm ##1}}\@lec{#1}\end@sblockquote} +\newenvironment{sblockquote}[1][] + {\def\@opt{#1}\ifx\@opt\@empty\begin@sblockquote\else\begin@@sblockquote\@opt\fi} + {\ifx\@opt\@empty\end@sblockquote\else\end@@sblockquote\@opt\fi} +%</package> +%<*ltxml> +DefEnvironment('{sblockquote} []', + "?#1(<omdoc:omtext type='quote'>" + . "<dc:source>#1</dc:source>" + . "#body" + . " </omdoc:omtext>)" + . "(<ltx:quote>#body</ltx:quote>)"); +%</ltxml> +% \end{macrocode} +% \end{environment} +% +% The line end comment macro makes sure that it will not be forced on the next line unless +% necessary. +% \begin{macro}{\lec} +% The actual appearance of the line end comment is determined by the |\@@lec| macro, +% which can be customized in the document class. The basic one here is provided so that +% it is not missing. +% \begin{macrocode} +%<*package> +\providecommand{\@@lec}[1]{(#1)} +\def\@lec#1{\strut\hfil\strut\null\nobreak\hfill\hbox{\@@lec{#1}}} +\def\lec#1{\@lec{#1}\par} +%</package> +%<*ltxml> +DefConstructor('\lec{}', + "\n<omdoc:note type='line-end-comment'>#1</omdoc:note>"); +%</ltxml> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\my*graphics} +% We set up a special treatment for including graphics to respect the intended {\omdoc} +% document structure. The main work is done in the transformation stylesheet though. +% +% \begin{macrocode} +%<ltxml>RawTeX(' +%<*ltxml|package> +\newcommand\mygraphics[2][]{\includegraphics[#1]{#2}} +\newcommand\mycgraphics[2][]{\begin{center}\includegraphics[#1]{#2}\end{center}} +\newcommand\mybgraphics[2][]{\fbox{\includegraphics[#1]{#2}\end{center}}} +%</ltxml|package> +%<ltxml>'); +% \end{macrocode} +% \end{macro} +% \end{omgroup} +% +% \begin{omgroup}[id=sec:impl:index]{Index Markup} +% +% \begin{macrocode} +% this is the main internal indexing comman. It makes sure that the modules necessary for +% interpreting the math in the index entries are loaded. +%<*package> +\newcommand{\omdoc@index}[2][]{\ifindex\def\@test{#1}%% +\ifx\@test\@empty\def\@@idx{#2}\else\def\@@idx{#1}\fi% +\@ifundefined{mod@id}{\index{\@@idx @#2}}% +{\index{\@@idx @{\importmodule{\mod@id} #2}}\fi}} +\newcommand{\indexalt}[3][]{{#2}\omdoc@index[#1]{#3}} % word in text and index +\newcommand{\indextoo}[2][]{{#2}\omdoc@index[#1]{#2}} % word in text and index +%</package> +% \end{macrocode} +% +% this puts two-compound words into the index in various permutations +% +% \begin{macrocode} +%<*package> +\newcommand{\@twin}[3][]{\ifindex\def\@test{#1}%% +\ifx\@test\@empty\def\@@idx{#2}\else\def\@@idx{#1}\fi% +\@ifundefined{mod@id} +{\index{\@@idx @#2!#3}% +\ifx\@test\@empty\def\@@idx{#3}\else\def\@@idx{#1}\fi% +\index{\@@idx @#2!#3}}% +{\index{\@@idx @{\importmodule{\mod@id} #2}!{\importmodule{\mod@id} #3}}% +\ifx\@test\@empty\def\@@idx{#3}\else\def\@@idx{#1}\fi% +\index{\@@idx @{\importmodule{\mod@id} #3}!{\importmodule{\mod@id} #2}}\fi}} +\newcommand{\twinalt}[4][]{#2\@twin[#1]{#3}{#4}} +\newcommand{\twintoo}[3][]{{#2 #3}\@twin[#1]{#2}{#3}} % and use the word compound too +%</package> +% \end{macrocode} +% +% this puts adjectivized two-compound words into the index in various +% permutations\ednote{what to do with the optional argument here and below?} +% +% \begin{macrocode} +%<*package> +\newcommand{\@atwin}[4][]{\ifindex\def\@test{#1}%% +\ifx\@test\@empty\def\@@idx{#2}\else\def\@@idx{#1}\fi% +\@ifundefined{mod@id}% +{\index{\@@idx @#2!#3!#4}% +\ifx\@test\@empty\def\@@idx{#3}\else\def\@@idx{#1}\fi +\index{\@@idx @#3!#2 (#4)}}% +{\index{\@@idx @{\importmodule{\mod@id} #2}!{\importmodule{\mod@id} #3}!{\importmodule{\mod@id} #4}} +\ifx\@test\@empty\def\@@idx{#3}\else\def\@@idx{#1}\fi% +\index{\@@idx @{\importmodule{\mod@id} #3}!{\importmodule{\mod@id} #2} ({\importmodule{\mod@id} #4})}\fi}} +\newcommand{\atwinalt}[5][]{#2\@atwin[#1]{#3}{#4}{#4}} +\newcommand{\atwintoo}[4][]{{#2 #3 #4}\@atwin[#1]{#2}{#3}{#4}} % and use it too +%</package> +%<*ltxml> +DefConstructor('\indextoo[]{}', + "<omdoc:idx>" + . "<omdoc:idt>#2</omdoc:idt>" + . "<omdoc:ide ?#1(sort-by='#1')()>" + . "<omdoc:idp>#2</omdoc:idp>" + . "</omdoc:ide>" + ."</omdoc:idx>"); +DefConstructor('\indexalt[]{}{}', + "<omdoc:idx>" + . "<omdoc:idt>#2</omdoc:idt>" + . "<omdoc:ide ?#1(sort-by='#1')()>" + . "<omdoc:idp>#3</omdoc:idp>" + . "</omdoc:ide>" + ."</omdoc:idx>"); +%</ltxml> +% \end{macrocode} +% +% \begin{macrocode} +%<*ltxml> +DefConstructor('\twintoo[]{}{}', + "<omdoc:idx>" + . "<omdoc:idt>#2 #3</omdoc:idt>" + . "<omdoc:ide ?#1(sort-by='#1')()>" + . "<omdoc:idp>#2</omdoc:idp>" + . "<omdoc:idp>#3</omdoc:idp>" + . "</omdoc:ide>" + ."</omdoc:idx>"); +DefConstructor('\twinalt[]{}{}{}', + "<omdoc:idx>" + . "<omdoc:idt>#2</omdoc:idt>" + . "<omdoc:ide ?#1(sort-by='#1')()>" + . "<omdoc:idp>#2</omdoc:idp>" + . "<omdoc:idp>#3</omdoc:idp>" + . "</omdoc:ide>" + ."</omdoc:idx>"); +%</ltxml> +% \end{macrocode} +% +% \begin{macrocode} +%<*ltxml> +DefConstructor('\atwintoo[]{}{}{}', + "<omdoc:idx>" + . "<omdoc:idt>#2 #3</omdoc:idt>" + . "<omdoc:ide ?#1(sort-by='#1')()>" + . "<omdoc:idp>#2</omdoc:idp>" + . "<omdoc:idp>#3</omdoc:idp>" + . "<omdoc:idp>#4</omdoc:idp>" + . "</omdoc:ide>" + ."</omdoc:idx>"); + +DefConstructor('\atwinalt[]{}{}{}{}', + "<omdoc:idx>" + . "<omdoc:idt>#2</omdoc:idt>" + . "<omdoc:ide ?#1(sort-by='#1')()>" + . "<omdoc:idp>#2</omdoc:idp>" + . "<omdoc:idp>#3</omdoc:idp>" + . "<omdoc:idp>#4</omdoc:idp>" + . "</omdoc:ide>" + ."</omdoc:idx>"); +%</ltxml> +% \end{macrocode} +% \end{omgroup} +% +% \begin{omgroup}{{\LaTeX} Commands we interpret differently} +% +% The first think we have to take care of are the paragraphs, we want to generate {\omdoc} +% that uses the |ltx:p| element for paragraphs inside |CMP|s. For that we have modified +% the DTD only to allowed |ltx:p| elements in |omdoc:CMP| (in particular no text). Then +% we instruct the |\par| macro to close a |ltx:p| element if possible. The next +% |ltx:p| element is then opened automatically, since we make |ltx:p| and |omdoc:CMP| +% autoclose and autoopen. +% +% \begin{macrocode} +%<*ltxml> +# needed? DefConstructor('\par',sub { $_[0]->maybeCloseElement('ltx:p'); },alias=>"\\par\n"); +Tag('omdoc:CMP', autoClose=>1, autoOpen=>1); +Tag('omdoc:omtext', autoClose=>1, autoOpen=>1); +%</ltxml>#$ +% \end{macrocode} +% the rest of the reinterpretations is quite simple, we either disregard presentational +% markup or we re-interpret it in terms of {\omdoc}.\ednote{MK: we should probably let +% LaTeXML deal with these and allow more text in the omdoc+ltml.xsl} +% \begin{macrocode} +%<package>\def\omspace#1{\hspace*{#1}} +%<*ltxml> +DefConstructor('\footnote[]{}', + "<omdoc:note type='foot' ?#1(mark='#1')>#2</omdoc:note>"); +DefConstructor('\footnotemark[]',""); +DefConstructor('\footnotetext[]{}', + "<omdoc:note class='foot' ?#1(mark='#1')>#2</omdoc:note>"); +%</ltxml> +% \end{macrocode} +% \end{omgroup} +% +% \begin{omgroup}[id=sec:impl:ids]{Providing IDs for {\omdoc} Elements} +% +% To provide default identifiers, we tag all {\omdoc} elements that allow |xml:id| +% attributes by executing the |numberIt| procedure below. Furthermore, we use the +% |locateIt| procedure to give source links. +% +% \begin{macrocode} +%<*ltxml> +Tag('omdoc:omtext',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('omdoc:omgroup',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('omdoc:CMP',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('omdoc:idx',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('omdoc:ide',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('omdoc:idt',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('omdoc:note',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('omdoc:metadata',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('omdoc:meta',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('omdoc:resource',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('ltx:p',afterOpen=>\&numberIt,afterClose=>\&locateIt); +%</ltxml> +% \end{macrocode} +% We also have to number some {\latexml} tags, so that we do not get into trouble with the +% \omdoc tags inside them. +% \begin{macrocode} +%<*ltxml> +Tag('ltx:tabular',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('ltx:thead',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('ltx:td',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('ltx:tr',afterOpen=>\&numberIt,afterClose=>\&locateIt); +Tag('ltx:caption',afterOpen=>\&numberIt,afterClose=>\&locateIt); +%</ltxml> +% \end{macrocode} +% The |numberIt| procedure gets the prefix from first parent with an |xml:id| attribute and then +% extends it with a label that reflects the number of preceding siblings, provided that +% there is not already an identifier. Additionally, it estimates an XPointer position in the original document +% of the command sequence which produced the tag. +% The |locateIt| subroutine is a sibling of |numberIt| as it is required as an |afterClose| handle for tags +% produced by {\LaTeX} environments, as opposed to commands. |locateIt| estimates an XPointer end position of +% the LaTeX environment, allowing to meaningfully locate the entire environment at the source. +% \begin{macrocode} +%<*ltxml> +sub numberIt { + my($document,$node,$whatsit)=@_; + my(@parents)=$document->findnodes('ancestor::*[@xml:id]',$node); + my $prefix= (@parents ? $parents[$#parents]->getAttribute('xml:id')."." : ''); + my(@siblings)=$document->findnodes('preceding-sibling::*[@xml:id]',$node); + my $n = scalar(@siblings)+1; + my $id = ($node -> getAttribute('xml:id')); + my $localname = $node->localname; + $node->setAttribute('xml:id'=>$prefix."$localname$n") unless $id; + my $about = $node -> getAttribute('about'); + $node->setAttribute('about'=>'#'.$node->getAttribute('xml:id')) unless $about; + #Also, provide locators: + my $locator = $whatsit->getProperty('locator'); + #Need to inherit locators if missing: + $locator = (@parents ? $parents[$#parents]->getAttribute('stex:srcref') : '') unless $locator; + if ($locator) { + # There is a BUG with namespace declarations (or am I using the API wrongly??) which + # does not recognize the stex namespace. Hence, I need to redeclare it... + my $parent=$document->getNode; + if(! defined $parent->lookupNamespacePrefix("http://kwarc.info/ns/sTeX")) + { # namespace not already declared? + $document->getDocument->documentElement->setNamespace("http://kwarc.info/ns/sTeX","stex",0); + } + $node->setAttribute('stex:srcref'=>$locator); + }return;} + +sub locateIt { + my($document,$node,$whatsit)=@_; + #Estimate trailer locator: + my $trailer = $whatsit->getProperty('trailer'); + return unless $trailer; #Nothing we can do if the trailer isn't defined + $trailer = $trailer->getLocator; + return unless ($trailer && $trailer!~/^\s*$/); #Useless if broken + my $locator = $node->getAttribute('stex:srcref'); + if ($locator) { + $locator =~ /^(.+from=\d+;\d+)/; + my $from = $1; + $trailer =~ /(,to=\d+;\d+.+)$/; + my $to = $1; + $locator = $from.$to; + } else { + $locator = $trailer; #This should never happen + } + my $parent = $document->getNode; + if(! defined $parent->lookupNamespacePrefix("http://kwarc.info/ns/sTeX")) + { # namespace not already declared? + $document->getDocument->documentElement->setNamespace("http://kwarc.info/ns/sTeX","stex",0); + } + $node->setAttribute('stex:srcref' => $locator); + return; +} +%</ltxml>#$ +% \end{macrocode} +% \end{omgroup} +% +% \begin{omgroup}{Finale} +% +% We need to terminate the file with a success mark for perl. +% \begin{macrocode} +%<ltxml>1; +% \end{macrocode} +% \end{omgroup} +%\end{omgroup} +% \Finale +\endinput +% \iffalse +% LocalWords: GPL structuresharing STR omdoc dtx stex CPERL LoadClass url dc +%%% Local Variables: +%%% mode: doctex +%%% TeX-master: t +%%% End: +% \fi +% LocalWords: RequirePackage RegisterNamespace namespace xsl DocType ltxml dtd +% LocalWords: ltx DefEnvironment beforeDigest AssignValue inPreamble getGullet +% LocalWords: afterDigest keyval omgroup DefKeyVal Semiverbatim KeyVal +% LocalWords: OptionalKeyVals DefParameterType IfBeginFollows skipSpaces CMP +% LocalWords: ifNext DefMacro needwrapper unlist DefConstructor omtext bgroup +% LocalWords: useCMPItemizations RefStepItemCounter egroup beginItemize li di +% LocalWords: beforeDigestEnd dt autoclose ul ol dl env showignores srcref def +% LocalWords: afterOpen LastSeenCMP autoClose DefCMPEnvironment proto ToString +% LocalWords: addAttribute nlex nlcex omdocColorMacro args tok MergeFont qw rm +% LocalWords: TokenizeInternal toString isMath foreach maybeCloseElement id'd +% LocalWords: autoOpen minipage footnotesize scriptsize numberIt whatsit href +% LocalWords: getAttribute setAttribute OMDoc RelaxNGSchema noindex xml lec sc +% LocalWords: Subsubsection useDefaultItemizations refundefinedtrue sblockquote +% LocalWords: DefCMPConstructor sinlinequote idx idt ide idp emph extrefs sref +% LocalWords: flushleft flushright DeclareOption PassOptions undef cls iffalse +% LocalWords: ProcessOptions subparagraph ignoresfalse ignorestrue raisebox tr +% LocalWords: texorpdfstring latexml texttt fileversion maketitle newpage iff +% LocalWords: tableofcontents newpage ednote obeylines usepackage indextoo Cwd +% LocalWords: indextoo twintoo twintoo exfig vspace twinalt ldots ttin emin +% LocalWords: renmanig myindex atwin atwin packge-local blockquote inlinequote +% LocalWords: atwintoo atwinalt atwinalt printbibliography impl cwd newif ifx +% LocalWords: ifindex indextrue indexfalse srefaddidkey smallskip showmeta +% LocalWords: providecommand stDMemph textbf newenvironment hfil showmeta +% LocalWords: noindent ignorespaces newcommand nobreak hfill hbox mygraphics +% LocalWords: includegraphics mycgraphics mybgraphics fbox adjectivized hspace +% LocalWords: printindex jobname.ind jobname.ind omspace footnotemark thead +% LocalWords: footnotetext findnodes doctex textsf langle textsf langle funval +% LocalWords: metakeys funsymbs addmetakey metasetkeys startemph textsl textit +% LocalWords: compactenum |