-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTeXout.cc
114 lines (98 loc) · 2.62 KB
/
TeXout.cc
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
#include "TeXout.h"
#include <cmath> // lround
#include <ostream>
#include <string>
#include <boost/dynamic_bitset.hpp>
using std::to_string;
void TeXout::documentclass(std::string docuclass) {
// Potentially validate against approved document classes
doc_class = docuclass;
}
void TeXout::classopt(std::string opt) {
classopts.insert(opt);
}
void TeXout::usepackage(std::string package) {
// potentially worry about package ordering and dependencies
packages.insert(package);
}
void TeXout::usetikzlibrary(std::string lib) {
tikzlibraries.insert(lib);
}
void TeXout::addtopreamble(std::string pre) {
preamble += pre;
}
TeXout& TeXout::operator<<(std::string s) {
doc += s;
return *this;
}
TeXout& TeXout::operator<<(char c) {
doc += c;
return *this;
}
TeXout& TeXout::operator<<(double d) {
long i = std::lround(d*10);
if (i < 0) {
doc += '-';
i *= -1;
}
doc += to_string(i/10) + '.' + to_string(i%10);
// do fixed, setprecision(1) without stringstreams
return *this;
}
TeXout& TeXout::operator<<(int i) {
doc += to_string(i);
return *this;
}
TeXout& TeXout::operator<<(unsigned u) {
doc += to_string(u);
return *this;
}
TeXout& TeXout::operator<<(long unsigned u) {
doc += to_string(u);
return *this;
}
TeXout& TeXout::operator<<(boost::dynamic_bitset<> b) {
char hex[] = "0123456789abcdef";
/* TODO: if b does not fit in ulong */
for (auto v = b.to_ulong(); v; v >>= 4)
doc += hex[v & 15ul]; //wrong-endian
return *this;
}
std::ostream& TeXout::tostream(std::ostream& s) {
if (doc_class == "standalone") {
auto ft = packages.find("tikz");
if (ft != packages.end()) {
packages.erase(ft);
classopts.insert("tikz");
}
}
s << "\\documentclass";
if (!classopts.empty()) {
s << '[';
for (auto sit = classopts.begin();;) {
s << *sit;
if (++sit == classopts.end()) break;
s << ',';
}
s << ']';
}
s << '{' << doc_class << "}\n";
for (auto sit = packages.begin(); sit != packages.end(); ++sit) {
if (doc_class == "amsart" && *sit == "amsmath")
continue;
s << "\\usepackage{" << *sit << "}\n";
}
if (!tikzlibraries.empty()) {
s << "\\usetikzlibrary{";
for (auto sit = tikzlibraries.begin();;) {
s << *sit;
if (++sit == tikzlibraries.end()) break;
s << ',';
}
s << "}\n";
}
return s << preamble
<< "\\begin{document}\n"
<< doc
<< "\\end{document}\n";
}