summaryrefslogtreecommitdiff
path: root/support/lametex/src/Stack.C
blob: ac21d44d7df199d48de1bd5fc88fdc0176db35a2 (plain)
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
/* Stack.C
 *
 * Adjusting the look and feel of the document in a recursive way is done
 * with a stack of Environments, where each environment holds variables such
 * as the current font and margin sizes. This describes the stack.
 *
 * Copyright 1992 Jonathan Monsarrat. Permission given to freely distribute,
 * edit and use as long as this copyright statement remains intact.
 *
 */

#include "Global.h"
#include "Document.h"
#include "Font.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Environment *Stack::environments[MAXNESTING];
int Stack::level;

Stack::Stack()
{
   level=0;
   for(int x=0; x < MAXNESTING; x++)
      environments[x] = NULL;
   environments[0] = new Environment();  // Initialize the root environment
}

void Stack::push(int, int, float, char *)
{
   if(level > MAXNESTING)
      Global::files->fatal_error("Too much nesting");
   
   environments[level+1] = new Environment(environments[level]);
   level++;
}

void Stack::pop(int, int subtype, float, char *)
{
   if(level == 0)
      Global::files->fatal_error("Too many \\end or } tokens");

   Stack::get(Environment::PDocument, subtype, "");

   environments[level-1]->revert(environments[level]);
   delete environments[level];
   level--;
}

/* This functions sets a parameter in the current environment. When the '}'
 * character or the \end command is encountered, the current environment
 * will popped off the stack and this parameter will be reset to its former
 * value (the value previous to the last '{' character or \begin command
 * or the default value)
 */
void Stack::set(int paramtype, int subtype, float value, char *replacestr)
{
   environments[level]->set(paramtype,subtype,value,replacestr);
}

/* This functions sets a parameter in the current environment, relative
 * to its current value.
 */
void Stack::relative_set(int paramtype, int subtype, float value,
			 char *replacestr)
{
   environments[level]->
      set(paramtype, subtype,
	   value + environments[level]->get(paramtype, subtype, replacestr),
	  replacestr);
}



/* This function gets a parameter value from the current environment, 
 * as indexed by the parameter type and subtype.
 */
float Stack::get(int paramtype, int subtype, char *comparestr)
{
   return environments[level]->get(paramtype, subtype, comparestr);
}

void Stack::shutdown()
{
   char commandname[MAXSTRING];
   if(level > 0)
	 Global::files->fatal_error("Missing \\end or }");
   Global::files->outfile << endl;
   Global::files->outfile << "ENDPAGE" << endl;

   Stack::get(Environment::PDocument, Document::ShutDown, "");
   Global::files->outfile.close();
   Global::labels->shutdown();
   char realname[MAXSTRING];

   char srcdir[MAXSTRING];     // Take a trailing / off the source
   strcpy(srcdir,SRCDIR);      // directory pathname, if needed.
   int last = strlen(srcdir) - 1;
   if(srcdir[last]=='/')
      srcdir[last]='\0';
   strcpy(realname, Global::files->outfilename);
   char *p = strchr(realname,'.');
   *p='\0';

   if(Global::files->plain_text_output) {
	sprintf(commandname, "perl %s/plaintext.pl < %s > %s.txt", srcdir,
		Global::files->outfilename, Global::files->outfileroot);
	system(commandname);
	sprintf(commandname, "Output has been placed in %s.txt",
		Global::files->outfileroot);
	cerr << commandname << endl;
        sprintf(commandname,"rm %s", Global::files->outfilename);
	system(commandname);
      return;
   }
   Stack::get(Environment::PFont, Font::ShutDown, "");

   /* A number of files have been created. It's time to merge them
      together into one big file */



   // Concatenate all these library and temporary files into
   // the final rootname.ps file.

   sprintf(commandname,
 "cat %s/latex.header lametex.PS %s/format.ps %s/breakpath.ps %s %s/latex.footer > %s.ps",
	   srcdir, srcdir, srcdir, Global::files->outfilename, srcdir,
	   realname);

   
   system(commandname);   // Execute the concatenate command
   cerr << "Created PostScript file " << realname
	<< ".ps" << endl;

   sprintf(commandname,"rm lametex.PS lametex.aux lametex.log %s", Global::files->outfilename);
   system(commandname);   // Execute the concatenate command
}

Length *Stack::get_length()
{
   return (Length *)environments[level]->get_param(Environment::PLength);
}