/* Operator.C * * Some tokens like the curly braces have many meanings in many places. * However, for most tokens there is a simple one-to-one mapping between * the token and some operation to be performed. There are a number of * common types of Operators, and then some special purpose ones. * * Copyright 1992 Jonathan Monsarrat. Permission given to freely distribute, * edit and use as long as this copyright statement remains intact. * */ #include #include #include #include #include #include "Operator.h" #include "Global.h" #include "Counter.h" #include "Document.h" #include "Font.h" #include "Justify.h" Operator::Operator(char *tokentext, int page_specific, int stealth, int paramtype, int subtype, float value, char *replacestr, void (*handle)(int, int, float, char *)) { _tokentext = tokentext; _page_specific = page_specific; _stealth = stealth; _paramtype = paramtype; _subtype = subtype; _value = value; _replacestr = replacestr; _handle = handle; _valid = TRUE; } Operator::Operator(const int array_ender) { _valid = array_ender; // Invalid operator marks the end of the array. } /* A list of all the token versus their Operators. Some tokens like "\quote" * have more than one Operator because they involve more than one simple * parameter change, like a change to both leftmargin and textwidth. * DO NOT USE M-x sort-lines TO SORT THIS! Some of the operators have multiple * lines, which must be kept preserved in a certain order. */ static Operator operators[] = { Operator("", 0,0,0, 0, 0.0, "", Operator::new_paragraph), // handled Operator("\\#", 1,0,0, 0, 0.0, "#", Operator::replace), // handled Operator("\\$", 1,0,0, 0, 0.0, "$", Operator::replace), // handled Operator("\\%", 1,0,Environment::PFont, Font::FunnyPrint, 0.0, "(%)", Stack::set), // handled Operator("\\&", 1,0,0, 0, 0.0, "&", Operator::replace), // handled Operator("\\Huge", 0,0,Environment::PFont, Font::Huge, 0.0, "", Stack::set), // handled Operator("\\LARGE", 0,0,Environment::PFont, Font::LARGE, 0.0, "", Stack::set), // handled Operator("\\Large", 0,0,Environment::PFont, Font::Large, 0.0, "", Stack::set), // handled Operator("\\STEALTH", 0,0,Environment::PDocument, Document::Stealth, 2.0, "", Stack::set), // handled Operator("\\\\", 1,0,Environment::PDocument, Document::NewLine, 0.0, "", Stack::set), // handled Operator("\\\\*", 1,0,Environment::PDocument, Document::NewLine, 0.0, "", Stack::set), // handled Operator("\\_", 1,0,Environment::PFont, Font::FunnyPrint, 0.0, "(_)", Stack::set), // handled Operator("\\addtolength", 0,0,0, 0, 0.0, "", Operator::addtolength), // handled Operator("\\backslash", 1,0,Environment::PFont, Font::FunnyPrint, 0.0, "(\\\\)", Stack::set), // handled Operator("\\begin", 0,0,0, 0, 0.0, "", Document::begin), // handled Operator("\\bf", 0,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\bigskip", 1,0,0, 0, 0.0, "\\bigskipamount", Operator::do_vspace), Operator("\\center", 0,0,Environment::PJustify, Justify::Center, 0.0, "", Stack::set), // handled Operator("\\chapter", 0,0,0, 0, 0.0, "", Operator::clearpage), // handled Operator("\\chapter", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), // handled Operator("\\chapter", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\chapter", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\chapter", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\chapter", 1,0,Environment::PFont, Font::huge, 0.0, "", Stack::set), // handled Operator("\\chapter", 1,0,Environment::PCounter, Counter::Chapter, 1.0, "", Stack::set), // handled Operator("\\chapter*", 0,0,0, 0, 0.0, "", Operator::clearpage), // handled Operator("\\chapter*", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), // handled Operator("\\chapter*", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\chapter*", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\chapter*", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\chapter*", 1,0,Environment::PFont, Font::huge, 0.0, "", Stack::set), // handled Operator("\\chapter*", 1,0,Environment::PCounter, Counter::Chapter, 0.0, "", Stack::set), // handled Operator("\\clearpage", 0,0,0, 0, 0.0, "", Operator::clearpage), // handled Operator("\\description", 1,0,Environment::PCounter, Counter::Description, 0.0, "", Stack::set), // handled Operator("\\description", 1,0,Environment::PLength, Length::Parameter, 22.5, "\\oddsidemargin", Stack::relative_set), // handled Operator("\\description", 1,0,Environment::PLength, Length::Parameter, -22.5, "\\textwidth", Stack::relative_set), // handled Operator("\\description", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\description", 1,0,Environment::PLength, Length::Parameter, 1.14, "\\baselinestretch", Stack::set), // handled Operator("\\document", 0,0,Environment::PDocument, Document::DocumentStart, 1.0, "", Stack::set), // handled Operator("\\documentstyle", 0,0,0, 0, 0.0, "", Document::documentstyle), // handled Operator("\\em", 0,0,Environment::PFont, Font::Italic, 0.0, "", Stack::set), // handled Operator("\\end", 0,0,0, 0, 0.0, "", Document::end), // handled Operator("\\enumerate", 1,0,Environment::PCounter, Counter::Enum, 0.0, "", Stack::set), // handled Operator("\\enumerate", 1,0,Environment::PLength, Length::Parameter, 22.5, "\\oddsidemargin", Stack::relative_set), // handled Operator("\\enumerate", 1,0,Environment::PLength, Length::Parameter, -22.5, "\\textwidth", Stack::relative_set), // handled Operator("\\enumerate", 1,0,Environment::PLength, Length::Parameter, 1.14, "\\baselinestretch", Stack::set), // handled Operator("\\enumerate", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\flushleft", 0,0,Environment::PJustify, Justify::FlushLeft, 0.0, "", Stack::set), // handled Operator("\\flushright", 0,0,Environment::PJustify, Justify::FlushRight, 0.0, "", Stack::set), // handled Operator("\\footnotesize", 0,0,Environment::PFont, Font::Footnotesize, 0.0, "", Stack::set), // handled Operator("\\hspace", 1,0,0, 0, 0.0, "", Operator::hspace), // handled Operator("\\hspace*", 1,0,0, 0, 0.0, "", Operator::hspace), // handled Operator("\\huge", 0,0,Environment::PFont, Font::huge, 0.0, "", Stack::set), // handled Operator("\\hyphenation", 0,0,0, 0, 0.0, "", Operator::skip), // skipped Operator("\\ignore", 1,1,Environment::PDocument, Document::Ignore, 1.0, "", Stack::set), // handled Operator("\\include", 0,0,0, 0, 0.0, "", Operator::include_file), // handled Operator("\\includeps", 0,1,0, 0, 0.0, "", Operator::includeps), // handled Operator("\\it", 0,0,Environment::PFont, Font::Italic, 0.0, "", Stack::set), // handled Operator("\\item", 1,0,Environment::PCounter, Counter::Item, 0.0, "", Stack::set), // handled Operator("\\itemize", 1,0,Environment::PCounter, Counter::Itemize, 0.0, "", Stack::set), // handled Operator("\\itemize", 1,0,Environment::PLength, Length::Parameter, 22.5, "\\oddsidemargin", Stack::relative_set), // handled Operator("\\itemize", 1,0,Environment::PLength, Length::Parameter, -22.5, "\\textwidth", Stack::relative_set), // handled Operator("\\itemize", 1,0,Environment::PLength, Length::Parameter, 1.0, "\\baselinestretch", Stack::set), // handled Operator("\\itemize", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\label", 1,0,0, 0, 0.0, "", Operator::label), // handled Operator("\\large", 0,0,Environment::PFont, Font::large, 0.0, "", Stack::set), // handled Operator("\\ldots", 1,0,0, 0, 0.0, "...", Operator::replace), // handled Operator("\\medskip", 1,0,0, 0, 0.0, "\\medskipamount", Operator::do_vspace), Operator("\\newlength", 0,0,0, 0, 0.0, "", Operator::newlength), // handled Operator("\\newline", 1,0,Environment::PDocument, Document::NewLine, 0.0, "", Stack::set), // handled Operator("\\normalsize", 0,0,Environment::PFont, Font::Normalsize, 0.0, "", Stack::set), // handled Operator("\\par", 1,0,Environment::PDocument, Document::NewLine, 0.0, "", Stack::set), // handled Operator("\\paragraph", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), Operator("\\paragraph", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\paragraph", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\paragraph", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\paragraph", 1,0,Environment::PFont, Font::Normalsize, 0.0, "", Stack::set), // handled Operator("\\paragraph", 1,0,Environment::PCounter, Counter::Paragraph, 1.0, "", Stack::set), // handled Operator("\\paragraph*", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), Operator("\\paragraph*", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\paragraph*", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\paragraph*", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\paragraph*", 1,0,Environment::PFont, Font::Normalsize, 0.0, "", Stack::set), // handled Operator("\\paragraph*", 1,0,Environment::PCounter, Counter::Paragraph, 0.0, "", Stack::set), // handled Operator("\\part", 0,0,0, 0, 0.0, "", Operator::clearpage), Operator("\\part", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), Operator("\\part", 1,0,0, 0, 0.0, "", Stack::push), Operator("\\part", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), Operator("\\part", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), Operator("\\part", 1,0,Environment::PFont, Font::Huge, 0.0, "", Stack::set), Operator("\\part", 1,0,Environment::PCounter, Counter::Part, 1.0, "", Stack::set), Operator("\\part*", 0,0,0, 0, 0.0, "", Operator::clearpage), Operator("\\part*", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), Operator("\\part*", 1,0,0, 0, 0.0, "", Stack::push), Operator("\\part*", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), Operator("\\part*", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), Operator("\\part*", 1,0,Environment::PFont, Font::Huge, 0.0, "", Stack::set), Operator("\\part*", 1,0,Environment::PCounter, Counter::Part, 0.0, "", Stack::set), Operator("\\postscript", 1,1,Environment::PDocument, Document::PostScript, 1.0, "", Stack::set), // handled Operator("\\pscmd", 0,1,0, 0, 0.0, "", Operator::pscmd), // handled Operator("\\pspage", 0,1,0, 0, 0.0, "", Operator::pspage), // handled Operator("\\quotation", 1,0,Environment::PDocument, Document::NewLine, 0.0, "", Stack::set), // handled Operator("\\quotation", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\quotation", 1,0,Environment::PLength, Length::Parameter, 1.0, "\\baselinestretch", Stack::set), // handled Operator("\\quotation", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parskip", Stack::set), // handled Operator("\\quotation", 1,0,Environment::PLength, Length::Parameter, 72.0, "\\oddsidemargin", Stack::relative_set), // handled Operator("\\quotation", 1,0,Environment::PLength, Length::Parameter, -72.0, "\\textwidth", Stack::relative_set), // handled Operator("\\quote", 1,0,Environment::PDocument, Document::NewLine, 0.0, "", Stack::set), // handled Operator("\\quote", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\quote", 1,0,Environment::PLength, Length::Parameter, 1.0, "\\baselinestretch", Stack::set), // handled Operator("\\quote", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parskip", Stack::set), // handled Operator("\\quote", 1,0,Environment::PLength, Length::Parameter, 72.0, "\\oddsidemargin", Stack::relative_set), // handled Operator("\\quote", 1,0,Environment::PLength, Length::Parameter, -72.0, "\\textwidth", Stack::relative_set), // handled Operator("\\raggedleft", 0,0,Environment::PJustify, Justify::FlushRight, 0.0, "", Stack::set), // handled Operator("\\raggedright", 0,0,Environment::PJustify, Justify::FlushLeft, 0.0, "", Stack::set), // handled Operator("\\ref", 1,0,0, 0, 0.0, "", Operator::ref), // handled Operator("\\rm", 0,0,Environment::PFont, Font::Roman, 0.0, "", Stack::set), // handled Operator("\\sc", 0,0,Environment::PFont, Font::SmallCaps, 0.0, "", Stack::set), // handled Operator("\\scriptsize", 0,0,Environment::PFont, Font::Scriptsize, 0.0, "", Stack::set), // handled Operator("\\section", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), // handled Operator("\\section", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\section", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\section", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\section", 1,0,Environment::PFont, Font::Large, 0.0, "", Stack::set), // handled Operator("\\section", 1,0,Environment::PCounter, Counter::Section, 1.0, "", Stack::set), // handled Operator("\\section*", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), // handled Operator("\\section*", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\section*", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\section*", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\section*", 1,0,Environment::PFont, Font::Large, 0.0, "", Stack::set), // handled Operator("\\section*", 1,0,Environment::PCounter, Counter::Section, 0.0, "", Stack::set), // handled Operator("\\setlength", 0,0,0, 0, 0.0, "", Operator::setlength), // handled Operator("\\sf", 0,0,Environment::PFont, Font::SansSerif, 0.0, "", Stack::set), // handled Operator("\\sl", 0,0,Environment::PFont, Font::Slant, 0.0, "", Stack::set), // handled Operator("\\small", 0,0,Environment::PFont, Font::Small, 0.0, "", Stack::set), // handled Operator("\\smallskip", 1,0,0, 0, 0.0, "\\smallskipamount", Operator::do_vspace), Operator("\\stealth", 0,0,Environment::PDocument, Document::Stealth, 1.0, "", Stack::set), // handled Operator("\\subparagraph", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), // handled Operator("\\subparagraph", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\subparagraph", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\subparagraph", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\subparagraph", 1,0,Environment::PFont, Font::Normalsize, 0.0, "", Stack::set), // handled Operator("\\subparagraph", 1,0,Environment::PCounter, Counter::Subparagraph, 1.0, "", Stack::set), // handled Operator("\\subparagraph*", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), // handled Operator("\\subparagraph*", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\subparagraph*", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\subparagraph*", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\subparagraph*", 1,0,Environment::PFont, Font::Normalsize, 0.0, "", Stack::set), // handled Operator("\\subparagraph*", 1,0,Environment::PCounter, Counter::Subparagraph, 0.0, "", Stack::set), // handled Operator("\\subsection", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), // handled Operator("\\subsection", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\subsection", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\subsection", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\subsection", 1,0,Environment::PFont, Font::large, 0.0, "", Stack::set), // handled Operator("\\subsection", 1,0,Environment::PCounter, Counter::Subsection, 1.0, "", Stack::set), // handled Operator("\\subsection*", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), // handled Operator("\\subsection*", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\subsection*", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\subsection*", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\subsection*", 1,0,Environment::PFont, Font::large, 0.0, "", Stack::set), // handled Operator("\\subsection*", 1,0,Environment::PCounter, Counter::Subsection, 0.0, "", Stack::set), // handled Operator("\\subsubsection", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), // handled Operator("\\subsubsection", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\subsubsection", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\subsubsection", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\subsubsection", 1,0,Environment::PFont, Font::Normalsize, 0.0, "", Stack::set), // handled Operator("\\subsubsection", 1,0,Environment::PCounter, Counter::Subsubsection, 1.0, "", Stack::set), // handled Operator("\\subsubsection*", 1,0,Environment::PDocument, Document::JustDidSection, 1.0, "", Stack::set), // handled Operator("\\subsubsection*", 1,0,0, 0, 0.0, "", Stack::push), // handled Operator("\\subsubsection*", 1,0,Environment::PLength, Length::Parameter, 0.0, "\\parindent", Stack::set), // handled Operator("\\subsubsection*", 1,0,Environment::PFont, Font::Bold, 0.0, "", Stack::set), // handled Operator("\\subsubsection*", 1,0,Environment::PFont, Font::Normalsize, 0.0, "", Stack::set), // handled Operator("\\subsubsection*", 1,0,Environment::PCounter, Counter::Subsubsection, 0.0, "", Stack::set), // handled Operator("\\tiny", 0,0,Environment::PFont, Font::Tiny, 0.0, "", Stack::set), // handled Operator("\\today", 1,0,0, 0, 0.0, "", Operator::today), // handled Operator("\\tt", 0,0,Environment::PFont, Font::Typewriter, 0.0, "", Stack::set), // handled Operator("\\verse", 1,0,Environment::PDocument, Document::NewLine, 0.0, "", Stack::set), // handled Operator("\\verse", 1,0,Environment::PLength, Length::Parameter, 45.0, "\\oddsidemargin", Stack::relative_set), // handled Operator("\\verse", 1,0,Environment::PLength, Length::Parameter, -22.5, "\\parindent", Stack::set), // handled Operator("\\verse", 1,0,Environment::PLength, Length::Parameter, 1.0, "\\baselinestretch", Stack::set), // handled Operator("\\verse", 1,0,Environment::PLength, Length::Parameter, 11.0, "\\parskip", Stack::set), // handled Operator("\\vspace", 1,0,0, 0, 0.0, "", Operator::vspace), // handled Operator("\\vspace*", 1,0,0, 0, 0.0, "", Operator::vspace), // handled Operator("\\{", 1,0,Environment::PFont, Font::FunnyPrint, 0.0, "({)", Stack::set), // handled Operator("\\}", 1,0,Environment::PFont, Font::FunnyPrint, 0.0, "(})", Stack::set), // handled Operator("{", 0,0,0, 0, 0.0, "", Stack::push), // handled Operator("}", 0,0,0, Document::CloseBrace, 0.0, "", Stack::pop), // handled 0 }; static int operator_size = 0; // Size of the operators array int Operator::compare(const void *op1, const void *op2) { Operator *oper1; Operator *oper2; oper1 = (Operator *) op1; oper2 = (Operator *) op2; return strcmp(oper1->_tokentext, oper2->_tokentext); } /* Do a binary search through the alphabetically sorted array of operators * for the first operator (there may be many) that matches this token name * Return a pointer to the first operator, or NULL if no match found. */ Operator* Operator::get_operator(char *tokenstr) { if(!operator_size) // Has the operator_size variable been initialized? while(operators[operator_size++].isvalid()) ; Operator key(tokenstr, 0, 0, 0, 0, 0.0, "", NULL); Operator *op = (Operator *) bsearch((char *)&key, (char *) operators, operator_size, sizeof(Operator), Operator::compare); if(op != NULL && !op->match("")) { // Found a non-null match? while((--op)->match(tokenstr)) // Backpeddle until first match found. ; op++; } return op; } /* Execute the given operator, which is a pointer into the array of operators * "operators". Since there could be more than one operator for a token name, * the pointer is incremented and executed until the token name doesn't match. */ void Operator::execute() { // Skip the operation if we're in a comment, unless this is a // stealth environment or the command is "\stealth" or "\begin". if(Stack::get(Environment::PDocument, Document::Comment, "")) { // Comment? if(!match("\\stealth") && !match("\\STEALTH") && !match("\\begin") && !Stack::get(Environment::PDocument, Document::Stealth, "")) return; } else // Don't put stealth comments outside of a comment line, if(is_stealth()) // because then normal LaTeX cannot process this file. Global::files->fatal_error( "Cannot execute stealth command outside of stealth environment in comment line."); // We are prepared to handle the Operator. But first, check to see if the // page description needs to be defined or if the current page needs to be // started with StartPage if(_page_specific) Global::files->force_start_page(); _handle(_paramtype, _subtype, _value, _replacestr); // Execute the operator } /* Returns true if the given token string matches the Operator's token string */ int Operator::match(char *tokenstr) { return !strcmp(_tokentext,tokenstr); } void Operator::addtolength(int paramtype, int subtype, float value, char *replacestr) { Length *length; length = Global::stack->get_length(); length->addtolength(paramtype, subtype, value, replacestr); } void Operator::clearpage(int, int, float, char *) { if(Stack::get(Environment::PDocument, Document::StartPage, "")) { Global::files->outfile << endl; Global::files->outfile << "ENDPAGE" << endl; // We don't start a new page unless we have to! This is just a marker // that a new page has not been started. Stack::set(Environment::PDocument, Document::StartPage, 0.0, ""); } } void Operator::document(int, int, float, char *) { Global::files->outfile << "in document()" << endl; } void Operator::do_vspace(int, int, float height, char *length_param) { if(length_param[0]) height = Global::stack->get(Environment::PLength, Length::Parameter, length_param); // Suppress any new paragraphs before text Global::files->blankline_area = 1; Global::files->newline_in_this_blankline_area = 1; Global::files->vspace_in_this_blankline_area += height; Global::files->got_whitespace(); } void Operator::hspace(int, int, float, char *) { Token openbrace; if(!openbrace.match("{")) Global::files->fatal_error("Expecting '{' after \\vspace"); float width = Stack::get(Environment::PLength, Length::Parse_Length, ""); Global::files->outfile << endl; Global::files->outfile << width << " HSpace" << endl; } /* Handle the LaTeX command \include, which includes a file at the current * place in the filestream. */ void Operator::include_file(int, int, float, char *) { Token openbrace; if(!openbrace.match("{")) Global::files->fatal_error("Expecting '{' after \\include statement"); Token filename; if(filename.match("}")) Global::files->warning( "Expecting filename before closing '}' in \\include"); Token closebrace; if(!closebrace.match("}")) Global::files->fatal_error( "More than one word before closing '}' in \\include"); Global::files->include_file(filename.get_text()); } /* Handle the LameTeX stealth command \includeps, which includes a * postscript file at the current place in the filestream. */ void Operator::includeps(int, int, float, char *) { Token openbrace; if(!openbrace.match("{")) Global::files->fatal_error("Expecting '{' after \\includeps statement"); Token filename; if(filename.match("}")) Global::files->warning( "Expecting filename before closing '}' in \\includeps"); Token closebrace; if(!closebrace.match("}")) Global::files->fatal_error( "More than one word before closing '}' in \\includeps"); Global::files->include_file_ps(filename.get_text(), FALSE); } void Operator::label(int, int, float, char *) { Token openbrace; if(!openbrace.match("{")) Global::files->fatal_error("Expecting '{' after \\label statement"); Token labelname; if(labelname.match("}")) Global::files->warning( "Expecting label name before closing '}' in \\label"); Token closebrace; if(!closebrace.match("}")) Global::files->fatal_error( "More than token before closing '}' in \\label. Sorry, you must rename your label."); Global::labels->add_label(labelname.get_text()); } void Operator::newlength(int paramtype, int subtype, float value, char *replacestr) { Length *length; length = Global::stack->get_length(); length->newlength(paramtype, subtype, value, replacestr); } void Operator::new_paragraph(int, int, float, char *) { if(Global::files->blankline_area) return; // Suppress more new paragraphs. Global::files->newline_in_this_blankline_area = 1; } /* LaTeX Fonts are bulky, and in LameTeX (just like LaTeX) the fonts * are included one character at a time, not one fontfamily at a time. * A fontfamily is much too large to load in if we're only going to * use a couple of characters from the font type. * * So, whenever we send to PostScript a character meant to be part of a string * we should register that the font description for this character in the * current font type should be included. * * This routine performs this registration. Also it adds the syntax * necessary for PostScript to print this string, returning it in textout. */ void Operator::registrar(char *textin, char *textout) { Stack::set(Environment::PFont, Font::Used, 0.0, textin); textout[0]='('; for(int in=0,out=1; textin[in]; in++,out++) { switch(textin[in]) { case '\n': textout[out++]='\\'; textout[out]='n'; break; case '\t': textout[out++]='\\'; textout[out]='t'; break; case '\r': textout[out++]='\\'; textout[out]='r'; break; case '`': if(textin[in+1]=='`') { in++; textout[out++]='\\'; textout[out]='\\'; } else textout[out]='`'; break; case '\'': if(textin[in+1]=='\'') { in++; textout[out]='\"'; } else textout[out]='\''; break; case '\\': case ')': case '(': textout[out++]='\\'; default: textout[out]=textin[in]; } } textout[out++]=')'; textout[out]='\0'; } /* If we are inside the middle of the document, then print this plaintext * normally. */ void Operator::plaintext(char *text) { // Plaintext is not valid in a comment that's not in a stealth environment. if(Stack::get(Environment::PDocument, Document::Comment, "") && !Stack::get(Environment::PDocument, Document::Stealth, "")) return; if(!Stack::get(Environment::PDocument,Document::DocumentStart,"")) { Global::files->warning("Missing \\begin{document}."); return; } Global::files->force_start_page(); // Start a new page if not started. // This is NOT just after a new section. Global::stack->set(Environment::PDocument, Document::JustDidSection, 0.0, ""); if(Global::files->readjust_vspace > 0.0) { Global::files->outfile << endl << Global::files->readjust_vspace << " woids 1 gt { 0 exch READJUST } { pop } ifelse" << endl; Global::files->readjust_vspace = 0.0; } // Must process for special characters! char output[MAXSTRING]; Operator::registrar(text, output); Global::files->outfile << " " << output << " NW"; } /* Shleps a PostScript operator into the word list */ void Operator::pscmd(int, int, float, char *) { char commandline[MAXSTRING+5]; char buildline[MAXSTRING]; Token openbrace; if(!openbrace.match("{")) Global::files->fatal_error("Expecting '{' after \\pscmd statement"); strcpy(buildline,""); int x=0; for(Token command; !command.match("}"); command = Token()) { if(x++>0) strcat(buildline, " "); strcat(buildline, command.get_text()); } if(x>1 || buildline[0]!='/') sprintf(commandline,"{ %s }", buildline); else strcpy(commandline, buildline); Stack::set(Environment::PFont, Font::Currentused, 0.0, commandline); } /* Gives the postscript file describing parameters for the next page */ void Operator::pspage(int, int, float, char *) { Token openbrace; if(!openbrace.match("{")) Global::files->fatal_error("Expecting '{' after \\pspage statement"); Token filename; if(filename.match("}")) Global::files->warning( "Expecting filename before closing '}' in \\pspage"); Token closebrace; if(!closebrace.match("}")) Global::files->fatal_error( "More than one word before closing '}' in \\pspage"); // Use the new pspage. Global::files->use_pspage(filename.get_text()); } void Operator::ref(int, int, float, char *) { Token openbrace; if(!openbrace.match("{")) Global::files->fatal_error("Expecting '{' after \\ref statement"); Token labelname; if(labelname.match("}")) Global::files->warning( "Expecting label name before closing '}' in \\ref"); Token closebrace; if(!closebrace.match("}")) Global::files->fatal_error( "More than token before closing '}' in \\ref. Sorry, you must rename your label."); Global::labels->print_ref(labelname.get_text()); } void Operator::replace(int, int, float, char *replacestr) { if(replacestr[0]) // A null string means there is no replacement plaintext(replacestr); } void Operator::setlength(int paramtype, int subtype, float value, char *replacestr) { Length *length; length = Global::stack->get_length(); length->setlength(paramtype, subtype, value, replacestr); } // Skip the contents of the next brace set void Operator::skip(int paramtype, int subtype, float value, char *replacestr) { Token openbrace; if(!openbrace.match("{")) Global::files->fatal_error("Missing {"); Token token; while(!token.match("}")) { token = Token(); if(token.match("\\end")) Operator::skip(paramtype, subtype, value, replacestr); } } void Operator::today(int, int, float, char*) { char buffer[20]; time_t clock; time(&clock); struct tm *tm = localtime(&clock); strftime(buffer, 20, "%B", tm); Operator::plaintext(buffer); strftime(buffer, 20, "%d,", tm); if(buffer[0]=='0') Operator::plaintext(&buffer[1]); else Operator::plaintext(buffer); strftime(buffer, 20, "%Y", tm); Operator::plaintext(buffer); } void Operator::vspace(int, int, float, char *) { Token openbrace; if(!openbrace.match("{")) Global::files->fatal_error("Expecting '{' after \\vspace"); float height = Stack::get(Environment::PLength, Length::Parse_Length, ""); Operator::do_vspace(0, 0, height, ""); } int Operator::isvalid() { return _valid; } int Operator::is_stealth() { return _stealth; }