% \iffalse meta-comment % An Infrastructure for extending macros by general metadata keys % $URL: https://svn.kwarc.info/repos/stex/trunk/sty/rdfmeta/rdfmeta.dtx $ % $Rev: 1911 $; last modified by $Author: kohlhase $ % $Date: 2011-10-27 14:01:09 +0200 (Thu, 27 Oct 2011) $ % Copyright (c) 2007 Michael Kohlhase, all rights reserved % this file is released under the % LaTeX Project Public License (LPPL) % \fi % % \iffalse %<*package> \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{rdfmeta}[2010/09/01 v0.2 Metadata key upgrades] % %<*driver> \documentclass{ltxdoc} \usepackage[sectioning]{rdfmeta} \usepackage{url,array,float,stex-logo} \usepackage[show]{ed} \usepackage{listings} \lstset{basicstyle=\small\tt,columns=flexible} \lstset{frame=none,numbers=none,lineskip=-.7ex,aboveskip=-.5ex,belowskip=-.5ex} \usepackage[hyperref=auto,style=alphabetic]{biblatex} \bibliography{kwarc} \usepackage{../ctansvn} \usepackage{hyperref} \usepackage[eso-foot,today]{svninfo} \svnInfo $Id: rdfmeta.dtx 1911 2011-10-27 12:01:09Z kohlhase $ \svnKeyword $HeadURL: https://svn.kwarc.info/repos/stex/trunk/sty/rdfmeta/rdfmeta.dtx $ \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}} \def\omdoc{OMDoc\xspace} \def\omdocv#1{OMDoc{#1}\xspace} \begin{document}\DocInput{rdfmeta.dtx}\end{document} % % \fi % %\iffalse\CheckSum{1}\fi % % \changes{v0.1}{2010/03/05}{new} % \changes{v0.2}{2010/09/01}{starred forms work now, more documentation} % % \GetFileInfo{rdfmeta.sty} % % \MakeShortVerb{\|} % \def\latexml{{\LaTeX}ML} % % \title{RDFa Metadata in {\LaTeX}\thanks{Version {\fileversion} (last revised % {\filedate})}} % \author{Michael Kohlhase \\ % Jacobs University, Bremen\\ % \url{http://kwarc.info/kohlhase}} % \maketitle % \begin{abstract} % The |rdfmeta| package allows mark up Ontology-based Metadata in {\LaTeX} documents % that can be harvested by automated tools or exported to PDF. % \end{abstract} %\tableofcontents %\begin{center}\bf\Huge % Experimental!\\ % do not use! %\end{center}\newpage % % \section[id=intro]{Introduction} % % The |rdfmeta| package allows mark up extensible metadata in \stex documents, so that % that it can be harvested by automated tools or exported to PDF. It is also intended to % support the new metadata infrastructure for the {\omdoc} format~\cite{Kohlhase:omdoc1.2} % introduced in {\omdocv{1.3}}~\cite{Kohlhase:OMDoc1.3} (see~\cite{LK:MathOntoAuthDoc09} % for the relevant ideas and and~\cite{KohKohLan:ssffld10:biblatex} for an application). % % Metadata are annotated as key value pairs in the semantic environments provided by % \stex. In most markup formats, the metadata vocabularies are fixed by the language % designer. In \stex, the |rdfmeta| package allows the user to extend the metadata % vocabulary. % % \begin{exfig}[ht] % \begin{verbatim} % \importmodule[../ontologies/cert]{certification} % ... % \section[id=userreq,hasState=$\statedocrd{\tuev}$]{User Requirements} % ... % \end{verbatim} % \vspace*{-1.5em}\hrule % \lstinputlisting[language=XMl,morekeywords={imports,metadata,resource,link,omgroup},aboveskip=.5ex]{hasstate.omdoc} % \caption{Metadata for Certification}\label{fig:hasState} % \end{exfig} % % Take, for instance, the case where we want to use metadata for the certification status % of document fragments. In Figure~\ref{fig:hasState} we use the |hasState| key to say % that a section has been approved by the T\"UV, a specific certification agency. There % are two concerns here. First, the |hasState| key has to be introduced and given a % meaning, and same for the (complex) value |\statedocrd{\tuev}|. This meaning is given in % the |certifiation| ontology which we imported via the |\importmodule| command. The % ontology can be marked up in \stex (see Figure~\ref{fig:certification}), with the % exception that we use the |\keydef| macro for the definition of the |hasState| relation % so that it also defines the key. For the details of this see the next section. % % \section[id=user]{User Interface} % % We now document the specifics of the environments and macros provided by the |rdfmeta| % package from a user perspective. % % \subsection[id=sec.user.options]{Package Options} % % The |rdfmeta| package takes the option: \DescribeMacro{showmeta}|showmeta|. If this is % set, then the metadata keys are shown (see~\cite{Kohlhase:metakeys:ctan} for details and % customization options). % % The remaining options can be used to specify metadata upgrades of standard keys, they % are detailed in \sref{user.redefinitions}. % % \subsection[id=sec.user.keydef]{Extending Macros and Environments by Metadata Keys} % % The main user-visible feature of the |rdfmeta| package is the % \DescribeMacro{\keydef}|keydef| macro. It takes two arguments, a ``key group % identifier'' and a key name. In a nutshell, every \stex command that takes metadata keys % comes with a ``key group identifier'' that identifies the set of admissible keys; % see~\cite{Kohlhase:metakeys:ctan} for details on this concept. Figure~\ref{fig:keygroups} % gives an overview over the key groups and their identifiers in \stex. % \begin{figure} % \begin{tabular}{|>{\tt}l|>{\tt}p{5.5cm}|>{\tt}p{2.4cm}|}\hline % \rm\textbf{Key Group Identifier} & \rm\textbf{Macros} & \rm\textbf{Package/Class} \\\hline\hline % dcm@person & DCMPerson & dcm.sty\\\hline % dcm@institution & DCMInstitution & dcm.sty\\\hline % dcm@sect & section & dcm.sty\\\hline % assig & assignment & hwexam.cls\\\hline % inclassig & includeassignment & hwexam.cls\\\hline % quizheading & quizheading & hwexam.cls\\\hline % testheading & quizheading & hwexam.cls\\\hline % module & module & modules.sty\\\hline % termdef & termdef & modules.sty \\\hline % view & view & modules.sty\\\hline % omgroup & omgroup & omdoc.sty\\\hline % ignore & ignore & omdoc.sty\\\hline % omtext & omtext, definition, axiom, assertion, example, inlinedef & omtext.sty, statements.sty\\\hline % phrase & phrase & omtext.sty\\\hline % problem & problem & problem.sty\\\hline % inclprob & includeproblem & problem.sty\\\hline % req & requirement & reqdoc.sty\\\hline % spf & sproof, spfcases, spfcase, spfstep, spfcomment & sproof.sty\\\hline % termref & termref & statements.sty \\\hline % symboldec & symboldec & statements.sty\\\hline % \end{tabular} % \caption{Key Group Identifiers in \protect\stex}\label{fig:keygroups} % \end{figure} % % Semantically, |\keydef{|\meta{keygroup}|}{|\meta{key}|}| defines a symbol just like the % |\symdef| macro from the |modules| package~\cite{KohAmb:smmssl:ctan}. But it also % extends the syntax of \stex itself: it adds a key \meta{key} to \meta{keygroup}, which % allows to state the corresponding metadata as a key/value pair in the \stex macro or % environment. Following the ideas from~\cite{LK:MathOntoAuthDoc09}, the metadata is % transformed to RDFa metadata~\cite{w3c:WD-rdfa-core-20100803} in {\omdoc}, where the % identifiers of relations are exactly the symbols introduced by the corresponding % |\keydef|. % % \begin{exfig}[ht] % \lstinputlisting[language=TeX,morekeywords={metalanguage}]{certification} % \caption{A simple Ontology on Certification}\label{fig:certification} % \end{exfig} % % In our example in Figure~\ref{fig:certification} we have defined a key |hasstate| in the % |omtext| key group\footnote{For the \texttt{\textbackslash omtext} environment and key group % see~\cite{Kohlhase:smmtf:ctan}} and a symbol |hasstate| via % |\addkey{omtext}{hasstate}|. Furthermore, we have defined the meaning of the relation % expressed by the |hasstate| symbol informally and specified some possible objects for % the relation (that could of course have been done in other modules as well). We have % made use of this metadata ontology and the new key |hasState| in the example in % Figure~\ref{fig:hasState}. % % \subsection[id=user.redefinitions]{Redefinitions of Common {\LaTeX} Macros and % Environments} % % The |rdfmeta| package redefines common {\LaTeX} commands (e.\,g.\ the sectioning macros) % so that they include optional KeyVal arguments that can be extended by |\keydef| % commands. With this extension, we can add RDFa metadata to any existing {\LaTeX} % document and generate linked data (XHTML+RDFa documents) via the {\latexml} % translator. The redefinitions are turned on by package options (see % \sref{sec.user.options}). We will now go through them in detail. % % \subsubsection[id=user.redefinitions.sectioning]{Sectioning Commands} % If the \DescribeMacro{sectioning}|sectioning| option is given, the |rdfmeta| package % upgrades the |\part|, |\chapter|, |\section|, |\subsection|, |\subsubsection|, % |\paragraph| macros (and of course their starred variants) with and optional argument % for the |sectioning| key group. % % \subsection[id=redefining]{Extending Packages with \texttt{rdfmeta}} % % The |rdfameta| package also exposes its internal infrastructure for extending the % redefinitions. Note that the upgrade macros can only be used in {\LaTeX} packages, as % the macro names contain |@|. Consequently, this section is only addressed at package % developers who want to extend existing (i.e. not written by them) packages with flexible % metadata functionality. % % \DescribeMacro{\rdfmeta@upgrade}|\rdfmeta@upgrade| is the basic upgrade facility for % pre-existing macros and environments provided by the |rdfmeta| package. % % |\rdfmeta@upgrade| takes an optional keyval argument an a command sequence \meta{cseq} % as a proper argument and (if that is defined), redefines |\|\meta{cseq} to take a keyval % argument. The |\rdfmeta@upgrade| macro also initializes a metadata key-group (a named % set of keys and their handlers; see~\cite{Kohlhase:metakeys:svn} for details) for the % upgraded macro with an |id| key for identification (see~\cite{Kohlhase:sref*} for % details). Often, the name of the key-group is the same as the command sequence, so we % take this as the default, if we want to specify a different metadata key-group name, we % can do so with the \DescribeMacro{keygroup}|keygroup| key in |\rdfmeta@upgrade|. If the % \DescribeMacro{idlabel}|idlabel| key is set to \meta{prefix}, then the {\LaTeX} label is % set to the value \meta{prefix}|.|\meta{id}, where \meta{id} is the value given in the % RDFa |id| key. This allows to use the normal {\LaTeX} referencing mechanism in addition % to the semantic referencing mechanism provided by the |sref| % package~\ctancite{Kohlhase:sref}. To fortify our intuition, let's consider the % |\caption| macro: % \begin{quote} % \begin{verbatim} % \rdfmeta@upgrade[keygroup=float,idlabel=flt]{caption} % \end{verbatim} % \end{quote} % will upgrade the existing |\caption| command so that it takes an optional argument. % % There is a variant \DescribeMacro{\rdfmeta@upgrade*}|\rdfmeta@upgrade*| that has to be % used to upgrade macros that have a starred form (e.g. |\section| and friends). Note that % |\rdfmeta@upgrade*| upgrades both forms (e.g. |\section| and |\section*|). % |\rdfmeta@upgrade*| uses same keys as |\rdfmeta@upgrade|, but adds two new ones to % specify the behavior in the case the the macro to be upgraded already has an optional % argument. For concreteness, we introduce them using the |\section| macro from standard % {\LaTeX} as an example. |\section| has an optional argument for the ``short title'', % which will appear in the table of contents. The \DescribeMacro{optarg}|optarg| key can % be used to specify a key for the existing optional argument. Thus, after upgrading it % via |\rdfmeta@upgrade*[optarg=short]{section}|, we can use the updated form % |\section[short=|\meta{toctitle}|]{|\meta{title}|}| instead of the old % |\section[|\meta{toctitle}|]{|\meta{title}|}|. Actually, this still has a problem: the % |\section*| would also be given the |short| key and would be passed an optional argument % (which it does not accept). To remedy this we can set the % \DescribeMacro{optargstar}|optargstar| key to |no|. In summary, the correct upgrade % command for |\section| and |\section*| would be % \begin{verbatim} % \rdfmeta@upgrade*[optarg=short,optargstar=no]{section} % \end{verbatim} % % \subsection[id=limitations]{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 Currently the coverage of the redefinitions of standard commands in the % \url{rdfmeta} package is minimal; we will extend this in the future. % \item The |\rdfmeta@upgrade| macro only works with single arguments, this should be easy % to fix with |\case| for the argument string. % \item I am not sure |\rdfmeta@upgrade| works with environments. % \item it would be convenient, if we had a macro |\keydefs|, which takes a list of % keygroups, so that we can define keys in multiple groups in one go, % e.g. |\keydefs{omtext,omgroup}{hasState}| in Figure~\ref{fig:certification}. But the % obvious ``solution'' % \begin{verbatim} % \newcommand\keydefs[2]{\@for\@I:=#1\do{\keydef{#1}{#2}}} % \end{verbatim} % does not work for me. % \end{compactenum} % % \StopEventually{\printbibliography} % % \section[id=impl]{The Implementation} % % The |sref| 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. % % We first set up header information for the {\latexml} binding file. % \begin{macrocode} %<*ltxml> package LaTeXML::Package::Pool; use strict; use LaTeXML::Package; % % \end{macrocode} % % \subsection[id=sec.impl.options]{Package Options} % % 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\if@rdfmeta@sectioning\@rdfmeta@sectioningfalse \DeclareOption{sectioning}{\@rdfmeta@sectioningtrue} \ProcessOptions % %<*ltxml> DeclareOption('showmeta',''); DeclareOption('sectioning',''); % % \end{macrocode} % % The first measure is to ensure that the right packages are loaded. From the from {\stex} % collection, we need the |sref| package (see~\ctancite{Kohlhase:sref}) for handling keys, % the |modules| package for exporting the |\keydef| (see~\ctancite{KohAmb:smmssl}). % \begin{macrocode} %<*package> \RequirePackage{sref,modules} % % \end{macrocode} % % \subsection[id=impl:keydef]{Key Definitions} % % \begin{macro}{\keydef} % The |\keydef| macro is rather simple, we just add a key to the respective environment % and extend the export token register for the current module by an |\addmetakey| % instruction. % \begin{macrocode} %<*package> \newcommand\keydef[2]{\addmetakey{#1}{#2}% \expandafter\g@addto@macro\this@module{\addmetakey{#1}{#2}}} % %<*ltxml> % % \end{macrocode} % \end{macro} % % \subsection[id=impl:upgrade]{RDFa upgrade Facilities} % % We first define the keys for the |\rdfmeta@upgrade| macro. % \begin{macrocode} %<*package> \def\@yes@{yes} \addmetakey*{upgrade}{idlabel} \addmetakey*{upgrade}{optarg} \addmetakey*[yes]{upgrade}{optargstar} \addmetakey*{upgrade}{keygroup} % \end{macrocode} % % \begin{macro}{\rdfmeta@upgrade} % This upgrade macro gives extended functionality according to the optional keys. The % top-level invocation just differentiates on whether a star is following: % \begin{macrocode} \def\rdfmeta@upgrade{\@ifstar\rdfmeta@upgrade@star\rdfmeta@upgrade@nostar} % \end{macrocode} % Both cases are almost the same, they only differ in the third line where they call % |\rdfmeta@upgrade@base| or |\rdfmeta@upgrade@base@star| defined above. In particular, % both take the arguments originally intended for |\rdfmeta@upgrade|. % \begin{macrocode} \newcount\@@args \newcommand\rdfmeta@upgrade@nostar[2][]{\def\@test{#1}% \ifx\@test\@empty\def\@@arg{0}\else\def\@@arg{#1}\fi\def\@@cseq{#2}% \rdfmeta@upgrade@base} % \end{macrocode} % They set the metakeys from the second argument, then set |\@@group| to be the intended % group (if the |keygroup| key was specified, it takes precedence over the default % |#2|). % \begin{macrocode} \newcommand\rdfmeta@upgrade@star[2][]{\def\@test{#1}% \ifx\@test\@empty\def\@@arg{0}\else\def\@@arg{#1}\fi\def\@@cseq{#2}% \rdfmeta@upgrade@base@star} % \end{macrocode} % \end{macro} % % \begin{macro}{\@rdfmeta@upgrade} % This macro does all the work that is comon to the starred and unstarred versions. It % takes two arguments. It first reads the keys from the first and manages the % |keygroup| default and the |idlabel| key. Then it saves the old behavior of % |\|\meta{cseq} as |\rdfmeta@|\meta{cseq}|@old|. Finally it generates a message on the % redefinition from the second argument. % \begin{macrocode} \newcommand\@rdfmeta@upgrade[2]{\metasetkeys{upgrade}{#1}% \ifx\upgrade@keygroup\@empty\def\@@group{\@@cseq}\else\edef\@@group{\upgrade@keygroup}\fi \def\@@gropt{\@nameuse{\@@group @\upgrade@optarg}} \ifx\upgrade@idlabel\@empty\srefaddidkey\@@cseq% \else\srefaddidkey[prefix=\upgrade@idlabel]{\@@cseq}\fi% \expandafter\let\csname rdfmeta@\@@cseq @old\expandafter\endcsname\csname\@@cseq\endcsname% \@@args=\@@arg\advance\@@args by 1 \addmetakey*\@@group\upgrade@optarg \message{redefining macro #2 for an optional argument with keygroup \@@group}} % \end{macrocode} % \end{macro} % % \begin{macro}{\rdfmeta@upgrade@base} % This auxiliary macro and is invoked as |\rdfmeta@upgrade@base{|\meta{optarg}|}|. It % checks if |\|\meta{cseq} (from above) is defined (if not it does nothing) and then % redefines |\|\meta{cseq} to take a keyval argument and passes \meta{optarg} as the % optional argument. % \begin{macrocode} \newcommand{\rdfmeta@upgrade@base}[1][]{\@ifundefined{\@@cseq}{}% {\@rdfmeta@upgrade{#1}{\@@cseq}% \expandafter\renewcommand\csname\@@cseq\endcsname[\the\@@args][]% {\metasetkeys{\@@cseq}{##1}% \ifx\@@gropt\@empty\@nameuse{rdfmeta@\@@cseq @old}{##2}% \else\@nameuse{rdfmeta@\@@cseq @old}[\@@gropt]{##2}\fi}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\rdfmeta@upgrade@base@star} % This is a variant of |\rdfmeta@upgrade@base|, which also takes care of the starred % variants of a macro. % \begin{macrocode} \newcommand\rdfmeta@upgrade@base@star[1][]{\@ifundefined{\@@cseq}{}% {\@rdfmeta@upgrade{#1}{\@@cseq and \@@cseq*} % \end{macrocode} % In this case, we cannot just use |\newcommand| for dealing with the optional argument % because the star is between the command sequence and the arguments. So we make a case % distinction on the presence of the star. % |\rdfmeta@|\meta{cseq}|@old|. % \begin{macrocode} \expandafter\renewcommand\csname\@@cseq\endcsname% {\@ifstar{\@nameuse{rdfmeta@\@@cseq @star}}{\@nameuse{rdfmeta@\@@cseq @nostar}}}% % \end{macrocode} % the macros |\rdfmeta@|\meta{cseq}|@star| and |\rdfmeta@|\meta{cseq}|@nostar| that are % defined in terms of |\rdfmeta@|\meta{cseq}|@old| handle the necessary cases. The second % one is simple: % \begin{macrocode} \expandafter\newcommand\csname rdfmeta@\@@cseq@nostar\endcsname[\the\@@args][]% {\metasetkeys{\@@cseq}{##1}% \ifx\@@gropt\@empty\@nameuse{rdfmeta@\@@cseq @old}{##2}% \else\@nameuse{rdfmeta@\@@cseq @old}[\@@gropt]{##2}\fi}% % \end{macrocode} % For |\rdfmeta@|\meta{cseq}|@star| we have to take care of the optional argument of the % old macro: if the |optargstar| key was set, then we pass the second argument of % |\rdfmeta@upgrade@base| as an optional argument to it as above. % \begin{macrocode} \ifx\upgrade@optargstar\@yes@% \expandafter\newcommand\csname rdfmeta@\@@cseq @star\endcsname[\the\@@args][]% {\metasetkeys{\@@cseq}{##1}% \@nameuse{rdfmeta@\@@cseq @old}*[\@@gropt]{##2}}% \else% \expandafter\newcommand\csname rdfmeta@\@@cseq @star\endcsname[\the\@@args][]% {\metasetkeys{\@@cseq}{##1}% \@nameuse{rdfmeta@\@@cseq @old}*{##2}}% \fi% \addmetakey*\@@group{\upgrade@optarg}}} % % \end{macrocode} % \end{macro} % % \subsection[id=impl:redef]{Redefinitions} % % If the |sectioning| macro is set, we redefine the respective commands % % \begin{macrocode} %<*package> \if@rdfmeta@sectioning \message{redefining sectioning commands!} \rdfmeta@upgrade*[keygroup=sectioning,optarg=short,optargstar=no]{part} \rdfmeta@upgrade*[keygroup=sectioning,optarg=short,optargstar=no]{chapter} \rdfmeta@upgrade*[keygroup=sectioning,optarg=short,optargstar=no]{section} \rdfmeta@upgrade*[keygroup=sectioning,optarg=short,optargstar=no]{subsection} \rdfmeta@upgrade*[keygroup=sectioning,optarg=short,optargstar=no]{subsubsection} \rdfmeta@upgrade*[keygroup=sectioning,optarg=short,optargstar=no]{paragraph} \fi % %<*ltxml> % % \end{macrocode} % \subsection{Finale} % % Finally, we need to terminate the file with a success mark for perl. % \begin{macrocode} %1; % \end{macrocode} % \Finale \endinput % \iffalse % LocalWords: GPL structuresharing STR LaTeX dcm dtx keyval sref CPERL url qw %%% Local Variables: %%% mode: doctex %%% TeX-master: t %%% End: % \fi % LocalWords: RequirePackage birthdate personaltitle academictitle workaddress % LocalWords: privaddress worktel privtel workfax privfax worktelfax noDelim % LocalWords: privtelfax getKeyValue valuelist ToString getValue affill STDERR % LocalWords: ExportMetadata AssignValue DCMperson DefConstructor afterDigest % LocalWords: getArg setValue FishOutMetadata keyvals foreach idlist tabline % LocalWords: LookupValue insertElement atabline bitabline shorttitle nc args % LocalWords: sharealike noderivativeworks DefMacro authorblock subsubsection % LocalWords: contribs OptionalKeyVals omgroup omdoc srcref xml RawTeX % LocalWords: openElement iffalse kohlhase Thu rdfmeta latexml fileversion omd % LocalWords: maketitle setcounter tocdepth tableofcontents newpage section % LocalWords: stex exfig vspace hrule lstinputlisting morekeywords aboveskip % LocalWords: hasstate.omdoc statedocrd tuev certifiation keydef ednote texttt % LocalWords: keysets rdfameta cseq idlabel ctancite ifundefined impl ltxml % LocalWords: printbibliography newcommand srefaddidkey expandafter csname ifx % LocalWords: expandafter endcsname csname endcsname renewcommand showmeta % LocalWords: symdef redef doctex showmeta metakeys keyset textbackslash cert % LocalWords: MathOntoAuthDoc09 WD-rdfa-core-20100803 hasstate omtext omtext % LocalWords: addkey optarg optarg toctitle optargstar optargstar keygroup % LocalWords: oldpart textsf langle textsf langle newif sectioningfalse ifstar % LocalWords: sectioningtrue metasetkeys nameuse addmetakey nostar