1/*	$Id: mdoc.h,v 1.122 2011/03/22 14:05:45 kristaps Exp $ */
2/*
3 * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17#ifndef MDOC_H
18#define MDOC_H
19
20enum	mdoct {
21	MDOC_Ap = 0,
22	MDOC_Dd,
23	MDOC_Dt,
24	MDOC_Os,
25	MDOC_Sh,
26	MDOC_Ss,
27	MDOC_Pp,
28	MDOC_D1,
29	MDOC_Dl,
30	MDOC_Bd,
31	MDOC_Ed,
32	MDOC_Bl,
33	MDOC_El,
34	MDOC_It,
35	MDOC_Ad,
36	MDOC_An,
37	MDOC_Ar,
38	MDOC_Cd,
39	MDOC_Cm,
40	MDOC_Dv,
41	MDOC_Er,
42	MDOC_Ev,
43	MDOC_Ex,
44	MDOC_Fa,
45	MDOC_Fd,
46	MDOC_Fl,
47	MDOC_Fn,
48	MDOC_Ft,
49	MDOC_Ic,
50	MDOC_In,
51	MDOC_Li,
52	MDOC_Nd,
53	MDOC_Nm,
54	MDOC_Op,
55	MDOC_Ot,
56	MDOC_Pa,
57	MDOC_Rv,
58	MDOC_St,
59	MDOC_Va,
60	MDOC_Vt,
61	MDOC_Xr,
62	MDOC__A,
63	MDOC__B,
64	MDOC__D,
65	MDOC__I,
66	MDOC__J,
67	MDOC__N,
68	MDOC__O,
69	MDOC__P,
70	MDOC__R,
71	MDOC__T,
72	MDOC__V,
73	MDOC_Ac,
74	MDOC_Ao,
75	MDOC_Aq,
76	MDOC_At,
77	MDOC_Bc,
78	MDOC_Bf,
79	MDOC_Bo,
80	MDOC_Bq,
81	MDOC_Bsx,
82	MDOC_Bx,
83	MDOC_Db,
84	MDOC_Dc,
85	MDOC_Do,
86	MDOC_Dq,
87	MDOC_Ec,
88	MDOC_Ef,
89	MDOC_Em,
90	MDOC_Eo,
91	MDOC_Fx,
92	MDOC_Ms,
93	MDOC_No,
94	MDOC_Ns,
95	MDOC_Nx,
96	MDOC_Ox,
97	MDOC_Pc,
98	MDOC_Pf,
99	MDOC_Po,
100	MDOC_Pq,
101	MDOC_Qc,
102	MDOC_Ql,
103	MDOC_Qo,
104	MDOC_Qq,
105	MDOC_Re,
106	MDOC_Rs,
107	MDOC_Sc,
108	MDOC_So,
109	MDOC_Sq,
110	MDOC_Sm,
111	MDOC_Sx,
112	MDOC_Sy,
113	MDOC_Tn,
114	MDOC_Ux,
115	MDOC_Xc,
116	MDOC_Xo,
117	MDOC_Fo,
118	MDOC_Fc,
119	MDOC_Oo,
120	MDOC_Oc,
121	MDOC_Bk,
122	MDOC_Ek,
123	MDOC_Bt,
124	MDOC_Hf,
125	MDOC_Fr,
126	MDOC_Ud,
127	MDOC_Lb,
128	MDOC_Lp,
129	MDOC_Lk,
130	MDOC_Mt,
131	MDOC_Brq,
132	MDOC_Bro,
133	MDOC_Brc,
134	MDOC__C,
135	MDOC_Es,
136	MDOC_En,
137	MDOC_Dx,
138	MDOC__Q,
139	MDOC_br,
140	MDOC_sp,
141	MDOC__U,
142	MDOC_Ta,
143	MDOC_MAX
144};
145
146enum	mdocargt {
147	MDOC_Split, /* -split */
148	MDOC_Nosplit, /* -nospli */
149	MDOC_Ragged, /* -ragged */
150	MDOC_Unfilled, /* -unfilled */
151	MDOC_Literal, /* -literal */
152	MDOC_File, /* -file */
153	MDOC_Offset, /* -offset */
154	MDOC_Bullet, /* -bullet */
155	MDOC_Dash, /* -dash */
156	MDOC_Hyphen, /* -hyphen */
157	MDOC_Item, /* -item */
158	MDOC_Enum, /* -enum */
159	MDOC_Tag, /* -tag */
160	MDOC_Diag, /* -diag */
161	MDOC_Hang, /* -hang */
162	MDOC_Ohang, /* -ohang */
163	MDOC_Inset, /* -inset */
164	MDOC_Column, /* -column */
165	MDOC_Width, /* -width */
166	MDOC_Compact, /* -compact */
167	MDOC_Std, /* -std */
168	MDOC_Filled, /* -filled */
169	MDOC_Words, /* -words */
170	MDOC_Emphasis, /* -emphasis */
171	MDOC_Symbolic, /* -symbolic */
172	MDOC_Nested, /* -nested */
173	MDOC_Centred, /* -centered */
174	MDOC_ARG_MAX
175};
176
177enum	mdoc_type {
178	MDOC_TEXT,
179	MDOC_ELEM,
180	MDOC_HEAD,
181	MDOC_TAIL,
182	MDOC_BODY,
183	MDOC_BLOCK,
184	MDOC_TBL,
185	MDOC_EQN,
186	MDOC_ROOT
187};
188
189/*
190 * Section (named/unnamed) of `Sh'.   Note that these appear in the
191 * conventional order imposed by mdoc.7.  In the case of SEC_NONE, no
192 * section has been invoked (this shouldn't happen).  SEC_CUSTOM refers
193 * to other sections.
194 */
195enum	mdoc_sec {
196	SEC_NONE = 0,
197	SEC_NAME, /* NAME */
198	SEC_LIBRARY, /* LIBRARY */
199	SEC_SYNOPSIS, /* SYNOPSIS */
200	SEC_DESCRIPTION, /* DESCRIPTION */
201	SEC_IMPLEMENTATION, /* IMPLEMENTATION NOTES */
202	SEC_RETURN_VALUES, /* RETURN VALUES */
203	SEC_ENVIRONMENT,  /* ENVIRONMENT */
204	SEC_FILES, /* FILES */
205	SEC_EXIT_STATUS, /* EXIT STATUS */
206	SEC_EXAMPLES, /* EXAMPLES */
207	SEC_DIAGNOSTICS, /* DIAGNOSTICS */
208	SEC_COMPATIBILITY, /* COMPATIBILITY */
209	SEC_ERRORS, /* ERRORS */
210	SEC_SEE_ALSO, /* SEE ALSO */
211	SEC_STANDARDS, /* STANDARDS */
212	SEC_HISTORY, /* HISTORY */
213	SEC_AUTHORS, /* AUTHORS */
214	SEC_CAVEATS, /* CAVEATS */
215	SEC_BUGS, /* BUGS */
216	SEC_SECURITY, /* SECURITY */
217	SEC_CUSTOM,
218	SEC__MAX
219};
220
221struct	mdoc_meta {
222	char		 *msec; /* `Dt' section (1, 3p, etc.) */
223	char		 *vol; /* `Dt' volume (implied) */
224	char		 *arch; /* `Dt' arch (i386, etc.) */
225	char		 *date; /* `Dd' normalised date */
226	char		 *title; /* `Dt' title (FOO, etc.) */
227	char		 *os; /* `Os' system (OpenBSD, etc.) */
228	char		 *name; /* leading `Nm' name */
229};
230
231/*
232 * An argument to a macro (multiple values = `-column xxx yyy').
233 */
234struct	mdoc_argv {
235	enum mdocargt  	  arg; /* type of argument */
236	int		  line;
237	int		  pos;
238	size_t		  sz; /* elements in "value" */
239	char		**value; /* argument strings */
240};
241
242/*
243 * Reference-counted macro arguments.  These are refcounted because
244 * blocks have multiple instances of the same arguments spread across
245 * the HEAD, BODY, TAIL, and BLOCK node types.
246 */
247struct 	mdoc_arg {
248	size_t		  argc;
249	struct mdoc_argv *argv;
250	unsigned int	  refcnt;
251};
252
253/*
254 * Indicates that a BODY's formatting has ended, but the scope is still
255 * open.  Used for syntax-broken blocks.
256 */
257enum	mdoc_endbody {
258	ENDBODY_NOT = 0,
259	ENDBODY_SPACE, /* is broken: append a space */
260	ENDBODY_NOSPACE /* is broken: don't append a space */
261};
262
263enum	mdoc_list {
264	LIST__NONE = 0,
265	LIST_bullet, /* -bullet */
266	LIST_column, /* -column */
267	LIST_dash, /* -dash */
268	LIST_diag, /* -diag */
269	LIST_enum, /* -enum */
270	LIST_hang, /* -hang */
271	LIST_hyphen, /* -hyphen */
272	LIST_inset, /* -inset */
273	LIST_item, /* -item */
274	LIST_ohang, /* -ohang */
275	LIST_tag, /* -tag */
276	LIST_MAX
277};
278
279enum	mdoc_disp {
280	DISP__NONE = 0,
281	DISP_centred, /* -centered */
282	DISP_ragged, /* -ragged */
283	DISP_unfilled, /* -unfilled */
284	DISP_filled, /* -filled */
285	DISP_literal /* -literal */
286};
287
288enum	mdoc_auth {
289	AUTH__NONE = 0,
290	AUTH_split, /* -split */
291	AUTH_nosplit /* -nosplit */
292};
293
294enum	mdoc_font {
295	FONT__NONE = 0,
296	FONT_Em, /* Em, -emphasis */
297	FONT_Li, /* Li, -literal */
298	FONT_Sy /* Sy, -symbolic */
299};
300
301struct	mdoc_bd {
302	const char	 *offs; /* -offset */
303	enum mdoc_disp	  type; /* -ragged, etc. */
304	int		  comp; /* -compact */
305};
306
307struct	mdoc_bl {
308	const char	 *width; /* -width */
309	const char	 *offs; /* -offset */
310	enum mdoc_list	  type; /* -tag, -enum, etc. */
311	int		  comp; /* -compact */
312	size_t		  ncols; /* -column arg count */
313	const char	**cols; /* -column val ptr */
314};
315
316struct	mdoc_bf {
317	enum mdoc_font	  font; /* font */
318};
319
320struct	mdoc_an {
321	enum mdoc_auth	  auth; /* -split, etc. */
322};
323
324struct	mdoc_rs {
325	int		  quote_T; /* whether to quote %T */
326};
327
328/*
329 * Consists of normalised node arguments.  These should be used instead
330 * of iterating through the mdoc_arg pointers of a node: defaults are
331 * provided, etc.
332 */
333union	mdoc_data {
334	struct mdoc_an 	  An;
335	struct mdoc_bd	  Bd;
336	struct mdoc_bf	  Bf;
337	struct mdoc_bl	  Bl;
338	struct mdoc_rs	  Rs;
339};
340
341/*
342 * Single node in tree-linked AST.
343 */
344struct	mdoc_node {
345	struct mdoc_node *parent; /* parent AST node */
346	struct mdoc_node *child; /* first child AST node */
347	struct mdoc_node *last; /* last child AST node */
348	struct mdoc_node *next; /* sibling AST node */
349	struct mdoc_node *prev; /* prior sibling AST node */
350	int		  nchild; /* number children */
351	int		  line; /* parse line */
352	int		  pos; /* parse column */
353	enum mdoct	  tok; /* tok or MDOC__MAX if none */
354	int		  flags;
355#define	MDOC_VALID	 (1 << 0) /* has been validated */
356#define	MDOC_EOS	 (1 << 2) /* at sentence boundary */
357#define	MDOC_LINE	 (1 << 3) /* first macro/text on line */
358#define	MDOC_SYNPRETTY	 (1 << 4) /* SYNOPSIS-style formatting */
359#define	MDOC_ENDED	 (1 << 5) /* rendering has been ended */
360#define	MDOC_DELIMO	 (1 << 6)
361#define	MDOC_DELIMC	 (1 << 7)
362	enum mdoc_type	  type; /* AST node type */
363	enum mdoc_sec	  sec; /* current named section */
364	union mdoc_data	 *norm; /* normalised args */
365	/* FIXME: these can be union'd to shave a few bytes. */
366	struct mdoc_arg	 *args; /* BLOCK/ELEM */
367	struct mdoc_node *pending; /* BLOCK */
368	struct mdoc_node *head; /* BLOCK */
369	struct mdoc_node *body; /* BLOCK */
370	struct mdoc_node *tail; /* BLOCK */
371	char		 *string; /* TEXT */
372	const struct tbl_span *span; /* TBL */
373	const struct eqn *eqn; /* EQN */
374	enum mdoc_endbody end; /* BODY */
375};
376
377/* Names of macros.  Index is enum mdoct. */
378extern	const char *const *mdoc_macronames;
379
380/* Names of macro args.  Index is enum mdocargt. */
381extern	const char *const *mdoc_argnames;
382
383__BEGIN_DECLS
384
385struct	mdoc;
386
387const struct mdoc_node *mdoc_node(const struct mdoc *);
388const struct mdoc_meta *mdoc_meta(const struct mdoc *);
389
390__END_DECLS
391
392#endif /*!MDOC_H*/
393