summaryrefslogtreecommitdiff
path: root/support/lametex/src/Label.C
blob: 86be6230dddf6430181885cf393420c9c9fca4f3 (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
/* Label.C
 *
 * Stores user-defined labels for backwards and forwards referencing with
 * the \ref and \pageref commands.
 *
 * Copyright 1992 Jonathan Monsarrat. Permission given to freely distribute,
 * edit and use as long as this copyright statement remains intact.
 *
 */

#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "Global.h"
#include "Counter.h"
#include "Operator.h"

Label::Label(char *name, int chapter, int section)
{
     _name = strdup(name);
     _chapter = chapter;
     _section = section;
     _referenced = 0;
}

Label::~Label()
{
     delete _name;
}

Label::match(char *name)
{
     return !strcmp(name, _name);
}

Labels::Labels()
{
     numlabels = 0;
     unknown_references = 0;
}

Labels::~Labels()
{
     for(int x=0; x < numlabels; x++)
	  delete label[x];
}

void Labels::add_label(char *labelname)
{
     if(numlabels > MAXLABELS - 2)
	  Global::files->fatal_error("Too many labels defined");
     for(int x=0; x < numlabels; x++)
	  if(label[x]->match(labelname)) {
	       char message[50];
	       sprintf(message, "Same label name %s defined twice", labelname);
	       Global::files->fatal_error(message);
	  }

     label[numlabels++] =
	  new Label(labelname,
		    (int)Stack::get(Environment::PCounter,
				    Counter::Chapter, ""),
		    (int)Stack::get(Environment::PCounter,
				    Counter::Section, ""));
}


/* Print a reference to a given labelname done from the \ref command.
 * Must handle forward referencing as a special case.
 */
void Labels::print_ref(char *labelname)
{
     for(int x=0; x < numlabels; x++)
	  if(label[x]->match(labelname)) {
	       char printout[MAXSTRING];
	       sprintf(printout,"%d.%d",label[x]->_chapter,label[x]->_section);
	       Operator::plaintext(printout);
	       label[x]->_referenced = 1;
	       return;
	  }

     /* Label is undefined. We assume it is a forward referencing problem */
     unknown_references = 1;
     Global::files->outfile << endl << "LAMETEXLABELREF" << labelname << endl;
}

/* Shutdown the program by going through the file and changing all the
 * undone label references to the correct information.
 */
void Labels::shutdown()
{
     ifstream outfile;
     ofstream tempfile;
     char buffer[MAXSTRING];
     char *p;
     char *labelname;

     if(!unknown_references)
	  return;
     cerr << "Handling forward references..." << endl;
     outfile.open(Global::files->outfilename);
     tempfile.open("lametex.temp");
     outfile.getline(buffer, MAXSTRING, '\n');
     while(!outfile.eof() && !outfile.fail()) {
	  if((p = strstr(buffer, "LAMETEXLABELREF"))!=NULL) {
	       labelname = (char *)(p + 15);
	       for(int x=0; x < numlabels; x++)
		    if(label[x]->match(labelname)) {
			 tempfile << "(" << label[x]->_chapter
				 << "." << label[x]->_section
				 << ") NW" << endl;
			 label[x]->_referenced = 1;
			 break;
		    }
	       if(x >= numlabels) {
		    cerr << "No match found for label " << labelname << endl;
		    exit(-1);
	       }
          } else {
               tempfile << buffer << endl;
          }
	  outfile.getline(buffer, MAXSTRING, '\n');
     }

     outfile.close();
     tempfile.close();
     sprintf(buffer, "mv lametex.temp %s", Global::files->outfilename);
     system(buffer);
}