1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
|
% \iffalse meta-comment
% An Infrastructure for Semantic Macros and Module Scoping
% Copyright (C) 2004-2006 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
% https://svn.kwarc.info/repos/kwarc/projects/stex/sty/modules.dtx
% \fi
%
% \iffalse
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{modules}[2006/01/13 v0.9a Semantic Markup]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{url,array,modules,float}
\usepackage[show]{ed}
\usepackage{hyperref}
\makeindex
\floatstyle{boxed}
\newfloat{exfig}{thp}{lop}
\floatname{exfig}{Example}
\begin{document}\DocInput{modules.dtx}\end{document}
%</driver>
% \fi
%
% \CheckSum{539}
%
% \changes{v0.9}{2005/06/14}{First Version with Documentation}
% \changes{v0.9a}{2005/07/01}{Completed Documentation}
% \changes{v0.9b}{2005/08/06}{Complete functionality and Updated Documentation}
% \changes{v0.9c}{2006/01/13}{more packaging}
% \changes{v0.9d}{2007/12/12}{fixing double loading of .tex and .sms}
%
% \GetFileInfo{modules.sty}
%
% \MakeShortVerb{\|}
%\def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}}
% \def\stex{{\raisebox{-.5ex}S\kern-.5ex\TeX}}
% \def\sTeX{\stex}
% \def\xml{\scsys{Xml}}
% \def\mathml{\scsys{MathML}}
% \def\omdoc{\scsys{OMDoc}}
% \def\openmath{\scsys{OpenMath}}
% \def\latexml{\scsys{LaTeXML}}
% \def\perl{\scsys{Perl}}
% \def\cmathml{Content-{\sc MathML}\index{Content {\sc MathML}}\index{MathML@{\sc MathML}!content}}
% \def\activemath{\scsys{ActiveMath}}
% \def\twin#1#2{\index{#1!#2}\index{#2!#1}}
% \def\twintoo#1#2{{#1 #2}\twin{#1}{#2}}
% \def\atwin#1#2#3{\index{#1!#2!#3}\index{#3!#2 (#1)}}
% \def\atwintoo#1#2#3{{#1 #2 #3}\atwin{#1}{#2}{#3}}
% \title{Semantic Macros and Module Scoping in {\stex}\thanks{Version {\fileversion} (last revised
% {\filedate})}}
% \author{Michael Kohlhase \& Rares Ambrus\\
% Jacobs University, Bremen\\
% \url{http://kwarc.info/kohlhase}}
% \maketitle
%
% \begin{abstract}
% The |modules| packge is a central 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 a definition mechanism for semantic macros and a non-standard
% scoping construct for them, which is oriented at the semantic depency relation rather
% than the document structure. This structure can be used by MKM systems for
% added-value services, either directly from the {\sTeX} sources, or after translation.
% \end{abstract}
%\newpage
% \section{Introduction}\label{sec:intro}
%
% Following general practice in the {\TeX/\LaTeX} community, we use the term ``semantic
% macro'' for a macro whose expansion stands for a mathematical object, and whose name
% takes up the name of the mathematical object. This can range from simple definitions
% like |\def\Reals{{\mathbb R}}| for indivicual mathematical objects to more complex
% (functional) ones object constructors like
% |\def\SmoothFunctionsOn#1{{\cal{C}}^\infty(#1)}|. Semantic macros are traditionally used
% to make {\TeX/\LaTeX} code more portable. However, the {\TeX/\LaTeX} scoping model
% (macro definitions are scoped either in the local group or until the rest of the
% document), does not mirror mathematical practice, where notations are scoped by
% mathematical environments like statements, theories, or such.
%
% \section{The User Interface}
%
% The main contributions of the |modules| package are the |module| environment, which
% allows for lexical scoping of semantic macros with inheritance and the |\symdef| macro
% for declaration of semantic macros that underly the |module| scoping.
%
% \subsection{Modules}\label{sec:modules}
%
% \DescribeEnv{module} The |module| environment takes an optional |KeyVal|
% argument. Currently, only the |id| key is supported for specifying the identifier of a
% module (also called the {\twintoo{module}{name}}).
%
% \DescribeMacro{\importmodule} A module introduced by |\begin{module}[id=foo]| restricts
% the scope the semantic macros defined by the |\symdef| form to the end of this module
% given by the corresponding |\end{module}|, and to any other |module| environments that
% import them by a |\importmodule{foo}| directive. If the module |foo| contains
% |\importmodule| directives of its own, these are also exported to the importing
% module. Thus |\importmodule| induces the {\atwintoo{semantic}{inheritance}{relation}}
% and |usesqualified|\ednote{do an importqualified as well} for macros imported with a
% prefix (this is used whenever we have conflicting names for macros inherited from
% different modules).
%
% \subsection{Semantic Macros}\label{sec:symdef}
%
% \DescribeMacro{\symdef}A call to the |\symdef| macro has the general form
% \begin{quote}
% |\symdef[|\meta{keys}|]{|\meta{cseq}|}[|\meta{args}|]{|\meta{definiens}|}|
% \end{quote}
% where {\meta{cseq}} is a control sequence (the name of the semantic macro) {\meta{args}}
% is a number between 0 and 9 for the number of arguments {\meta{definiens}} is the token
% sequence used in macro expansion for {\meta{cseq}}. Finally {\meta{keys}} is a keyword
% list that further specifies the semantic status of the defined macro.
%
% A key |local| can be added to {\meta{keys}} to specify that the symbol is local to the
% module and is invisible outside. The key-value pair |aliases=|\meta{symname} specifies
% that the defined symbol {\meta{cseq}} is a presentational variant of the symbol
% {\meta{symname}}.
%
% Finallly, the keys |cmml|, |cattrs|, and |definitionURL| can be used to specify the
% {\cmathml} encoding of the symbols. They key-value pair |cmml=|\meta{elt} specifies that
% the semantic macro corresponds to the {\cmathml} element with the name \meta{elt},
% |cattrs=|\meta{attrtring} its argument string and |definitionURL| allows to specify the
% |definitionURL| attribute on that element. The most common case will be a symbol
% definition of the following form:
%
% \begin{quote}
% |\symdef[cmml=csymbol,definitionURL=|\meta{URI}|]{|\meta{cseq}|}[|\meta{args}|]{|\meta{definiens}|}|
% \end{quote}
%
% where \meta{URI} is the URI pointing to the location of the {\xml} file generated from
% the current {\LaTeX} file.
%
% \DescribeMacro{\abbrdef}The |\abbrdef| macro is a variant of |\symdef| that is only
% different in semantics, not in presentation. An abbreviative macro is like a semantic
% macro, and underlies the same scoping and inheritance rules, but it is just an
% abbreviation that is meant to be expanded, it does not stand for an atomic mathematical
% object.
%
% We will use a simple module for natural number arithmetics as a running example. It
% defines exponentiation and summation as new concepts while drawing on the basic
% operations like $+$ and $-$ from {\LaTeX}. In our example, we will define a semantic
% macro for summation |\Sumfromto|, which will allow us to express an expression like
% $\sum{i=1}^nx^i$ as |\Sumfromto{i}1n{2i-1}| (see Example~\ref{fig:semmodule} for an
% example). In this example we have also made use of a local semantic symbol for $n$,
% which is treated as an arbitrary (but fixed) symbol.
%
% \begin{module}[id=arith]
% \symdef{Sumfromto}[4]{\sum_{#1=#2}^{#3}{#4}}
% \symdef[local]{arbitraryn}{n}
%
%\begin{exfig}
% \begin{verbatim}
% \begin{module}[id=arith]
% \symdef{Sumfromto}[4]{\sum_{#1=#2}^{#3}{#4}}
% \symdef[local]{arbitraryn}{n}
% What is the sum of the first $\arbitraryn$ odd numbers, i.e.
% $\Sumfromto{i}1\arbitraryn{2i-1}?$
% \end{module}
% \end{verbatim}
% \vspace{-2em}is formatted by {\sTeX} to \medskip\par\noindent
% What is the sum of the first $\arbitraryn$ odd numbers, i.e.
% $\Sumfromto{i}1\arbitraryn{2i-1}?$
% \caption{Semantic Markup in a {\tt{module}} context}\label{fig:semmodule}
% \end{exfig}
% \end{module}
%
% \subsection{Dealing with multiple Files}\label{sec:user:multiple}
%
% The infrastructure presented above works well if we are dealing with small files or
% small collections of modules. In reality, collections of modules tend to grow, get
% re-used, etc, making it much more difficult to keep everything in one file. This general
% trend towards increasing enthropy is aggravated by the fact that modules are very
% self-contiained objects that are ideal for re-used. Therefore in the absence of a
% content management system for {\LaTeX} document (fragments), module collections tend to
% develop towards the ``one module one file'' rule, which leads to situations with lots
% and lots of little files.
%
% Moreover, most mathematical documents are not self-contained, i.e. they do not build up
% the theory from scratch, but pre-suppose the knowledge (and notation) from other
% documents. In this case we want to make use of the semantic macros from these
% prerequisite documents without including their text into the current document. One way
% to do this would be to have {\LaTeX} read the prerequisite documents without producing
% output. For efficiency reasons, {\stex} chooses a different route. It comes with a
% utility |sms| (see Section~\ref{sec:utilities}) that exports the modules and macros
% defined inside them from a particular document and stores them inside |.sms| files. This
% way we can avoid overloading LaTeX with useless information, while retaining the
% important information which can then be imported in a more efficient way.
%
% \DescribeMacro{\importmodule} For such situations, the |\importmodule| macro can be
% given an optional first argument that is a path to a file that contains a path to the
% module file, whose module definition (the |.sms| file) is read. Note that the
% |\importmodule| macro can be used to make module files truly self-contained. To arrive
% at a file-based content management system, it is good practice to reuse the module
% identifiers as module names and to prefix module files with corresponding
% |\importmodule| statements that pre-load the corresponing module files.
%
%\begin{exfig}
% \begin{verbatim}
% \begin{module}[id=foo]
% \importmodule[../other/bar]{bar}
% \importmodule[../mycolleaguesmodules]{baz}
% \importmodule[../other/bar]{foobar}
% ...
% \end{module}
% \end{verbatim}
% \vspace{-1.7em}
% \caption{Self-contained Modules via {\tt{importmodule}}}\label{exf:importmodule}
% \end{exfig}
%
% In Example~\ref{exf:importmodule}, we have shown the typical setup of a module
% file. The |\importmodule| macro takes great care that files are only read once, as
% {\sTeX} allows multiple inheritance and this setup would lead to an exponential (in the
% module inheritance depth) number of file loads.
%
% Note that the recursive (depth-first) nature of the file loads induced by this setup is
% very natural, but can lead to problems with the depth of the file stack in the {\TeX}
% formatte (it is usually set to something like 15). Therefore, it may be necessary to
% circumvent the recursive load pattern providing (logically spurious) |\importmodule|
% commands. Consider for instance module |bar| in Example~\ref{exf:importmodule}, say that
% |bar| already has load deph 15, then we cannot naivedly import it in this way. If module
% |bar| depended say on a module |base| on the critical load path, then we could add a
% statement \DescribeMacro{\requiremodules} |\requiremodules{../base}| in the second
% line. This would load the modules from |../base.sms| in advance (uncritical, since it
% has load depth 10), so that it would not have to be re-loaded in the critical path of
% the module |foo|. Solving the load depth problem.
%
% \subsection{Including Externally Defined Semantic Macros }
%
% In some cases, we use an existing {\LaTeX} macro package for typesetting objects that
% have a conventionalized mathematical meaning. In this case, the macros are ``semantic''
% even though they have not been defined by a |\symdef|. This is no problem, if we are
% only interested in the {\LaTeX} workflow. But if we want to e.g. transform them to
% {\omdoc} via {\latexml}, the {\latexml} bindings will need to contain references to an
% {\omdoc} theory that semantically correponds to the {\LaTeX} package. In particular,
% this theory will have to be imported in the generated {\omdoc} file to make it
% {\omdoc}-valid.
%
% \DescribeMacro{\requirepackage} To deal with this situation, the |modules| package
% provides the |\requirepackage| macro. It takes two arguments: a package name, and a URI
% of the corresponing {\omdoc} theory. In the {\LaTeX} workflow this macro behaves like a
% |\usepackage| on the first argument, except that it can --- and should --- be used
% outside the {\LaTeX} preamble. In the {\latexml} workflow, this loads the {\latexml}
% bindings of the package specified in the first argument and generates an appropriate
% |imports| element using the URI in the second argument.
%
% \StopEventually{\ednotemessage}
%
% \section{The Implementation}
%
% We declare some switches which will modify the behavior accoring to the package
% options. Generally, an option |xxx| will just set the appropriate switches to true
% (otherwise they stay false).
% \begin{macrocode}
%<*package>
\newif\ifmod@env\mod@envfalse
\newif\ifmod@id\mod@idfalse
\newif\ifmod@display\mod@displayfalse
\newif\ifmod@uses\mod@usesfalse
\newif\ifmod@usesqualified\mod@usesqualifiedfalse
\DeclareOption{env}{\mod@envtrue}
\DeclareOption{id}{\mod@idtrue}
\DeclareOption{uses}{\mod@usestrue}
\DeclareOption{display}{\mod@displaytrue}
\DeclareOption{usesqualified}{\mod@usesqualifiedtrue}
% \end{macrocode}
% Now, we define two collective options, which are equivalent to turning on all the other
% options.
% \begin{macrocode}
\def\modtrue{\mod@idtrue\mod@usestrue\mod@displaytrue\mod@usesqualifiedtrue}
\DeclareOption{draft}{\modtrue}
\DeclareOption{all}{\modtrue}
% \end{macrocode}
% Finally, we need to declare the end of the option declaration section to {\LaTeX}.
% \begin{macrocode}
\ProcessOptions
%</package>
% \end{macrocode}
%
% {\latexml} does not support module options yet, so we do not have to do anything here
% for the {\latexml} bindings. We only set up the {\perl} packages (and tell {\tt{emacs}}
% about the appropriate mode for convenience
%
% The next measure is to ensure that the |KeyVal| package is loaded (in the right
% version). for {\latexml}, we also initialize the package inclusions.
% \begin{macrocode}
%<package>\RequirePackage{keyval}[1997/11/10]
%<*ltxml>
# -*- CPERL -*-
package LaTeXML::Package::Pool;
use strict;
use LaTeXML::Global;
use LaTeXML::Package;
RequirePackage('keyval');
%</ltxml>
% \end{macrocode}
%
% \subsection{Modules}\label{sec:impl:modules}
%
% We define the keys for the |module| environment and the actions that are undertaken,
% when the keys are encountered.
%
% \begin{macro}{module:cd}
% This |KeyVal| key is only needed for {\latexml} at the moment; use this to specify a
% content dictionary name that is different from the module name.
% \begin{macrocode}
%<package>\define@key{module}{cd}{}
%<*ltxml>
DefKeyVal('Module','cd','Semiverbatim');
%</ltxml>
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{module:id}
% For a module with |[id=name]|, we create a macro |\module@defs@name| and initialize
% it. Furthermore, we save the name in |\mod@id|.
% \begin{macrocode}
%<*package>
\define@key{module}{id}{%
\edef\this@module{\expandafter\noexpand\csname module@defs@#1\endcsname}%
\edef\this@qualified@module{\expandafter\noexpand\csname module@defs@qualified@#1\endcsname}%
\global\@namedef{module@defs@#1}{}
\global\@namedef{module@defs@qualified@#1}{}
\def\mod@id{#1}}
%</package>
%<*ltxml>
DefKeyVal('Module','id','Semiverbatim');
%</ltxml>
% \end{macrocode}
% \end{macro}
%
% \begin{environment}{module}
% finally, we define the begin module command for the module environment. All the work
% has already been done in the keyval bindings, so this is very simple.
% \begin{macrocode}
%<package>\newenvironment{module}[1][]{\setkeys{module}{#1}\ifmod@env\show@mod@keys{module}\fi}{}
% \end{macrocode}
% for the {\latexml} bindings, we have to do the work all at once.
% \begin{macrocode}
%<*ltxml>
DefEnvironment('{module} OptionalKeyVals:Module',
"?#excluded()(<omdoc:theory ?&KeyVal(#1,'id')(xml:id='&KeyVal(#1,'id')')> #body</omdoc:theory>)",
#closed bracket ) seems to work fine now
#commented this out - do we need current_theory?
#plus: keyvals->getValue seems to be undefined?!
#beforeConstruct=> sub {
#my ($doc, $keyvals, %props) = @_;
#my $theory = $keyvals->getValue('id') if $keyvals;
#$theory = ref $theory ? $theory->toString : 'UNDEFINED';
#AssignValue(current_theory => $theory);
#return;},
# $Doc->openElement('omdoc:theory', 'xml:id' => $theory);
# my $uses = $keyvals->getValue('usses');
# $uses = ref $uses ? $uses->toString || '' : '';
# $uses =~ s/\s+//g; $uses=~ s/^\{//; $uses=~ s/\}$//;
# my $module_paths = LookupValue('module_paths') || {};
# foreach my $used(split(',',$uses)) {
# my $file = $module_paths->{$used}; $file .= '.omdoc#' if $file;
# $doc->openElement('omdoc:imports', 'from' => $file.$used);
# $doc->closeElement('omdoc:imports'); }
# $doc->absorb($props{body}) if $props{body};
# $doc->closeElement('omdoc:theory'); }
# return; },
beforeDigest=>\&useTheoryItemizations,
afterDigestBegin=>sub {
my($stomach, $whatsit)=@_;
$whatsit->setProperty(excluded=>LookupValue('excluding_modules'));
my $keys = $whatsit->getArg(1);
my($id, $cd)=$keys
&& map(ToString($keys->getValue($_)),qw(id cd));
$cd = $id unless $cd;
# update the catalog with paths for modules
my $module_paths = LookupValue('module_paths') || {};
$module_paths->{$id} = LookupValue('last_module_path');
AssignValue('module_paths', $module_paths, 'global');
#Update the current module position
AssignValue(current_module => $id);
AssignValue(module_cd => $cd) if $cd;
# my @uses = ();
# if($uses){
# $uses =~ s/\s//g; $uses=~ s/^\{//; $uses=~ s/\}$//;
# @uses = split(',',$uses); }
############### AssignValue("module_${id}_uses" => [@uses], 'global');
#Idea: introdcue global list of used modules and activateScope on it once at the
# main block.
#use_module($id); #22.02.08 need to ALWAYS invoke this to make things global
#activate the module in our current scope
$STATE->activateScope("module:".$id); #changed from use_module as only needs to take care of current module
return; });
%</ltxml>
% \end{macrocode}
% \end{environment}
%
%
% \begin{macro}{usemodule}
% The |use_module| subroutine
% performs depth-first load of definitions of the used modules
% \begin{macrocode}
%<*ltxml>
sub use_module {
my($module)=@_;
$module = ToString($module);
# Depth-first load definitions from used modules
foreach my $used_module (@{ LookupValue("module_${module}_uses") || []}){
use_module($used_module); }
# then load definitions for this module
$STATE->activateScope("module:$module"); }
%</ltxml>
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\show@mod@keys}
% The |\show@mod@keys| macro is used for the draft mode, they allow to annotate the
% document with reminders of the key values in the modules.
% \begin{macrocode}
%<*package>
\def\show@mod@keys@aux{%
\@ifundefined{mod@id}{}{\ifmod@id{id=\mod@id},\fi}%
\@ifundefined{mod@display}{}{\ifmod@display{display=\mod@display}\fi}
\@ifundefined{mod@uses}{\relax}{\ifmod@uses{uses=\mod@uses},\fi}
\@ifundefined{mod@usesqualified}\relax\else
\ifmod@usesqualified{usesqualified=\mod@usesqualified},\fi\fi}
\def\clear@mod@keys{\let\mod@usesqualified=\relax\mod@uses=\relax
\let\st@id=\relax\let\st@display=\relax}
\def\show@mod@keys#1{\footnote{#1[\show@mod@keys@aux]}\clear@mod@keys}
%</package>
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{activate@defs}
% To activate the symdefs from a given module xxx, we call the macro |\module@defs@xxx|.
% \begin{macrocode}
%<package>\def\activate@defs#1{\csname module@defs@#1\endcsname}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{export@defs}
% To export a the symdefs from the current module, we all the macros |\module@defs@xxx|
% to |\module@defs@xxx| (if the current module has a name and it is xxx)
% \begin{macrocode}
%<*package>
\def\export@defs#1{\@ifundefined{mod@id}{}{
\expandafter\expandafter\expandafter
\g@addto@macro\expandafter
\this@module\expandafter{\csname module@defs@#1\endcsname}}}
%</package>
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\importmodule}
% The |\importmodule[|\meta{file}|]{|\meta{mod}|}| macro is an interface macro that
% loads \meta{file} and activates and re-exports the symdefs from module
% \meta{mod}.\ednote{document it above, and implement it in {\latexml}}
% \begin{macrocode}
%<*package>
\newcommand{\importmodule}[2][]{\def\@test{#1}%
\ifx\@test\@empty\else\requiremodules{#1}\fi
\activate@defs{#2}\export@defs{#2}}
%</package>
%<*ltxml>
DefConstructor('\importmodule[]{}',"<omdoc:imports from='?#1(#1)\# #2'/>",
afterDigest=>sub {
my($stomach,$whatsit)=@_;
my $file = $whatsit->getArg(1);
my $module = $whatsit->getArg(2);
$module = ToString($module);
#if filepath is not supply simply look for the $module.sms file
if (!$file) {$file=ToString($module)};
my $containing_module = LookupValue('current_module');
#set the relation between the current module and the one to be imported
PushValue("module_".$containing_module."_uses"=>$module);
#check if we've already loaded this module
if(LookupValue('module_'.$module.'_loaded')) {use_module($module);} #if so activate it!
else {
#if not:
my $gullet = $stomach->getGullet;
#1) mark as loaded
AssignValue('module_'.$module.'_loaded' => 1, 'global');
#open a group for its definitions so that they are localized
$stomach->bgroup;
#update the last module path
AssignValue('last_module_path', $file);
#queue the closing tag for this module in the gullet where it will be executed
#after all other definitions of the imported module have been taken care of
$gullet->unread(Invocation(T_CS('\end@requiredmodule'), T_OTHER($module))->unlist);
#we only need to load the sms definitions without generating any xml output, so we set the flag to 1
AssignValue('excluding_modules' => 1);
#queue this module's sms file in the gullet so that its definitions are imported
$gullet->input($file,['sms']);
}
return;});
%</ltxml>
% \end{macrocode}
% \end{macro}
%
% \subsection{Semantic Macros}\label{sec:impl:symdef}
%
% We first define the optional KeyVal arguments for the |\symdef| form and the actions
% that are taken when they are encountered.
%
% \begin{macro}{symdef:aliases}
% This optional key aliases for the symdef function allows us to provide additional
% arguments representing other functions that are aliased by the one currently being
% defined.
% \begin{macrocode}
%<package>\define@key{symdef}{aliases}{}
%<*ltxml>
DefKeyVal('symdef','aliases','Semiverbatim');
%</ltxml>
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{symdef:local}
% The optional argument local specifies the scope of the function to be defined. If
% local is not present as an optional argument then |\symdef| assumes the scope of the
% function is global and it will include it in the pool of macros of the current
% module. Otherwise, if local is present then the function will be defined only locally
% and it will not be added to the current module (i.e. we cannot inherit a local
% function). Note, the optional key local does not need a value: we write
% |\symdef[local]{somefunction}[0]{some expansion}|
% \begin{macrocode}
%<package>\define@key{symdef}{local}[true]{\@symdeflocaltrue}
%<*ltxml>
DefKeyVal('symdef','local','Semiverbatim','true');
%</ltxml>
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{symdef:}
% The keys |cmmml|, |cattrs|, and |definitionURL| are not used in {\TeX/\LaTeX}
% bindings\ednote{decide what we want to do about them in the future.}.
% \begin{macrocode}
%<*package>
\define@key{symdef}{cmml}{}
\define@key{symdef}{cattrs}{}
\define@key{symdef}{definitionURL}{}
%</package>
%<*ltxml>
DefKeyVal('symdef','cmml','Semiverbatim','true');
DefKeyVal('symdef','cattrs','Semiverbatim','true');
DefKeyVal('symdef','definitionURL','Semiverbatim','true');
%</ltxml>
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\symdef}
% The the |\symdef|, and |\@symdef| macros just handle optional arguments.
% \begin{macrocode}
%<*package>
\newif\if@symdeflocal
\def\symdef{\@ifnextchar[{\@symdef}{\@symdef[]}}
\def\@symdef[#1]#2{\@ifnextchar[{\@@symdef[#1]{#2}}{\@@symdef[#1]{#2}[0]}}
% \end{macrocode}
% now comes the real meat: the |\@@symdef| macro does two things, it adds the macro
% definition to the macro definition pool of the current module and also provides it.
% \begin{macrocode}
\def\@@symdef[#1]#2[#3]#4{%
% \end{macrocode}
% We use a switch to keep track of the local optional argument. We initialize the switch
% to false and check for the local keyword. Then we set all the keys that have been
% provided as arguments: aliases, local. First, using |\providecommand| we
% initialize the intermediate function, the one that can be changed internally with
% |\redefine| and then we link the actual function to it, again with |\providecommand|. We
% check if the switch for the local scope is set: if it is we are done, since this
% function has a local scope. Otherwise, we add these two functions to the module's pool
% of defined macros using |\g@addto@macro|. We add both functions so that we can keep the
% link between the real and the intermediate function whenever we inherit the
% module. Finally, using |\g@addto@macro| we add the two functions to the qualified
% version of the module.
% \begin{macrocode}
\@symdeflocalfalse\setkeys{symdef}{#1}
\expandafter\providecommand\csname modules@#2@pres\endcsname[#3]{#4}
\expandafter\def\csname#2\endcsname{\csname modules@#2@pres\endcsname}
\if@symdeflocal\else
\@ifundefined{mod@id}{}{
\expandafter\g@addto@macro\this@module{\expandafter\providecommand\csname modules@#2@pres\endcsname[#3]{#4}}%
\expandafter\g@addto@macro\this@module{\expandafter\def\csname#2\endcsname{\csname modules@#2@pres\endcsname}}
\expandafter\g@addto@macro\this@qualified@module{\expandafter\providecommand\csname modules@#2@pres@qualified\endcsname[#3]{#4}}%
\expandafter\g@addto@macro\this@qualified@module{\expandafter\def\csname#2atqualified\endcsname{\csname modules@#2@pres@qualified\endcsname}}
}\fi}
%</package>
% \end{macrocode}
% In the {\latexml} bindings, we have a top-level macro that delegates the work to two
% internal macros: |\@symdef|, which defines the content macro and |\@symdef@pres|, which
% generates the {\omdoc} |symbol| and |presentation| elements (see
% Section~\ref{sec:impl:presentation}).
% \begin{macrocode}
%<*ltxml>
DefMacro('\symdef OptionalKeyVals:symdef {}[][]{}',
sub {
my($self,@args)=@_;
# print STDERR "excluding" if LookupValue('excluding_modules');
((Invocation(T_CS('\@symdef'),@args)->unlist),
(LookupValue('excluding_modules') ? ()
: (Invocation(T_CS('\@symdef@pres'), @args)->unlist)));
});
DefPrimitive('\@symdef OptionalKeyVals:symdef {}[][]{}', sub {
my($stomach,$keys,$cs,$nargs,$opt,$presentation)=@_;
my($name,$cd,$role,$cmml,$cattrs,$definitionURL)=$keys
&& map($_ && $_->toString,map($keys->getValue($_), qw(name cd role cmml cattrs definitionURL)));
$cd = LookupValue('module_cd') unless $cd;
$nargs = (ref $nargs ? $nargs->toString : $nargs || 0);
my $module = LookupValue('current_module');
# print STDERR "Define ".Stringify($cs)." in $module\n";
my $scope = (($keys && ($keys->getValue('local') || '' eq 'true')) ? 'module_local' : 'module').":".$module;
my $attr="name='#name' meaning='#meaning' omcd='#omcd'";
DefConstructorI("\\".$cs->toString,convertLaTeXArgs($nargs,$opt),
($nargs == 0
? "<ltx:XMTok $attr scriptpos='#scriptpos'/>"
: "<ltx:XMApp scriptpos='#scriptpos'>"
. "<ltx:XMTok $attr scriptpos='#operator_scriptpos'/>"
. join('',map("<ltx:XMArg>#$_</ltx:XMArg>", (1..$nargs)))
."</ltx:XMApp>"),
properties => {name=>$name, meaning=>$cs->toString,omcd=>$cd,role => $role},
scope=>$scope);
return; });
%</ltxml>
% \end{macrocode}
% \end{macro}
%
%\begin{macro}{\redefine}
% We can use this function to redefine our intermediate presentational function inside
% the modules\ednote{does not seem to have a {\latexml} counterpart yet!}
% \begin{macrocode}
%<package>\def\redefine#1[#2]#3{\expandafter\renewcommand\csname modules@#1@pres\endcsname[#2]{#3}}
% \end{macrocode}
%\end{macro}
%
%\begin{macro}{\abbrdef}
% The |\abbrdef| macro is a variant of |\symdef| that does the same on the {\LaTeX} level.
% \begin{macrocode}
%<package>\let\abbrdef\symdef
%<*ltxml>
DefPrimitive('\abbrdef OptionalKeyVals:symdef {}[][]{}', sub {
my($stomach,$keys,$cs,$nargs,$opt,$presentation)=@_;
my $module = LookupValue('current_module');
my $scope = (($keys && ($keys->getValue('local') || '' eq 'true')) ? 'module_local' : 'module').":$module";
DefMacroI("\\".$cs->toString,convertLaTeXArgs($nargs,$opt),$presentation,
scope=>$scope);
return; });
%</ltxml>
% \end{macrocode}
% \end{macro}
%
% \subsection{Loading Module Signatures}\ednote{talk about module signatures above (SMS
% files)}
% Before we can come to the functionality we want to offer, we need some auxiliary
% functions that deal with path names.
% \begin{macro}{\mod@simplify}
% The |\mod@simplify| macro removes |xxx/..| from a string. eg: |aaa/bbb/../ddd| goes to
% |aaa/ddd|. This is used to normalize relative path names below.
% \begin{macrocode}
%<*package>
\def\mod@simplify#1{\expandafter\mod@simpl#1/\relax}
% \end{macrocode}
% It is based on the |\mod@simpl| macro
% \begin{macrocode}
\def\mod@simpl#1/#2\relax{%\message{ 1 = #1, 2 = #2 }%
\def\mod@test{}\ifx\mod@blaaaa\mod@test\edef\mod@savedprefix{}\def\mod@blaaaa{aaa}\else\fi
\def\mod@comp{#2}\ifx\mod@test\mod@comp\edef\mod@savedprefix{\mod@savedprefix#1}%
\else\mod@simplhelp#1/#2\relax\fi}
% \end{macrocode}
% which in turn is based on a helper macro
% \begin{macrocode}
\def\mod@simplhelp#1/#2/#3\relax{%
\def\mod@test{}\def\mod@tust{#2}\def\mod@tist{#3}\def\mod@tost{..}\ifx\mod@test\mod@tist%
\ifx\mod@tost\mod@tust\edef\mod@savedprefix{}\else\edef\mod@savedprefix
{\mod@savedprefix#1/#2}\fi \else\ifx\mod@tost\mod@tust\mod@simpl#3\relax%
\else\edef\mod@savedprefix{\mod@savedprefix#1/}\mod@simplhelp#2/#3\relax\fi\fi}%
% \end{macrocode}
% \end{macro}
% We will need a switch\ednote{Rares, say why?}
% \begin{macrocode}
\newif\ifmodules
% \end{macrocode}
% and a ``registry'' macro whose expansion represents the list of added macros (or files)
% \begin{macro}{\reg}
% We initialize the |\reg| macro with the empty string.
% \begin{macrocode}
\gdef\reg{}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mod@update}
% This macro provides special append functionality. It takes a string and appends it
% to the expansion of the |\reg| macro in the following way: |string@\reg|.
% \begin{macrocode}
\def\mod@update#1{\def\mod@empty{}
\ifx\reg\mod@empty\xdef\reg{#1}\else\xdef\reg{#1@\reg}\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mod@check}
% The |\mod@check| takes as input a file path (arg 3), and searches the registry. If the
% file path is not in the registry it means it means it has not been already added, so
% we make modulestrue, otherwise make modulesfalse. The macro |\mod@search| will look at
% ifinclude and update the registry for modulestrue or do nothing for modulesfalse.
% \begin{macrocode}
\def\mod@check#1@#2///#3\relax{%
\def\mod@empty{}\def\mod@one{#1}\def\mod@two{#2}\def\mod@three{#3}%
% \end{macrocode}
% Define a few intermediate macros so that we can split the registry into separate file
% paths and compare to the new one
% \begin{macrocode}
\expandafter\ifx\mod@three\mod@one\modulestrue\else\ifx\mod@two\mod@empty\modulesfalse%
\else\mod@check#2///#3\relax\fi\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mod@search}
% Macro for updating the registry after the execution of |\mod@check|
% \begin{macrocode}
\def\mod@search#1{%
% \end{macrocode}
% We put the registry as the first argument for |\mod@check| and the other
% argument is the new file path.
% \begin{macrocode}
\modulesfalse\expandafter\mod@check\reg @///#1\relax%
% \end{macrocode}
% We run |\mod@check| with these arguments and the check |\ifmodules| for
% the result
% \begin{macrocode}
\ifmodules\else\mod@update{#1}\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mod@reguse}
% The macro operates almost as the |mod@search| function, but it does not update the
% registry. Its purpose is to check whether some file is or not inside the registry but
% without updating it. Will be used before deciding on a new sms file
% \begin{macrocode}
\def\mod@reguse#1{\modulesfalse\expandafter\mod@check\reg @///#1\relax}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mod@prefix}
% This is a local macro for storing the path prefix, we initialize it as the empty
% string.
% \begin{macrocode}
\def\mod@prefix{}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mod@updatedpre}
% This macro allows to update the path prefix with the last part of the new path
% \begin{macrocode}
\def\mod@updatedpre#1{
\edef\mod@prefix{\mod@prefix\mod@pathprefix@check#1/\relax}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mod@pathprefix@check}
% |\mod@pathprefix@check| returns the last word in a string composed of words separated
% by slashes
% \begin{macrocode}
\def\mod@pathprefix@check#1/#2\relax{%
\ifx\\#2\\% no slash in string
\else\mod@ReturnAfterFi{#1/\mod@pathprefix@help#2\relax}%
\fi}
% \end{macrocode}
% It needs two helper macros:
% \begin{macrocode}
\def\mod@pathprefix@help#1/#2\relax{%
\ifx\\#2\\% end of recursion
\else\mod@ReturnAfterFi{#1/\mod@pathprefix@help#2\relax}%
\fi}
\long\def\mod@ReturnAfterFi#1\fi{\fi#1}
% \end{macrocode}
% \end{macro}
%
%\begin{macro}{\mod@pathpostfix@check}
% |\mod@pathpostfix@check| takes a string composed of words separated by slashes and
% returns the part of the string until the last slash
% \begin{macrocode}
\def\mod@pathpostfix@check#1/#2\relax{% slash
\ifx\\#2\\%no slash in string
#1\else\mod@ReturnAfterFi{\mod@pathpostfix@help#2\relax}%
\fi}
% \end{macrocode}
% Helper function for the pathpostfix@check function defined above
% \begin{macrocode}
\def\mod@pathpostfix@help#1/#2\relax{%
\ifx\\#2\\%
#1\else\mod@ReturnAfterFi{\mod@pathpostfix@help#2\relax}%
\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
\def\mod@updatedpost#1{%
\edef\mod@savedprefix{\mod@savedprefix\mod@pathpostfix@check#1/\relax} }
% \end{macrocode}
% Macro that will add a |.sms| extension to a path. Will be used when adding a |.sms| file
% \begin{macrocode}
\def\mod@updatesms{\edef\mod@savedprefix{\mod@savedprefix.sms}}
%</package>
% \end{macrocode}
%
% \subsection{Selective Inclusion}
%
% \begin{macro}{\requiremodules}
% \begin{macrocode}
%<*package>
\newcommand{\requiremodules}[1]{%
{\mod@updatedpre{#1} % add the new file to the already existing path
\let\mod@savedprefix\mod@prefix % add the path to the new file to the prefix
\mod@updatedpost{#1}
\def\mod@blaaaa{} % macro used in the simplify function (remove .. from the prefix)
\mod@simplify{\mod@savedprefix} % remove |xxx/..| from the path (in case it exists)
\mod@reguse{\mod@savedprefix}
\ifmodules\else
\mod@updatesms % update the file to contain the .sms extension
\let\newreg\reg % use to compare, in case the .sms file was loaded before
\mod@search{\mod@savedprefix} % update registry
\ifx\newreg\reg\else\input{\mod@savedprefix}\fi % check if the registry was updated and load if necessary
\fi}}
%</package>
%<*ltxml>
DefPrimitive('\requiremodules{}', sub {
my($stomach,$module)=@_;
my $GULLET = $stomach->getGullet;
$module = Digest($module)->toString;
if(LookupValue('module_'.$module.'_loaded')) {}
else {
AssignValue('module_'.$module.'_loaded' => 1, 'global');
$stomach->bgroup;
AssignValue('last_module_path', $module);
$GULLET->unread(T_CS('\end@requiredmodule'));
AssignValue('excluding_modules' => 1);
$GULLET->input($module,['sms']);
}
return;});
DefPrimitive('\end@requiredmodule{}',sub {
#close the group
$_[0]->egroup;
#print STDERR "END: ".ToString(Digest($_[1])->toString);
#Take care of any imported elements in this current module by activating it and all its dependencies
#print STDERR "Important: ".ToString(Digest($_[1])->toString)."\n";
use_module(ToString(Digest($_[1])->toString));
return; });
%</ltxml>
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\sinput}
% \begin{macrocode}
%<*package>
\def\sinput#1{
{\mod@updatedpre{#1} % add the new file to the already existing path
\let\mod@savedprefix\mod@prefix % add the path to the new file to the prefix
\mod@updatedpost{#1}
\def\mod@blaaaa{} % macro used in the simplify function (remove .. from the prefix)
\mod@simplify{\mod@savedprefix} % remove |xxx/..| from the path (in case it exists)
\mod@reguse{\mod@savedprefix}
\let\newreg\reg % use to compare, in case the .sms file was loaded before
\mod@search{\mod@savedprefix} % update registry
\ifx\newreg\reg%\message{This file has been previously introduced}
\else\input{\mod@savedprefix}\fi}}
%</package>
%<*ltxml>
DefPrimitive('\sinput{}', sub {
my($stomach,$module)=@_;
my $GULLET = $stomach->getGullet;
$module = Digest($module)->toString;
AssignValue('module_'.$module.'_loaded' => 1, 'global');
$stomach->bgroup;
AssignValue('last_module_path', $module);
$GULLET->unread(Invocation(T_CS('\end@requiredmodule'),T_OTHER($module))->unlist);
$GULLET->input($module,['tex']);
return;});
%</ltxml>
% \end{macrocode}
% \end{macro}
% \ednote{the sinput macro is just faked, it should be more like requiremodules, except
% that the tex file is inputted; I wonder if this can be simplified.}
%
% \subsection{Generating {\texorpdfstring\omdoc{OMDoc}} Presentation Elements}\label{sec:impl:presentation}
%
% Additional bundle of code to generate presentation encodings. Redefined to an expandable
% (macro) so that we can add conversions.
%
% \begin{macrocode}
%<*ltxml>
DefMacro('\@symdef@pres OptionalKeyVals:symdef {}[][]{}', sub {
my($self,$keys, $cs,$nargs,$opt,$presentation)=@_;
Invocation(T_CS('\@symdef@pres@aux'),
$cs,
($nargs || Tokens(T_OTHER(0))),
symdef_presentation_pmml($cs,ToString($nargs)||0,$presentation),
symdef_presentation_TeX($presentation),
$keys)->unlist; });
% \end{macrocode}
% Generate the expansion of a symdef'd macro using special arguments
% \begin{macrocode}
sub symdef_presentation_pmml {
my($cs,$nargs,$presentation)=@_;
my @toks = $presentation->unlist;
while(@toks && $toks[0]->equals(T_SPACE)){ pop(@toks); } # Remove leading space
$presentation = Tokens(@toks);
# Wrap with \@use, unless already has a recognized formatter.
$presentation = Invocation(T_CS('\@use'),$presentation) # Using simple text for now, until getting a proper \@use
unless @toks && ($toks[0]->toString =~ /^\\(infix|prefix|postfix|assoc|use|mixfixi|mixfixa|mixfixii|mixfixia|mixfixai|mixfixiii)$/);
# Low level substitution.
my @args = map(Invocation(T_CS('\@SYMBOL'),T_OTHER("pres_arg:".($_+1))),1..$nargs);
$presentation = Tokens(LaTeXML::Expandable::substituteTokens($presentation,@args));
$presentation; }
% \end{macrocode}
% The |\@use| macro just generates the contents of the notation element
% \begin{macrocode}
DefConstructor('\@use {}',
"<omdoc:prototype>"
. "<om:OMS cd='' name=''/>"
."</omdoc:prototype>"
."<omdoc:rendering>"
. "<ltx:Math><ltx:XMath>#1</ltx:XMath></ltx:Math>"
."</omdoc:rendering>",
mode=>'inline_math');
% \end{macrocode}
% The |get_cd| procedure reads of the cd from our list of keys.
% \begin{macrocode}
sub get_cd {
my($name,$cd,$role,$cmml,$cattrs,$definitionURL)=@_;
return $cd;}
% \end{macrocode}
% The |\@symdef@pres@aux| creates the |symbol| element and the outer layer of the of the
% |notation| element. The content of the latter is generated by applying the {\latexml} to
% the definiens of the |\symdef| form.
% \begin{macrocode}
DefConstructor('\@symdef@pres@aux{}{}{}{} OptionalKeyVals:symdef',
"<omdoc:symbol name='#1'/>"
."<omdoc:notation name='#name' cd='&get_cd(#5)'>"
."#3"
."</omdoc:notation>",
afterDigest=>sub { my ($stomach, $whatsit) = @_;
my $keys = $whatsit->getArg(5);
my $module = LookupValue('current_module');
$whatsit->setProperties(for=>ToString($whatsit->getArg(1)));
$whatsit->setProperty(role=>($keys ? $keys->getValue('role')
: (ToString($whatsit->getArg(2)) ? 'applied'
: undef))); });
% \end{macrocode}
% Convert a macro body (tokens with parameters |#1|,..) into a Presentation |style=TeX| form.
% walk through the tokens, breaking into chunks of neutralized (|T_OTHER|) tokens and
% parameter specs.
% \begin{macrocode}
sub symdef_presentation_TeX {
my($presentation)=@_;
my @tokens = $presentation->unlist;
my(@frag,@frags) = ();
while(my $tok = shift(@tokens)){
if($tok->equals(T_PARAM)){
push(@frags,Invocation(T_CS('\@symdef@pres@text'),Tokens(@frag))) if @frag;
@frag=();
my $n = shift(@tokens)->getString;
push(@frags,Invocation(T_CS('\@symdef@pres@arg'),T_OTHER($n+1))); }
else {
push(@frag,T_OTHER($tok->getString)); }} # IMPORTANT! Neutralize the tokens!
push(@frags,Invocation(T_CS('\@symdef@pres@text'),Tokens(@frag))) if @frag;
Tokens(map($_->unlist,@frags)); }
DefConstructor('\@symdef@pres@arg{}', "<omdoc:recurse select='#select'/>",
afterDigest=>sub { my ($stomach, $whatsit) = @_;
my $select = $whatsit->getArg(1);
$select = ref $select ? $select->toString : '';
$whatsit->setProperty(select=>"*[".$select."]"); });
DefConstructor('\@symdef@pres@text{}', "<omdoc:text>#1</omdoc:text>");
%</ltxml>
% \end{macrocode}
%
%
% \subsection{Including Externally Defined Semantic Macros }\label{sec:impl:packages}
%
% \begin{macro}{\requirepackage}
% \begin{macrocode}
%<package>\def\requirepackage#1#2{\makeatletter\input{#1.sty}\makeatother}
%<*ltxml>
DefConstructor('\requirepackage{} Semiverbatim',"<omdoc:imports from='#2'/>",
afterDigest=>sub { my ($stomach, $whatsit) = @_;
my $select = $whatsit->getArg(1);
RequirePackage($select->toString); });
% \end{macrocode}
% \end{macro}
%
% \subsection{Deprecated Functionality}\label{sec:impl:deprecated}
%
% In this section we centralize old interfaces that are only partially supported any more.
% \begin{macro}{module:uses}
% For each the module name |xxx| specified in the |uses| key, we activate their symdefs
% and we export the local symdefs.\ednote{this isue is deprecated, it will be removed
% before 1.0.}
% \begin{macrocode}
%<*package>
\define@key{module}{uses}{%
\@for\module@tmp:=#1\do{\activate@defs\module@tmp\export@defs\module@tmp}}
%</package>
% \end{macrocode}
%
% \begin{macro}{module:usesqualified}
% This option operates similarly to the module:uses option defined above. The only
% difference is that here we import modules with a prefix. This is useful when two
% modules provide a macro with the same name.
% \begin{macrocode}
%<*package>
\define@key{module}{usesqualified}{%
\@for\module@tmp:=#1\do{\activate@defs{qualified@\module@tmp}\export@defs\module@tmp}}
%</package>
% \end{macrocode}
% \end{macro}
%
% \subsection{Finale}
%
% Finally, we need to terminate the file with a success mark for perl.
% \begin{macrocode}
%<ltxml>1;
% \end{macrocode}
%
% \section {Utility}\label{sec:utilities}
% \Finale
\endinput
% \iffalse
%%% Local Variables:
%%% mode: doctex
%%% TeX-master: t
%%% End:
% LocalWords: GPL structuresharing STR dtx env envfalse idfalse displayfalse
% LocalWords: usesfalse usesqualified usesqualifiedfalse envtrue idtrue CPERL
% LocalWords: usestrue displaytrue usesqualifiedtrue RequirePackage keyval tmp
% LocalWords: defs foreach LookupValue activateScope DefEnvironment keyvals cd
% LocalWords: OptionalKeyVals getValue toString AssignValue openElement omdoc
% LocalWords: closeElement beforeDigest useTheoryItemizations afterDigestBegin
% LocalWords: whatsit setProperty getArg qw symdef cmml cattrs definitionURL
% LocalWords: DefKeyVal Semiverbatim symdeflocal atqualified DefMacro STDERR
% LocalWords: args unlist DefPrimitive nargs Stringify eq attr omcd ltx XMTok
% LocalWords: DefConstructorI convertLaTeXArgs scriptpos XMApp OMA XMArg simpl
% LocalWords: DefMacroI blaaaa savedprefix aaa simplhelp tust tist tost reguse
% LocalWords: updatedpre ReturnAfterFi updateall updatedpost updatesms bgroup
% LocalWords: texclude tinclude getGullet requiredmodule tex sms egroup pmml
% LocalWords: toks mixfixi mixfixa mixfixii mixfixia mixfixai mixfixiii arg
% LocalWords: DefConstructor afterDigest setProperties undef tok PARAM
% LocalWords: getString
% \fi
|