1 /*
2 blahtex: a TeX to MathML converter designed with MediaWiki in mind
3 blahtexml: an extension of blahtex with XML processing in mind
4 http://gva.noekeon.org/blahtexml
5 
6 Copyright (c) 2006, David Harvey
7 All rights reserved.
8 
9 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
10 
11     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
13     * Neither the names of the authors nor the names of their affiliation may be used to endorse or promote products derived from this software without specific prior written permission.
14 
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16 */
17 
18 #ifndef BLAHTEX_PARSETREE_H
19 #define BLAHTEX_PARSETREE_H
20 
21 // Everything here is implemented variously in ParseTree1.cpp,
22 // ParseTree2.cpp and ParseTree3.cpp.
23 
24 #include <memory>
25 #include "LayoutTree.h"
26 
27 // The ParseTree namespace contains all classes representing nodes in the
28 // parse tree. This is essentially a tree representation of the input
29 // TeX expression, with as little additional processing done as possible.
30 // The idea is that the "purified TeX" should be easily reconstructible
31 // from the parse tree.
32 
33 namespace blahtex
34 {
35 
36 // This struct describes (approximately) a TeX font during math mode.
37 struct TexMathFont
38 {
39     enum Family
40     {
41         cFamilyDefault,  // indicates default font
42                          // (e.g. "x" gets italics, "1" gets roman)
43         cFamilyRm,       // roman
44         cFamilyBf,       // bold
45         cFamilyIt,       // italics
46         cFamilySf,       // sans serif
47         cFamilyTt,       // typewriter
48         cFamilyBb,       // blackboard bold
49         cFamilyCal,      // calligraphic
50         cFamilyFrak      // fraktur
51     }
52     mFamily;
53 
54     // Whether or not we are in "\boldsymbol" mode (from AMS packages).
55     // This seems to be mostly orthogonal to the family. (I haven't
56     // studied carefully how this is implemented in TeX.)
57     bool mIsBoldsymbol;
58 
59     TexMathFont(
60         Family family = cFamilyDefault,
61         bool isBoldsymbol = false
62     ) :
mFamilyTexMathFont63         mFamily(family),
64         mIsBoldsymbol(isBoldsymbol)
65     { }
66 
67     // This function finds the closest MathML font (i.e. value of
68     // mathvariant) which matches this TeX font.
69     MathmlFont GetMathmlApproximation() const;
70 };
71 
72 // This struct describes (approximately) a TeX font during text mode.
73 struct TexTextFont
74 {
75     enum Family
76     {
77         cFamilyRm,       // roman
78         cFamilySf,       // sans serif
79         cFamilyTt        // typewriter
80     }
81     mFamily;
82 
83     bool mIsBold;
84     bool mIsItalic;
85 
86     TexTextFont(
87         Family family = cFamilyRm,
88         bool isBold = false,
89         bool isItalic = false
90     ) :
mFamilyTexTextFont91         mFamily(family),
92         mIsBold(isBold),
93         mIsItalic(isItalic)
94     { }
95 
96     // This function finds the closest MathML font (i.e. value of
97     // mathvariant) which matches this TeX font.
98     MathmlFont GetMathmlApproximation() const;
99 };
100 
101 
102 // This struct represents some state information during the parse tree =>
103 // layout tree building phase (i.e. while within BuildLayoutTree).
104 struct TexProcessingState
105 {
106     TexMathFont mMathFont;
107     TexTextFont mTextFont;
108     LayoutTree::Node::Style mStyle;
109     RGBColour mColour;
110 };
111 
112 
113 // This struct keeps track of the packages, encodings etc, that LaTeX will
114 // need to be able to handle the given input.
115 struct LatexFeatures
116 {
117     // Requires amsmath, amsfonts, amssymb packages
118     bool mNeedsAmsmath;
119     bool mNeedsAmsfonts;
120     bool mNeedsAmssymb;
121 
122     // Requires "\usepackage[utf8x]{inputenc}".
123     bool mNeedsUcs;
124 
125     // Requires the "color" package.
126     bool mNeedsColor;
127 
128     // Requires "X2" font encoding (for cyrillic).
129     bool mNeedsX2;
130 
131     // Requires the "CJK" package.
132     bool mNeedsCJK;
133 
134     // Needs a japanese font to be installed.
135     bool mNeedsJapaneseFont;
136 
LatexFeaturesLatexFeatures137     LatexFeatures() :
138         mNeedsAmsmath(false),
139         mNeedsAmsfonts(false),
140         mNeedsAmssymb(false),
141         mNeedsUcs(false),
142         mNeedsColor(false),
143         mNeedsX2(false),
144         mNeedsCJK(false),
145         mNeedsJapaneseFont(false)
146     { }
147 
148     // Given the LaTeX command "command", checks to see if any of the above
149     // flags need to be switched on for that command to work.
150     void Update(const std::wstring& command);
151 };
152 
153 
154 // While preparing the purified TeX, blahtex keeps track of something
155 // approximating the current font encoding. E.g. while in X2 encoding, only
156 // cyrillic characters and whitespace are allowed.
157 enum FontEncoding
158 {
159     cFontEncodingDefault,
160     cFontEncodingCyrillic,
161     cFontEncodingJapanese
162 };
163 
164 
165 namespace ParseTree
166 {
167     // Base class for nodes in the parse tree.
168     struct Node
169     {
~NodeNode170         virtual ~Node()
171         { };
172 
173         // This function converts the parse tree under this node into a
174         // layout tree. This is where most of blahtex's hard work is done.
175         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
176             const TexProcessingState& state
177         ) const = 0;
178 
179         // This function converts the parse tree under this node to
180         // "purified TeX"; that is, TeX markup that can get sent to LaTeX
181         // for PNG generation. Output gets written to the supplied stream.
182         //
183         // This (obviously) does not include the file header and footer;
184         // see Manager::GeneratePurifiedTex for that.
185         //
186         // The "features" object is used to store a list of e.g. LaTeX
187         // packages that will be required to handle the given output.
188         virtual void GetPurifiedTex(
189             std::wostream& os,
190             LatexFeatures& features,
191             FontEncoding fontEncoding
192         ) const = 0;
193 
194         // Print() recursively prints the parse tree under this node.
195         // Debugging use only.
196         virtual void Print(
197             std::wostream& os,
198             int depth = 0
199         ) const = 0;
200     };
201 
202 
203     // MathNode represents any node occurring during math mode.
204     struct MathNode : Node
205     {
206     };
207 
208     // TextNode represents any node occurring during text mode.
209     struct TextNode : Node
210     {
211     };
212 
213 
214     // Represents any command like "a", "1", "\alpha", "\int" which blahtex
215     // treats as a single symbol. Also includes spacing commands like "\,".
216     struct MathSymbol : MathNode
217     {
218         // The command, e.g. "a", "\alpha".
219         std::wstring mCommand;
220 
MathSymbolMathSymbol221         MathSymbol(const std::wstring& command) :
222             mCommand(command)
223         { }
224 
225         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
226             const TexProcessingState& state
227         ) const;
228 
229         virtual void GetPurifiedTex(
230             std::wostream& os,
231             LatexFeatures& features,
232             FontEncoding fontEncoding
233         ) const;
234 
235         virtual void Print(
236             std::wostream& os,
237             int depth
238         ) const;
239     };
240 
241     // Represents a command taking a single argument.
242     struct MathCommand1Arg : MathNode
243     {
244         // The command, e.g. "\hat", "\mathop".
245         std::wstring mCommand;
246 
247         // Node corresponding to the argument of the command.
248         std::auto_ptr<MathNode> mChild;
249 
MathCommand1ArgMathCommand1Arg250         MathCommand1Arg(
251             const std::wstring& command,
252             std::auto_ptr<MathNode> child
253         ) :
254             mCommand(command),
255             mChild(child)
256         { }
257 
258         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
259             const TexProcessingState& state
260         ) const;
261 
262         virtual void GetPurifiedTex(
263             std::wostream& os,
264             LatexFeatures& features,
265             FontEncoding fontEncoding
266         ) const;
267 
268         virtual void Print(
269             std::wostream& os,
270             int depth
271         ) const;
272     };
273 
274 
275     // Represents a TeX state change command like "\rm", "\scriptstyle",
276     // "\color".
277     struct MathStateChange : MathNode
278     {
279         // The style change command, e.g. "\scriptstyle".
280         std::wstring mCommand;
281 
MathStateChangeMathStateChange282         MathStateChange(
283             const std::wstring& command
284         ) :
285             mCommand(command)
286         { }
287 
288         // Modifies "state" according to the state change command.
289         virtual void Apply(
290             TexProcessingState& state
291         ) const;
292 
293         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
294             const TexProcessingState& state
295         ) const;
296 
297         virtual void GetPurifiedTex(
298             std::wostream& os,
299             LatexFeatures& features,
300             FontEncoding fontEncoding
301         ) const;
302 
303         virtual void Print(
304             std::wostream& os,
305             int depth
306         ) const;
307     };
308 
309 
310     // Represents a "\color{xyz}" command in math mode.
311     struct MathColour : MathStateChange
312     {
313         // The colour name, e.g. "red".
314         std::wstring mColourName;
315 
MathColourMathColour316         MathColour(
317             const std::wstring& colourName
318         ) :
319             MathStateChange(L"\\color"),
320             mColourName(colourName)
321         { }
322 
323         virtual void Apply(
324             TexProcessingState& state
325         ) const;
326 
327         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
328             const TexProcessingState& state
329         ) const;
330 
331         virtual void GetPurifiedTex(
332             std::wostream& os,
333             LatexFeatures& features,
334             FontEncoding fontEncoding
335         ) const;
336 
337         virtual void Print(
338             std::wostream& os,
339             int depth
340         ) const;
341     };
342 
343 
344     // Represents a command taking two arguments, including infix commands.
345     struct MathCommand2Args : MathNode
346     {
347         // The command, e.g. "\frac", "\choose".
348         std::wstring mCommand;
349 
350         // The two arguments.
351         std::auto_ptr<MathNode> mChild1, mChild2;
352 
353         // This flag is set for infix commands like "\over".
354         bool mIsInfix;
355 
MathCommand2ArgsMathCommand2Args356         MathCommand2Args(
357             const std::wstring& command,
358             std::auto_ptr<MathNode> child1,
359             std::auto_ptr<MathNode> child2,
360             bool isInfix
361         ) :
362             mCommand(command),
363             mChild1(child1),
364             mChild2(child2),
365             mIsInfix(isInfix)
366         { }
367 
368         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
369             const TexProcessingState& state
370         ) const;
371 
372         virtual void GetPurifiedTex(
373             std::wostream& os,
374             LatexFeatures& features,
375             FontEncoding fontEncoding
376         ) const;
377 
378         virtual void Print(
379             std::wostream& os,
380             int depth
381         ) const;
382     };
383 
384 
385     // Represents a "big" command like "\big", "\bigg" etc.
386     struct MathBig : MathNode
387     {
388         // The command, e.g. "\big".
389         std::wstring mCommand;
390 
391         // The delimiter that the big command is applied to, e.g. "\langle".
392         std::wstring mDelimiter;
393 
MathBigMathBig394         MathBig(
395             const std::wstring& command,
396             const std::wstring& delimiter
397         ) :
398             mCommand(command),
399             mDelimiter(delimiter)
400         { }
401 
402         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
403             const TexProcessingState& state
404         ) const;
405 
406         virtual void GetPurifiedTex(
407             std::wostream& os,
408             LatexFeatures& features,
409             FontEncoding fontEncoding
410         ) const;
411 
412         virtual void Print(
413             std::wostream& os,
414             int depth
415         ) const;
416     };
417 
418 
419     // Represents material surrounded by grouping braces, e.g. "{abc}" gets
420     // stored as a MathGroup node whose child contains "abc".
421     struct MathGroup : MathNode
422     {
423         // The enclosed material.
424         std::auto_ptr<MathNode> mChild;
425 
MathGroupMathGroup426         MathGroup(std::auto_ptr<MathNode> child) :
427             mChild(child)
428         { }
429 
430         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
431             const TexProcessingState& state
432         ) const;
433 
434         virtual void GetPurifiedTex(
435             std::wostream& os,
436             LatexFeatures& features,
437             FontEncoding fontEncoding
438         ) const;
439 
440         virtual void Print(
441             std::wostream& os,
442             int depth
443         ) const;
444     };
445 
446 
447     // Represents a sequence of nodes in math mode, concatenated together.
448     // e.g. "a\alpha 2" is stored as a MathList containing three MathSymbol
449     // nodes.
450     struct MathList : MathNode
451     {
452         std::vector<MathNode*> mChildren;
453 
454         ~MathList();
455 
456         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
457             const TexProcessingState& state
458         ) const;
459 
460         virtual void GetPurifiedTex(
461             std::wostream& os,
462             LatexFeatures& features,
463             FontEncoding fontEncoding
464         ) const;
465 
466         virtual void Print(
467             std::wostream& os,
468             int depth
469         ) const;
470     };
471 
472 
473     // Represents a base with a superscript and/or subscript.
474     // (i.e. an expression like "x^y_z".)
475     struct MathScripts : MathNode
476     {
477         // All three fields are optional (NULL indicates an empty field).
478         std::auto_ptr<MathNode> mBase, mUpper, mLower;
479 
480         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
481             const TexProcessingState& state
482         ) const;
483 
484         virtual void GetPurifiedTex(
485             std::wostream& os,
486             LatexFeatures& features,
487             FontEncoding fontEncoding
488         ) const;
489 
490         virtual void Print(
491             std::wostream& os,
492             int depth
493         ) const;
494     };
495 
496 
497     // Represents a "limits" command, i.e. one of "\limits", "\nolimits",
498     // or "\displaylimits".
499     struct MathLimits : MathNode
500     {
501         // The command, e.g. "\limits".
502         std::wstring mCommand;
503 
504         // mChild is the operator that the limits command is applied to.
505         // e.g. for the input "x^2\limits_5", the base of the MathScripts
506         // node should be a MathLimits node, whose child is the MathSymbol
507         // node representing "x".
508         std::auto_ptr<MathNode> mChild;
509 
MathLimitsMathLimits510         MathLimits(
511             const std::wstring& command,
512             std::auto_ptr<MathNode> child
513         ) :
514             mCommand(command),
515             mChild(child)
516         { }
517 
518         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
519             const TexProcessingState& state
520         ) const;
521 
522         virtual void GetPurifiedTex(
523             std::wostream& os,
524             LatexFeatures& features,
525             FontEncoding fontEncoding
526         ) const;
527 
528         virtual void Print(
529             std::wostream& os,
530             int depth
531         ) const;
532     };
533 
534 
535     // Represents an expression surrounded by "\left( ... \right)".
536     struct MathDelimited : MathNode
537     {
538         // The delimiters, e.g. "\langle", "(".
539         std::wstring mLeftDelimiter, mRightDelimiter;
540 
541         // The stuff enclosed by the delimiters:
542         std::auto_ptr<MathNode> mChild;
543 
MathDelimitedMathDelimited544         MathDelimited(
545             std::auto_ptr<MathNode> child,
546             const std::wstring& leftDelimiter,
547             const std::wstring& rightDelimiter
548         ) :
549             mChild(child),
550             mLeftDelimiter(leftDelimiter),
551             mRightDelimiter(rightDelimiter)
552         { }
553 
554         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
555             const TexProcessingState& state
556         ) const;
557 
558         virtual void GetPurifiedTex(
559             std::wostream& os,
560             LatexFeatures& features,
561             FontEncoding fontEncoding
562         ) const;
563 
564         virtual void Print(
565             std::wostream& os,
566             int depth
567         ) const;
568     };
569 
570 
571     // Represents a row of a table, e.g. might represent the
572     // TeX subexpression "a & b & c".
573     struct MathTableRow : MathNode
574     {
575         // The entries in the row.
576         std::vector<MathNode*> mEntries;
577 
578         ~MathTableRow();
579 
580         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
581             const TexProcessingState& state
582         ) const;
583 
584         virtual void GetPurifiedTex(
585             std::wostream& os,
586             LatexFeatures& features,
587             FontEncoding fontEncoding
588         ) const;
589 
590         virtual void Print(
591             std::wostream& os,
592             int depth
593         ) const;
594     };
595 
596 
597     // Represents a table, e.g. might represent the TeX subexpression
598     // expression "a & b & c \\ \\ d & e & f \\ g & h".
599     struct MathTable : MathNode
600     {
601         // The rows of the table.
602         std::vector<MathTableRow*> mRows;
603 
604         ~MathTable();
605 
606         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
607             const TexProcessingState& state
608         ) const;
609 
610         virtual void GetPurifiedTex(
611             std::wostream& os,
612             LatexFeatures& features,
613             FontEncoding fontEncoding
614         ) const;
615 
616         virtual void Print(
617             std::wostream& os,
618             int depth
619         ) const;
620     };
621 
622 
623     // Represents an environment, i.e. "\begin{xxx} ... \end{xxx}".
624     // Currently all supported environments are just various forms of table,
625     // so for the moment we insist that it contains a table.
626     struct MathEnvironment : MathNode
627     {
628         // Currently one of:
629         // "matrix", "pmatrix", "bmatrix", "Bmatrix", "vmatrix", "Vmatrix",
630         // "cases", "smallmatrix", "aligned", "substack"
631         std::wstring mName;
632 
633         // True for things like "\substack" which don't need "\begin"
634         // and "\end";
635         // False for anything involving "\begin" and "\end"
636         bool mIsShort;
637 
638         // The contained table.
639         std::auto_ptr<MathTable> mTable;
640 
MathEnvironmentMathEnvironment641         MathEnvironment(
642             const std::wstring& name,
643             std::auto_ptr<MathTable> table,
644             bool isShort
645         ) :
646             mName(name),
647             mTable(table),
648             mIsShort(isShort)
649         { }
650 
651         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
652             const TexProcessingState& state
653         ) const;
654 
655         virtual void GetPurifiedTex(
656             std::wostream& os,
657             LatexFeatures& features,
658             FontEncoding fontEncoding
659         ) const;
660 
661         virtual void Print(
662             std::wostream& os,
663             int depth
664         ) const;
665     };
666 
667 
668     // Represents a command that switches from math mode into text mode,
669     // e.g. "\text". Note that certain commands (e.g. "\text") will be
670     // translated into a TextCommand1Arg node if encountered during text
671     // mode, but into a EnterTextMode if encountered during math mode.
672     struct EnterTextMode : MathNode
673     {
674         // The command, e.g. "\text".
675         std::wstring mCommand;
676 
677         // The enclosed *text-mode* node.
678         std::auto_ptr<TextNode> mChild;
679 
EnterTextModeEnterTextMode680         EnterTextMode(
681             const std::wstring& command,
682             std::auto_ptr<TextNode> child
683         ) :
684             mCommand(command),
685             mChild(child)
686         { }
687 
688         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
689             const TexProcessingState& state
690         ) const;
691 
692         virtual void GetPurifiedTex(
693             std::wostream& os,
694             LatexFeatures& features,
695             FontEncoding fontEncoding
696         ) const;
697 
698         virtual void Print(
699             std::wostream& os,
700             int depth
701         ) const;
702     };
703 
704 
705     // Represents a sequence of nodes in text mode, concatenated together.
706     // e.g. "abc" is stored as a TextList containing three TextSymbol nodes.
707     struct TextList : TextNode
708     {
709         std::vector<TextNode*> mChildren;
710 
711         ~TextList();
712 
713         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
714             const TexProcessingState& state
715         ) const;
716 
717         virtual void GetPurifiedTex(
718             std::wostream& os,
719             LatexFeatures& features,
720             FontEncoding fontEncoding
721         ) const;
722 
723         virtual void Print(
724             std::wostream& os,
725             int depth
726         ) const;
727     };
728 
729 
730     // Represents text mode material surrounded by grouping braces.
731     struct TextGroup : TextNode
732     {
733         // The enclosed material.
734         std::auto_ptr<TextNode> mChild;
735 
TextGroupTextGroup736         TextGroup(std::auto_ptr<TextNode> child) :
737             mChild(child)
738         { }
739 
740         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
741             const TexProcessingState& state
742         ) const;
743 
744         virtual void GetPurifiedTex(
745             std::wostream& os,
746             LatexFeatures& features,
747             FontEncoding fontEncoding
748         ) const;
749 
750         virtual void Print(
751             std::wostream& os,
752             int depth
753         ) const;
754     };
755 
756 
757     // Represents any text mode command like "a", "1", "\textbackslash"
758     // that is treated as a single symbol (includes spacing commands
759     // like "\,").
760     struct TextSymbol : TextNode
761     {
762         // The command, e.g. "a" or "\textbackslash"
763         std::wstring mCommand;
764 
TextSymbolTextSymbol765         TextSymbol(const std::wstring& command) :
766             mCommand(command)
767         { }
768 
769         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
770             const TexProcessingState& state
771         ) const;
772 
773         virtual void GetPurifiedTex(
774             std::wostream& os,
775             LatexFeatures& features,
776             FontEncoding fontEncoding
777         ) const;
778 
779         virtual void Print(
780             std::wostream& os,
781             int depth
782         ) const;
783     };
784 
785 
786     // Represents a state change command like "\rm" occurring in text mode.
787     struct TextStateChange : TextNode
788     {
789         // The command, e.g. "\rm".
790         std::wstring mCommand;
791 
TextStateChangeTextStateChange792         TextStateChange(
793             const std::wstring& command
794         ) :
795             mCommand(command)
796         { }
797 
798         // Modifies "state" according to the state change command.
799         virtual void Apply(
800             TexProcessingState& state
801         ) const;
802 
803         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
804             const TexProcessingState& state
805         ) const;
806 
807         virtual void GetPurifiedTex(
808             std::wostream& os,
809             LatexFeatures& features,
810             FontEncoding fontEncoding
811         ) const;
812 
813         virtual void Print(
814             std::wostream& os,
815             int depth
816         ) const;
817     };
818 
819 
820     // Represents a "\color{xyz}" command in text mode.
821     struct TextColour : TextStateChange
822     {
823         // The colour name, e.g. "red".
824         std::wstring mColourName;
825 
TextColourTextColour826         TextColour(
827             const std::wstring& colourName
828         ) :
829             TextStateChange(L"\\color"),
830             mColourName(colourName)
831         { }
832 
833         virtual void Apply(
834             TexProcessingState& state
835         ) const;
836 
837         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
838             const TexProcessingState& state
839         ) const;
840 
841         virtual void GetPurifiedTex(
842             std::wostream& os,
843             LatexFeatures& features,
844             FontEncoding fontEncoding
845         ) const;
846 
847         virtual void Print(
848             std::wostream& os,
849             int depth
850         ) const;
851     };
852 
853 
854     // Represents a command in text mode taking a single argument.
855     struct TextCommand1Arg : TextNode
856     {
857         // The command, e.g. "\textrm".
858         std::wstring mCommand;
859 
860         // Node corresponding to the argument of the command.
861         std::auto_ptr<TextNode> mChild;
862 
TextCommand1ArgTextCommand1Arg863         TextCommand1Arg(
864             const std::wstring& command,
865             std::auto_ptr<TextNode> child
866         ) :
867             mCommand(command),
868             mChild(child)
869         { }
870 
871         virtual std::auto_ptr<LayoutTree::Node> BuildLayoutTree(
872             const TexProcessingState& state
873         ) const;
874 
875         virtual void GetPurifiedTex(
876             std::wostream& os,
877             LatexFeatures& features,
878             FontEncoding fontEncoding
879         ) const;
880 
881         virtual void Print(
882             std::wostream& os,
883             int depth
884         ) const;
885     };
886 
887 } // end ParseTree namespace
888 
889 }
890 
891 #endif
892 
893 // end of file @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
894