troff: escape dots after inline markups
[ctxt.git] / troff.c
blob7f004b1d6dc332ecff7bcf885c3e18d29919cbc8
1 #include <stdlib.h>
2 #include <string.h>
3 #include "ctxt.h"
5 static int eatspc; /* jump space chars */
6 static int gotnl; /* last output char was a space */
7 static int inblk; /* inside a block */
9 static void troff_doc_beg(struct doc *doc)
13 static void troff_doc_end(struct doc *doc)
17 static void troff_put(struct doc *doc, char *s)
19 if (!*s)
20 return;
21 if (inblk) {
22 doc_write(doc, s);
23 return;
25 if (eatspc) {
26 while (*s == ' ' || *s == '\t' || *s == '\n')
27 s++;
28 if (*s == '.')
29 doc_write(doc, "\\&");
30 eatspc = 0;
32 while (gotnl && *s == '\n')
33 s++;
34 while (*s) {
35 char *r = strchr(s, '\n');
36 r = r ? r + 1 : strchr(s, '\0');
37 doc_memcat(doc, s, r - s);
38 s = r;
39 while (*s == '\n')
40 s++;
42 gotnl = s[-1] == '\n';
45 static void troff_head_beg(struct doc *doc, int level)
47 switch (level) {
48 case 0:
49 troff_put(doc, ".NH 1\n");
50 break;
51 case 1:
52 troff_put(doc, ".NH 2\n");
53 break;
54 default:
55 troff_put(doc, ".SH\n");
59 static void troff_head_end(struct doc *doc, int level)
63 static void troff_par_beg(struct doc *doc)
65 troff_put(doc, ".PP\n");
68 static void troff_par_end(struct doc *doc)
72 static void troff_list_beg(struct doc *doc)
74 eatspc = 1;
77 static void troff_list_end(struct doc *doc)
81 static void troff_item_beg(struct doc *doc)
83 troff_put(doc, ".IP \\(bu\n");
84 eatspc = 1;
87 static void troff_item_end(struct doc *doc)
91 static void troff_block_beg(struct doc *doc, char *beg, int block)
93 inblk = 1;
94 troff_put(doc, beg);
95 troff_put(doc, "\n");
98 static void troff_block_end(struct doc *doc, char *end, int block)
100 troff_put(doc, end);
101 troff_put(doc, "\n");
102 inblk = 0;
105 static void troff_put_txt(struct doc *doc, char *s, int marker)
107 switch(marker) {
108 case M_EMPH:
109 troff_put(doc, "\\fB");
110 troff_put(doc, s);
111 troff_put(doc, "\\fP");
112 break;
113 case M_RAW:
114 troff_put(doc, s);
115 break;
116 case M_LINK:
117 troff_put(doc, "\n.[]\n");
118 troff_put(doc, s);
119 troff_put(doc, "\n.][\n");
120 eatspc = 1;
121 break;
122 case M_FOOT:
123 troff_put(doc, "\n.FS\n");
124 troff_put(doc, s);
125 troff_put(doc, "\n.FE\n");
126 eatspc = 1;
127 break;
128 case M_MATH:
129 troff_put(doc, "$");
130 troff_put(doc, s);
131 troff_put(doc, "$");
132 break;
133 default:
134 troff_put(doc, s);
138 static void troff_table_beg(struct doc *doc, int columns)
140 int i;
141 troff_put(doc, ".TS\n");
142 troff_put(doc, "allbox;\n");
143 for (i = 0; i < columns; i++)
144 troff_put(doc, "c ");
145 troff_put(doc, ".\n");
148 static void troff_table_end(struct doc *doc)
150 troff_put(doc, ".TE\n");
153 /* a hack to identify the first entry in each row */
154 static int entcol;
156 static void troff_row_beg(struct doc *doc)
158 entcol = 0;
161 static void troff_row_end(struct doc *doc)
163 troff_put(doc, "\n");
166 static void troff_entry_beg(struct doc *doc)
168 if (entcol++)
169 troff_put(doc, "\t");
170 troff_put(doc, "T{\n");
173 static void troff_entry_end(struct doc *doc)
175 troff_put(doc, "\nT}");
178 struct fmt_ops troff_ops = {
179 .doc_beg = troff_doc_beg,
180 .doc_end = troff_doc_end,
181 .head_beg = troff_head_beg,
182 .head_end = troff_head_end,
183 .par_beg = troff_par_beg,
184 .par_end = troff_par_end,
185 .list_beg = troff_list_beg,
186 .list_end = troff_list_end,
187 .item_beg = troff_item_beg,
188 .item_end = troff_item_end,
189 .table_beg = troff_table_beg,
190 .table_end = troff_table_end,
191 .row_beg = troff_row_beg,
192 .row_end = troff_row_end,
193 .entry_beg = troff_entry_beg,
194 .entry_end = troff_entry_end,
195 .block_beg = troff_block_beg,
196 .block_end = troff_block_end,
197 .put = troff_put,
198 .put_txt = troff_put_txt