major cleanup and improved block handling
[ctxt.git] / troff.c
blobd2a0eeb75dd8f24e4bdf0c0430cb58eac16bf773
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include "ctxt.h"
6 static int eatspc; /* jump space chars */
7 static int gotnl; /* last output char was a space */
8 static int inblk; /* inside a block */
10 static void troff_doc_beg(struct doc *doc)
14 static void troff_doc_end(struct doc *doc)
18 static void troff_put(struct doc *doc, char *s)
20 if (!*s)
21 return;
22 if (inblk) {
23 doc_write(doc, s);
24 return;
26 if (eatspc) {
27 while (*s == ' ' || *s == '\t' || *s == '\n')
28 s++;
29 if (*s == '.')
30 doc_write(doc, "\\&");
31 eatspc = 0;
33 while (gotnl && *s == '\n')
34 s++;
35 while (*s) {
36 char *r = strchr(s, '\n');
37 r = r ? r + 1 : strchr(s, '\0');
38 doc_memcat(doc, s, r - s);
39 s = r;
40 while (*s == '\n')
41 s++;
43 gotnl = s[-1] == '\n';
46 static void troff_head_beg(struct doc *doc, int level)
48 switch (level) {
49 case 0:
50 troff_put(doc, ".NH 1\n");
51 break;
52 case 1:
53 troff_put(doc, ".NH 2\n");
54 break;
55 default:
56 troff_put(doc, ".SH\n");
60 static void troff_head_end(struct doc *doc, int level)
64 static void troff_par_beg(struct doc *doc)
66 troff_put(doc, ".PP\n");
69 static void troff_par_end(struct doc *doc)
73 static int ldepth;
75 static void troff_list_beg(struct doc *doc)
77 troff_put(doc, "\n.br\n");
78 if (!ldepth)
79 troff_put(doc, ".sp 1\n");
80 eatspc = 1;
81 ldepth++;
82 if (ldepth > 1)
83 doc_write(doc, ".RS\n");
86 static void troff_list_end(struct doc *doc)
88 if (ldepth > 1)
89 doc_write(doc, ".RE\n");
90 ldepth--;
93 static void troff_item_beg(struct doc *doc)
95 doc_write(doc, ".IP \\(bu 2\n");
96 eatspc = 1;
99 static void troff_item_end(struct doc *doc)
103 static void troff_block_beg(struct doc *doc, char *beg)
105 inblk = 1;
106 troff_put(doc, beg ? beg : ".DS");
107 troff_put(doc, "\n");
110 static void troff_block_end(struct doc *doc, char *end)
112 troff_put(doc, end ? end : ".DE");
113 troff_put(doc, "\n");
114 inblk = 0;
117 static void troff_put_txt(struct doc *doc, char *s, char *m)
119 char b[1024];
120 switch(m[0]) {
121 case '*':
122 troff_put(doc, "\\f3");
123 troff_put(doc, s);
124 troff_put(doc, "\\fP");
125 break;
126 case '/':
127 troff_put(doc, "\\f2");
128 troff_put(doc, s);
129 troff_put(doc, "\\fP");
130 break;
131 case '%':
132 troff_put(doc, s);
133 break;
134 case '|':
135 troff_put(doc, "\n.[[\n");
136 troff_put(doc, s);
137 troff_put(doc, "\n.]]\n");
138 eatspc = 1;
139 break;
140 case '[':
141 troff_put(doc, "\n.FS\n");
142 troff_put(doc, s);
143 troff_put(doc, "\n.FE\n");
144 eatspc = 1;
145 break;
146 default:
147 sprintf(b, "%c%s%c", m[0], s, m[1]);
148 troff_put(doc, b);
152 static void troff_table_beg(struct doc *doc, int columns)
154 int i;
155 troff_put(doc, ".TS\n");
156 if (columns) {
157 troff_put(doc, "allbox;\n");
158 for (i = 0; i < columns; i++)
159 troff_put(doc, "c ");
160 troff_put(doc, ".\n");
164 static void troff_table_end(struct doc *doc)
166 troff_put(doc, ".TE\n");
169 /* a hack to identify the first entry in each row */
170 static int entcol;
172 static void troff_row_beg(struct doc *doc)
174 entcol = 0;
177 static void troff_row_end(struct doc *doc)
179 troff_put(doc, "\n");
182 static void troff_entry_beg(struct doc *doc)
184 if (entcol++)
185 troff_put(doc, "\t");
186 troff_put(doc, "T{\n");
189 static void troff_entry_end(struct doc *doc)
191 troff_put(doc, "\nT}");
194 struct fmt_ops troff_ops = {
195 .doc_beg = troff_doc_beg,
196 .doc_end = troff_doc_end,
197 .head_beg = troff_head_beg,
198 .head_end = troff_head_end,
199 .par_beg = troff_par_beg,
200 .par_end = troff_par_end,
201 .list_beg = troff_list_beg,
202 .list_end = troff_list_end,
203 .item_beg = troff_item_beg,
204 .item_end = troff_item_end,
205 .table_beg = troff_table_beg,
206 .table_end = troff_table_end,
207 .row_beg = troff_row_beg,
208 .row_end = troff_row_end,
209 .entry_beg = troff_entry_beg,
210 .entry_end = troff_entry_end,
211 .block_beg = troff_block_beg,
212 .block_end = troff_block_end,
213 .put = troff_put,
214 .put_txt = troff_put_txt