003 File Manager
Current Path:
/usr/src/contrib/mandoc
usr
/
src
/
contrib
/
mandoc
/
📁
..
📄
INSTALL
(6.86 KB)
📄
LICENSE
(2.46 KB)
📄
Makefile
(15.29 KB)
📄
Makefile.depend
(5.65 KB)
📄
NEWS
(60.04 KB)
📄
TODO
(23.98 KB)
📄
apropos.1
(10.66 KB)
📄
arch.c
(1.94 KB)
📄
att.c
(1.62 KB)
📄
catman.8
(4.49 KB)
📄
catman.c
(5.52 KB)
📄
cgi.c
(27.06 KB)
📄
cgi.h.example
(220 B)
📄
chars.c
(13.24 KB)
📄
compat_err.c
(2.68 KB)
📄
compat_fts.c
(17.42 KB)
📄
compat_fts.h
(4.09 KB)
📄
compat_getline.c
(1.59 KB)
📄
compat_getsubopt.c
(2.89 KB)
📄
compat_isblank.c
(986 B)
📄
compat_mkdtemp.c
(1.59 KB)
📄
compat_ohash.c
(6.82 KB)
📄
compat_ohash.h
(2.63 KB)
📄
compat_progname.c
(1.05 KB)
📄
compat_reallocarray.c
(1.49 KB)
📄
compat_recallocarray.c
(2.88 KB)
📄
compat_strcasestr.c
(2.38 KB)
📄
compat_stringlist.c
(2.71 KB)
📄
compat_stringlist.h
(1.73 KB)
📄
compat_strlcat.c
(1.71 KB)
📄
compat_strlcpy.c
(1.59 KB)
📄
compat_strndup.c
(1.3 KB)
📄
compat_strsep.c
(2.55 KB)
📄
compat_strtonum.c
(1.88 KB)
📄
compat_vasprintf.c
(1.55 KB)
📄
config.h
(1.33 KB)
📄
configure
(17.5 KB)
📄
configure.local.example
(11.37 KB)
📄
dba.c
(13.02 KB)
📄
dba.h
(1.73 KB)
📄
dba_array.c
(4.23 KB)
📄
dba_array.h
(2 KB)
📄
dba_read.c
(2.33 KB)
📄
dba_write.c
(2.42 KB)
📄
dba_write.h
(1.23 KB)
📄
dbm.c
(9.28 KB)
📄
dbm.h
(1.94 KB)
📄
dbm_map.c
(4.67 KB)
📄
dbm_map.h
(1.2 KB)
📄
demandoc.1
(2.64 KB)
📄
demandoc.c
(5.21 KB)
📄
eqn.7
(12.07 KB)
📄
eqn.c
(27.21 KB)
📄
eqn.h
(2.19 KB)
📄
eqn_html.c
(5.91 KB)
📄
eqn_parse.h
(1.96 KB)
📄
eqn_term.c
(4.83 KB)
📄
gmdiff
(1.74 KB)
📄
html.c
(19.34 KB)
📄
html.h
(3.86 KB)
📄
lib.c
(1.07 KB)
📄
lib.in
(8.96 KB)
📄
libman.h
(1.66 KB)
📄
libmandoc.h
(3.21 KB)
📄
libmdoc.h
(2.97 KB)
📄
main.c
(28.93 KB)
📄
main.h
(2.06 KB)
📄
makewhatis.8
(4.78 KB)
📄
man-cgi.css
(464 B)
📄
man.1
(9.33 KB)
📄
man.7
(16.8 KB)
📄
man.c
(8.62 KB)
📄
man.cgi.3
(7.83 KB)
📄
man.cgi.8
(11.02 KB)
📄
man.conf.5
(3.92 KB)
📄
man.h
(991 B)
📄
man.options.1
(21.05 KB)
📄
man_html.c
(13.39 KB)
📄
man_macro.c
(11.4 KB)
📄
man_term.c
(25.6 KB)
📄
man_validate.c
(11.84 KB)
📄
manconf.h
(1.56 KB)
📄
mandoc.1
(54.89 KB)
📄
mandoc.3
(12.5 KB)
📄
mandoc.c
(12.41 KB)
📄
mandoc.css
(8.63 KB)
📄
mandoc.db.5
(5.74 KB)
📄
mandoc.h
(14.92 KB)
📄
mandoc_aux.c
(2.42 KB)
📄
mandoc_aux.h
(1.31 KB)
📄
mandoc_char.7
(29.23 KB)
📄
mandoc_escape.3
(9.33 KB)
📄
mandoc_headers.3
(12.41 KB)
📄
mandoc_html.3
(7.42 KB)
📄
mandoc_malloc.3
(4.46 KB)
📄
mandoc_msg.c
(8.92 KB)
📄
mandoc_ohash.c
(1.58 KB)
📄
mandoc_ohash.h
(1004 B)
📄
mandoc_parse.h
(1.82 KB)
📄
mandoc_xr.c
(2.75 KB)
📄
mandoc_xr.h
(1.17 KB)
📄
mandocd.8
(4.59 KB)
📄
mandocd.c
(5.98 KB)
📄
mandocdb.c
(55.16 KB)
📄
manpath.c
(7.73 KB)
📄
manpath.h
(1.22 KB)
📄
mansearch.3
(3.26 KB)
📄
mansearch.c
(18.99 KB)
📄
mansearch.h
(4.03 KB)
📄
mchars_alloc.3
(5.24 KB)
📄
mdoc.7
(73.34 KB)
📄
mdoc.c
(9.99 KB)
📄
mdoc.h
(3.96 KB)
📄
mdoc_argv.c
(16.19 KB)
📄
mdoc_html.c
(36.48 KB)
📄
mdoc_macro.c
(39.55 KB)
📄
mdoc_man.c
(37.07 KB)
📄
mdoc_markdown.c
(33.41 KB)
📄
mdoc_state.c
(5.24 KB)
📄
mdoc_term.c
(43.69 KB)
📄
mdoc_validate.c
(61.85 KB)
📄
msec.c
(1.09 KB)
📄
msec.in
(1.48 KB)
📄
out.c
(13.61 KB)
📄
out.h
(2.26 KB)
📄
preconv.c
(3.84 KB)
📄
predefs.in
(2.05 KB)
📄
read.c
(16.44 KB)
📄
roff.7
(61.96 KB)
📄
roff.c
(98.93 KB)
📄
roff.h
(8.85 KB)
📄
roff_html.c
(2.92 KB)
📄
roff_int.h
(4.08 KB)
📄
roff_term.c
(5.36 KB)
📄
roff_validate.c
(3.41 KB)
📄
soelim.1
(2.6 KB)
📄
soelim.c
(3.76 KB)
📄
st.c
(4.33 KB)
📄
tag.c
(6.65 KB)
📄
tag.h
(1.09 KB)
📄
tbl.3
(6.9 KB)
📄
tbl.7
(10.91 KB)
📄
tbl.c
(3.89 KB)
📄
tbl.h
(4.43 KB)
📄
tbl_data.c
(7.3 KB)
📄
tbl_html.c
(5.74 KB)
📄
tbl_int.h
(2.09 KB)
📄
tbl_layout.c
(8.06 KB)
📄
tbl_opts.c
(3.77 KB)
📄
tbl_parse.h
(1.31 KB)
📄
tbl_term.c
(24.42 KB)
📄
term.c
(24.4 KB)
📄
term.h
(6.14 KB)
📄
term_ascii.c
(9.88 KB)
📄
term_ps.c
(27.41 KB)
📄
term_tab.c
(3 KB)
📄
test-EFTYPE.c
(56 B)
📄
test-O_DIRECTORY.c
(88 B)
📄
test-PATH_MAX.c
(1.02 KB)
📄
test-be32toh.c
(147 B)
📄
test-cmsg.c
(174 B)
📄
test-dirent-namlen.c
(124 B)
📄
test-err.c
(994 B)
📄
test-fgetln.c
(147 B)
📄
test-fts.c
(964 B)
📄
test-getline.c
(186 B)
📄
test-getsubopt.c
(1.31 KB)
📄
test-isblank.c
(96 B)
📄
test-mkdtemp.c
(175 B)
📄
test-nanosleep.c
(239 B)
📄
test-noop.c
(30 B)
📄
test-ntohl.c
(91 B)
📄
test-ohash.c
(585 B)
📄
test-pledge.c
(73 B)
📄
test-progname.c
(118 B)
📄
test-reallocarray.c
(75 B)
📄
test-recallocarray.c
(132 B)
📄
test-recvmsg.c
(100 B)
📄
test-rewb-bsd.c
(618 B)
📄
test-rewb-sysv.c
(610 B)
📄
test-sandbox_init.c
(186 B)
📄
test-strcasestr.c
(131 B)
📄
test-stringlist.c
(1.14 KB)
📄
test-strlcat.c
(166 B)
📄
test-strlcpy.c
(148 B)
📄
test-strndup.c
(141 B)
📄
test-strptime.c
(212 B)
📄
test-strsep.c
(183 B)
📄
test-strtonum.c
(1.25 KB)
📄
test-vasprintf.c
(1.25 KB)
📄
test-wchar.c
(1.58 KB)
📄
tree.c
(8.17 KB)
Editing: mdoc_markdown.c
/* $Id: mdoc_markdown.c,v 1.31 2019/07/01 22:56:24 schwarze Exp $ */ /* * Copyright (c) 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <sys/types.h> #include <assert.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "mandoc_aux.h" #include "mandoc.h" #include "roff.h" #include "mdoc.h" #include "main.h" struct md_act { int (*cond)(struct roff_node *n); int (*pre)(struct roff_node *n); void (*post)(struct roff_node *n); const char *prefix; /* pre-node string constant */ const char *suffix; /* post-node string constant */ }; static void md_nodelist(struct roff_node *); static void md_node(struct roff_node *); static const char *md_stack(char c); static void md_preword(void); static void md_rawword(const char *); static void md_word(const char *); static void md_named(const char *); static void md_char(unsigned char); static void md_uri(const char *); static int md_cond_head(struct roff_node *); static int md_cond_body(struct roff_node *); static int md_pre_abort(struct roff_node *); static int md_pre_raw(struct roff_node *); static int md_pre_word(struct roff_node *); static int md_pre_skip(struct roff_node *); static void md_pre_syn(struct roff_node *); static int md_pre_An(struct roff_node *); static int md_pre_Ap(struct roff_node *); static int md_pre_Bd(struct roff_node *); static int md_pre_Bk(struct roff_node *); static int md_pre_Bl(struct roff_node *); static int md_pre_D1(struct roff_node *); static int md_pre_Dl(struct roff_node *); static int md_pre_En(struct roff_node *); static int md_pre_Eo(struct roff_node *); static int md_pre_Fa(struct roff_node *); static int md_pre_Fd(struct roff_node *); static int md_pre_Fn(struct roff_node *); static int md_pre_Fo(struct roff_node *); static int md_pre_In(struct roff_node *); static int md_pre_It(struct roff_node *); static int md_pre_Lk(struct roff_node *); static int md_pre_Mt(struct roff_node *); static int md_pre_Nd(struct roff_node *); static int md_pre_Nm(struct roff_node *); static int md_pre_No(struct roff_node *); static int md_pre_Ns(struct roff_node *); static int md_pre_Pp(struct roff_node *); static int md_pre_Rs(struct roff_node *); static int md_pre_Sh(struct roff_node *); static int md_pre_Sm(struct roff_node *); static int md_pre_Vt(struct roff_node *); static int md_pre_Xr(struct roff_node *); static int md_pre__T(struct roff_node *); static int md_pre_br(struct roff_node *); static void md_post_raw(struct roff_node *); static void md_post_word(struct roff_node *); static void md_post_pc(struct roff_node *); static void md_post_Bk(struct roff_node *); static void md_post_Bl(struct roff_node *); static void md_post_D1(struct roff_node *); static void md_post_En(struct roff_node *); static void md_post_Eo(struct roff_node *); static void md_post_Fa(struct roff_node *); static void md_post_Fd(struct roff_node *); static void md_post_Fl(struct roff_node *); static void md_post_Fn(struct roff_node *); static void md_post_Fo(struct roff_node *); static void md_post_In(struct roff_node *); static void md_post_It(struct roff_node *); static void md_post_Lb(struct roff_node *); static void md_post_Nm(struct roff_node *); static void md_post_Pf(struct roff_node *); static void md_post_Vt(struct roff_node *); static void md_post__T(struct roff_node *); static const struct md_act md_acts[MDOC_MAX - MDOC_Dd] = { { NULL, NULL, NULL, NULL, NULL }, /* Dd */ { NULL, NULL, NULL, NULL, NULL }, /* Dt */ { NULL, NULL, NULL, NULL, NULL }, /* Os */ { NULL, md_pre_Sh, NULL, NULL, NULL }, /* Sh */ { NULL, md_pre_Sh, NULL, NULL, NULL }, /* Ss */ { NULL, md_pre_Pp, NULL, NULL, NULL }, /* Pp */ { md_cond_body, md_pre_D1, md_post_D1, NULL, NULL }, /* D1 */ { md_cond_body, md_pre_Dl, md_post_D1, NULL, NULL }, /* Dl */ { md_cond_body, md_pre_Bd, md_post_D1, NULL, NULL }, /* Bd */ { NULL, NULL, NULL, NULL, NULL }, /* Ed */ { md_cond_body, md_pre_Bl, md_post_Bl, NULL, NULL }, /* Bl */ { NULL, NULL, NULL, NULL, NULL }, /* El */ { NULL, md_pre_It, md_post_It, NULL, NULL }, /* It */ { NULL, md_pre_raw, md_post_raw, "*", "*" }, /* Ad */ { NULL, md_pre_An, NULL, NULL, NULL }, /* An */ { NULL, md_pre_Ap, NULL, NULL, NULL }, /* Ap */ { NULL, md_pre_raw, md_post_raw, "*", "*" }, /* Ar */ { NULL, md_pre_raw, md_post_raw, "**", "**" }, /* Cd */ { NULL, md_pre_raw, md_post_raw, "**", "**" }, /* Cm */ { NULL, md_pre_raw, md_post_raw, "`", "`" }, /* Dv */ { NULL, md_pre_raw, md_post_raw, "`", "`" }, /* Er */ { NULL, md_pre_raw, md_post_raw, "`", "`" }, /* Ev */ { NULL, NULL, NULL, NULL, NULL }, /* Ex */ { NULL, md_pre_Fa, md_post_Fa, NULL, NULL }, /* Fa */ { NULL, md_pre_Fd, md_post_Fd, "**", "**" }, /* Fd */ { NULL, md_pre_raw, md_post_Fl, "**-", "**" }, /* Fl */ { NULL, md_pre_Fn, md_post_Fn, NULL, NULL }, /* Fn */ { NULL, md_pre_Fd, md_post_raw, "*", "*" }, /* Ft */ { NULL, md_pre_raw, md_post_raw, "**", "**" }, /* Ic */ { NULL, md_pre_In, md_post_In, NULL, NULL }, /* In */ { NULL, md_pre_raw, md_post_raw, "`", "`" }, /* Li */ { md_cond_head, md_pre_Nd, NULL, NULL, NULL }, /* Nd */ { NULL, md_pre_Nm, md_post_Nm, "**", "**" }, /* Nm */ { md_cond_body, md_pre_word, md_post_word, "[", "]" }, /* Op */ { NULL, md_pre_abort, NULL, NULL, NULL }, /* Ot */ { NULL, md_pre_raw, md_post_raw, "*", "*" }, /* Pa */ { NULL, NULL, NULL, NULL, NULL }, /* Rv */ { NULL, NULL, NULL, NULL, NULL }, /* St */ { NULL, md_pre_raw, md_post_raw, "*", "*" }, /* Va */ { NULL, md_pre_Vt, md_post_Vt, "*", "*" }, /* Vt */ { NULL, md_pre_Xr, NULL, NULL, NULL }, /* Xr */ { NULL, NULL, md_post_pc, NULL, NULL }, /* %A */ { NULL, md_pre_raw, md_post_pc, "*", "*" }, /* %B */ { NULL, NULL, md_post_pc, NULL, NULL }, /* %D */ { NULL, md_pre_raw, md_post_pc, "*", "*" }, /* %I */ { NULL, md_pre_raw, md_post_pc, "*", "*" }, /* %J */ { NULL, NULL, md_post_pc, NULL, NULL }, /* %N */ { NULL, NULL, md_post_pc, NULL, NULL }, /* %O */ { NULL, NULL, md_post_pc, NULL, NULL }, /* %P */ { NULL, NULL, md_post_pc, NULL, NULL }, /* %R */ { NULL, md_pre__T, md_post__T, NULL, NULL }, /* %T */ { NULL, NULL, md_post_pc, NULL, NULL }, /* %V */ { NULL, NULL, NULL, NULL, NULL }, /* Ac */ { md_cond_body, md_pre_word, md_post_word, "<", ">" }, /* Ao */ { md_cond_body, md_pre_word, md_post_word, "<", ">" }, /* Aq */ { NULL, NULL, NULL, NULL, NULL }, /* At */ { NULL, NULL, NULL, NULL, NULL }, /* Bc */ { NULL, NULL, NULL, NULL, NULL }, /* Bf XXX not implemented */ { md_cond_body, md_pre_word, md_post_word, "[", "]" }, /* Bo */ { md_cond_body, md_pre_word, md_post_word, "[", "]" }, /* Bq */ { NULL, NULL, NULL, NULL, NULL }, /* Bsx */ { NULL, NULL, NULL, NULL, NULL }, /* Bx */ { NULL, NULL, NULL, NULL, NULL }, /* Db */ { NULL, NULL, NULL, NULL, NULL }, /* Dc */ { md_cond_body, md_pre_word, md_post_word, "\"", "\"" }, /* Do */ { md_cond_body, md_pre_word, md_post_word, "\"", "\"" }, /* Dq */ { NULL, NULL, NULL, NULL, NULL }, /* Ec */ { NULL, NULL, NULL, NULL, NULL }, /* Ef */ { NULL, md_pre_raw, md_post_raw, "*", "*" }, /* Em */ { md_cond_body, md_pre_Eo, md_post_Eo, NULL, NULL }, /* Eo */ { NULL, NULL, NULL, NULL, NULL }, /* Fx */ { NULL, md_pre_raw, md_post_raw, "**", "**" }, /* Ms */ { NULL, md_pre_No, NULL, NULL, NULL }, /* No */ { NULL, md_pre_Ns, NULL, NULL, NULL }, /* Ns */ { NULL, NULL, NULL, NULL, NULL }, /* Nx */ { NULL, NULL, NULL, NULL, NULL }, /* Ox */ { NULL, NULL, NULL, NULL, NULL }, /* Pc */ { NULL, NULL, md_post_Pf, NULL, NULL }, /* Pf */ { md_cond_body, md_pre_word, md_post_word, "(", ")" }, /* Po */ { md_cond_body, md_pre_word, md_post_word, "(", ")" }, /* Pq */ { NULL, NULL, NULL, NULL, NULL }, /* Qc */ { md_cond_body, md_pre_raw, md_post_raw, "'`", "`'" }, /* Ql */ { md_cond_body, md_pre_word, md_post_word, "\"", "\"" }, /* Qo */ { md_cond_body, md_pre_word, md_post_word, "\"", "\"" }, /* Qq */ { NULL, NULL, NULL, NULL, NULL }, /* Re */ { md_cond_body, md_pre_Rs, NULL, NULL, NULL }, /* Rs */ { NULL, NULL, NULL, NULL, NULL }, /* Sc */ { md_cond_body, md_pre_word, md_post_word, "'", "'" }, /* So */ { md_cond_body, md_pre_word, md_post_word, "'", "'" }, /* Sq */ { NULL, md_pre_Sm, NULL, NULL, NULL }, /* Sm */ { NULL, md_pre_raw, md_post_raw, "*", "*" }, /* Sx */ { NULL, md_pre_raw, md_post_raw, "**", "**" }, /* Sy */ { NULL, md_pre_raw, md_post_raw, "`", "`" }, /* Tn */ { NULL, NULL, NULL, NULL, NULL }, /* Ux */ { NULL, NULL, NULL, NULL, NULL }, /* Xc */ { NULL, NULL, NULL, NULL, NULL }, /* Xo */ { NULL, md_pre_Fo, md_post_Fo, "**", "**" }, /* Fo */ { NULL, NULL, NULL, NULL, NULL }, /* Fc */ { md_cond_body, md_pre_word, md_post_word, "[", "]" }, /* Oo */ { NULL, NULL, NULL, NULL, NULL }, /* Oc */ { NULL, md_pre_Bk, md_post_Bk, NULL, NULL }, /* Bk */ { NULL, NULL, NULL, NULL, NULL }, /* Ek */ { NULL, NULL, NULL, NULL, NULL }, /* Bt */ { NULL, NULL, NULL, NULL, NULL }, /* Hf */ { NULL, md_pre_raw, md_post_raw, "*", "*" }, /* Fr */ { NULL, NULL, NULL, NULL, NULL }, /* Ud */ { NULL, NULL, md_post_Lb, NULL, NULL }, /* Lb */ { NULL, md_pre_abort, NULL, NULL, NULL }, /* Lp */ { NULL, md_pre_Lk, NULL, NULL, NULL }, /* Lk */ { NULL, md_pre_Mt, NULL, NULL, NULL }, /* Mt */ { md_cond_body, md_pre_word, md_post_word, "{", "}" }, /* Brq */ { md_cond_body, md_pre_word, md_post_word, "{", "}" }, /* Bro */ { NULL, NULL, NULL, NULL, NULL }, /* Brc */ { NULL, NULL, md_post_pc, NULL, NULL }, /* %C */ { NULL, md_pre_skip, NULL, NULL, NULL }, /* Es */ { md_cond_body, md_pre_En, md_post_En, NULL, NULL }, /* En */ { NULL, NULL, NULL, NULL, NULL }, /* Dx */ { NULL, NULL, md_post_pc, NULL, NULL }, /* %Q */ { NULL, md_pre_Lk, md_post_pc, NULL, NULL }, /* %U */ { NULL, NULL, NULL, NULL, NULL }, /* Ta */ }; static const struct md_act *md_act(enum roff_tok); static int outflags; #define MD_spc (1 << 0) /* Blank character before next word. */ #define MD_spc_force (1 << 1) /* Even before trailing punctuation. */ #define MD_nonl (1 << 2) /* Prevent linebreak in markdown code. */ #define MD_nl (1 << 3) /* Break markdown code line. */ #define MD_br (1 << 4) /* Insert an output line break. */ #define MD_sp (1 << 5) /* Insert a paragraph break. */ #define MD_Sm (1 << 6) /* Horizontal spacing mode. */ #define MD_Bk (1 << 7) /* Word keep mode. */ #define MD_An_split (1 << 8) /* Author mode is "split". */ #define MD_An_nosplit (1 << 9) /* Author mode is "nosplit". */ static int escflags; /* Escape in generated markdown code: */ #define ESC_BOL (1 << 0) /* "#*+-" near the beginning of a line. */ #define ESC_NUM (1 << 1) /* "." after a leading number. */ #define ESC_HYP (1 << 2) /* "(" immediately after "]". */ #define ESC_SQU (1 << 4) /* "]" when "[" is open. */ #define ESC_FON (1 << 5) /* "*" immediately after unrelated "*". */ #define ESC_EOL (1 << 6) /* " " at the and of a line. */ static int code_blocks, quote_blocks, list_blocks; static int outcount; static const struct md_act * md_act(enum roff_tok tok) { assert(tok >= MDOC_Dd && tok <= MDOC_MAX); return md_acts + (tok - MDOC_Dd); } void markdown_mdoc(void *arg, const struct roff_meta *mdoc) { outflags = MD_Sm; md_word(mdoc->title); if (mdoc->msec != NULL) { outflags &= ~MD_spc; md_word("("); md_word(mdoc->msec); md_word(")"); } md_word("-"); md_word(mdoc->vol); if (mdoc->arch != NULL) { md_word("("); md_word(mdoc->arch); md_word(")"); } outflags |= MD_sp; md_nodelist(mdoc->first->child); outflags |= MD_sp; md_word(mdoc->os); md_word("-"); md_word(mdoc->date); putchar('\n'); } static void md_nodelist(struct roff_node *n) { while (n != NULL) { md_node(n); n = n->next; } } static void md_node(struct roff_node *n) { const struct md_act *act; int cond, process_children; if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) return; if (outflags & MD_nonl) outflags &= ~(MD_nl | MD_sp); else if (outflags & MD_spc && n->flags & NODE_LINE) outflags |= MD_nl; act = NULL; cond = 0; process_children = 1; n->flags &= ~NODE_ENDED; if (n->type == ROFFT_TEXT) { if (n->flags & NODE_DELIMC) outflags &= ~(MD_spc | MD_spc_force); else if (outflags & MD_Sm) outflags |= MD_spc_force; md_word(n->string); if (n->flags & NODE_DELIMO) outflags &= ~(MD_spc | MD_spc_force); else if (outflags & MD_Sm) outflags |= MD_spc; } else if (n->tok < ROFF_MAX) { switch (n->tok) { case ROFF_br: process_children = md_pre_br(n); break; case ROFF_sp: process_children = md_pre_Pp(n); break; default: process_children = 0; break; } } else { act = md_act(n->tok); cond = act->cond == NULL || (*act->cond)(n); if (cond && act->pre != NULL && (n->end == ENDBODY_NOT || n->child != NULL)) process_children = (*act->pre)(n); } if (process_children && n->child != NULL) md_nodelist(n->child); if (n->flags & NODE_ENDED) return; if (cond && act->post != NULL) (*act->post)(n); if (n->end != ENDBODY_NOT) n->body->flags |= NODE_ENDED; } static const char * md_stack(char c) { static char *stack; static size_t sz; static size_t cur; switch (c) { case '\0': break; case (char)-1: assert(cur); stack[--cur] = '\0'; break; default: if (cur + 1 >= sz) { sz += 8; stack = mandoc_realloc(stack, sz); } stack[cur] = c; stack[++cur] = '\0'; break; } return stack == NULL ? "" : stack; } /* * Handle vertical and horizontal spacing. */ static void md_preword(void) { const char *cp; /* * If a list block is nested inside a code block or a blockquote, * blank lines for paragraph breaks no longer work; instead, * they terminate the list. Work around this markdown issue * by using mere line breaks instead. */ if (list_blocks && outflags & MD_sp) { outflags &= ~MD_sp; outflags |= MD_br; } /* * End the old line if requested. * Escape whitespace at the end of the markdown line * such that it won't look like an output line break. */ if (outflags & MD_sp) putchar('\n'); else if (outflags & MD_br) { putchar(' '); putchar(' '); } else if (outflags & MD_nl && escflags & ESC_EOL) md_named("zwnj"); /* Start a new line if necessary. */ if (outflags & (MD_nl | MD_br | MD_sp)) { putchar('\n'); for (cp = md_stack('\0'); *cp != '\0'; cp++) { putchar(*cp); if (*cp == '>') putchar(' '); } outflags &= ~(MD_nl | MD_br | MD_sp); escflags = ESC_BOL; outcount = 0; /* Handle horizontal spacing. */ } else if (outflags & MD_spc) { if (outflags & MD_Bk) fputs(" ", stdout); else putchar(' '); escflags &= ~ESC_FON; outcount++; } outflags &= ~(MD_spc_force | MD_nonl); if (outflags & MD_Sm) outflags |= MD_spc; else outflags &= ~MD_spc; } /* * Print markdown syntax elements. * Can also be used for constant strings when neither escaping * nor delimiter handling is required. */ static void md_rawword(const char *s) { md_preword(); if (*s == '\0') return; if (escflags & ESC_FON) { escflags &= ~ESC_FON; if (*s == '*' && !code_blocks) fputs("‌", stdout); } while (*s != '\0') { switch(*s) { case '*': if (s[1] == '\0') escflags |= ESC_FON; break; case '[': escflags |= ESC_SQU; break; case ']': escflags |= ESC_HYP; escflags &= ~ESC_SQU; break; default: break; } md_char(*s++); } if (s[-1] == ' ') escflags |= ESC_EOL; else escflags &= ~ESC_EOL; } /* * Print text and mdoc(7) syntax elements. */ static void md_word(const char *s) { const char *seq, *prevfont, *currfont, *nextfont; char c; int bs, sz, uc, breakline; /* No spacing before closing delimiters. */ if (s[0] != '\0' && s[1] == '\0' && strchr("!),.:;?]", s[0]) != NULL && (outflags & MD_spc_force) == 0) outflags &= ~MD_spc; md_preword(); if (*s == '\0') return; /* No spacing after opening delimiters. */ if ((s[0] == '(' || s[0] == '[') && s[1] == '\0') outflags &= ~MD_spc; breakline = 0; prevfont = currfont = ""; while ((c = *s++) != '\0') { bs = 0; switch(c) { case ASCII_NBRSP: if (code_blocks) c = ' '; else { md_named("nbsp"); c = '\0'; } break; case ASCII_HYPH: bs = escflags & ESC_BOL && !code_blocks; c = '-'; break; case ASCII_BREAK: continue; case '#': case '+': case '-': bs = escflags & ESC_BOL && !code_blocks; break; case '(': bs = escflags & ESC_HYP && !code_blocks; break; case ')': bs = escflags & ESC_NUM && !code_blocks; break; case '*': case '[': case '_': case '`': bs = !code_blocks; break; case '.': bs = escflags & ESC_NUM && !code_blocks; break; case '<': if (code_blocks == 0) { md_named("lt"); c = '\0'; } break; case '=': if (escflags & ESC_BOL && !code_blocks) { md_named("equals"); c = '\0'; } break; case '>': if (code_blocks == 0) { md_named("gt"); c = '\0'; } break; case '\\': uc = 0; nextfont = NULL; switch (mandoc_escape(&s, &seq, &sz)) { case ESCAPE_UNICODE: uc = mchars_num2uc(seq + 1, sz - 1); break; case ESCAPE_NUMBERED: uc = mchars_num2char(seq, sz); break; case ESCAPE_SPECIAL: uc = mchars_spec2cp(seq, sz); break; case ESCAPE_UNDEF: uc = *seq; break; case ESCAPE_DEVICE: md_rawword("markdown"); continue; case ESCAPE_FONTBOLD: nextfont = "**"; break; case ESCAPE_FONTITALIC: nextfont = "*"; break; case ESCAPE_FONTBI: nextfont = "***"; break; case ESCAPE_FONT: case ESCAPE_FONTCW: case ESCAPE_FONTROMAN: nextfont = ""; break; case ESCAPE_FONTPREV: nextfont = prevfont; break; case ESCAPE_BREAK: breakline = 1; break; case ESCAPE_NOSPACE: case ESCAPE_SKIPCHAR: case ESCAPE_OVERSTRIKE: /* XXX not implemented */ /* FALLTHROUGH */ case ESCAPE_ERROR: default: break; } if (nextfont != NULL && !code_blocks) { if (*currfont != '\0') { outflags &= ~MD_spc; md_rawword(currfont); } prevfont = currfont; currfont = nextfont; if (*currfont != '\0') { outflags &= ~MD_spc; md_rawword(currfont); } } if (uc) { if ((uc < 0x20 && uc != 0x09) || (uc > 0x7E && uc < 0xA0)) uc = 0xFFFD; if (code_blocks) { seq = mchars_uc2str(uc); fputs(seq, stdout); outcount += strlen(seq); } else { printf("&#%d;", uc); outcount++; } escflags &= ~ESC_FON; } c = '\0'; break; case ']': bs = escflags & ESC_SQU && !code_blocks; escflags |= ESC_HYP; break; default: break; } if (bs) putchar('\\'); md_char(c); if (breakline && (*s == '\0' || *s == ' ' || *s == ASCII_NBRSP)) { printf(" \n"); breakline = 0; while (*s == ' ' || *s == ASCII_NBRSP) s++; } } if (*currfont != '\0') { outflags &= ~MD_spc; md_rawword(currfont); } else if (s[-2] == ' ') escflags |= ESC_EOL; else escflags &= ~ESC_EOL; } /* * Print a single HTML named character reference. */ static void md_named(const char *s) { printf("&%s;", s); escflags &= ~(ESC_FON | ESC_EOL); outcount++; } /* * Print a single raw character and maintain certain escape flags. */ static void md_char(unsigned char c) { if (c != '\0') { putchar(c); if (c == '*') escflags |= ESC_FON; else escflags &= ~ESC_FON; outcount++; } if (c != ']') escflags &= ~ESC_HYP; if (c == ' ' || c == '\t' || c == '>') return; if (isdigit(c) == 0) escflags &= ~ESC_NUM; else if (escflags & ESC_BOL) escflags |= ESC_NUM; escflags &= ~ESC_BOL; } static int md_cond_head(struct roff_node *n) { return n->type == ROFFT_HEAD; } static int md_cond_body(struct roff_node *n) { return n->type == ROFFT_BODY; } static int md_pre_abort(struct roff_node *n) { abort(); } static int md_pre_raw(struct roff_node *n) { const char *prefix; if ((prefix = md_act(n->tok)->prefix) != NULL) { md_rawword(prefix); outflags &= ~MD_spc; if (*prefix == '`') code_blocks++; } return 1; } static void md_post_raw(struct roff_node *n) { const char *suffix; if ((suffix = md_act(n->tok)->suffix) != NULL) { outflags &= ~(MD_spc | MD_nl); md_rawword(suffix); if (*suffix == '`') code_blocks--; } } static int md_pre_word(struct roff_node *n) { const char *prefix; if ((prefix = md_act(n->tok)->prefix) != NULL) { md_word(prefix); outflags &= ~MD_spc; } return 1; } static void md_post_word(struct roff_node *n) { const char *suffix; if ((suffix = md_act(n->tok)->suffix) != NULL) { outflags &= ~(MD_spc | MD_nl); md_word(suffix); } } static void md_post_pc(struct roff_node *n) { md_post_raw(n); if (n->parent->tok != MDOC_Rs) return; if (n->next != NULL) { md_word(","); if (n->prev != NULL && n->prev->tok == n->tok && n->next->tok == n->tok) md_word("and"); } else { md_word("."); outflags |= MD_nl; } } static int md_pre_skip(struct roff_node *n) { return 0; } static void md_pre_syn(struct roff_node *n) { if (n->prev == NULL || ! (n->flags & NODE_SYNPRETTY)) return; if (n->prev->tok == n->tok && n->tok != MDOC_Ft && n->tok != MDOC_Fo && n->tok != MDOC_Fn) { outflags |= MD_br; return; } switch (n->prev->tok) { case MDOC_Fd: case MDOC_Fn: case MDOC_Fo: case MDOC_In: case MDOC_Vt: outflags |= MD_sp; break; case MDOC_Ft: if (n->tok != MDOC_Fn && n->tok != MDOC_Fo) { outflags |= MD_sp; break; } /* FALLTHROUGH */ default: outflags |= MD_br; break; } } static int md_pre_An(struct roff_node *n) { switch (n->norm->An.auth) { case AUTH_split: outflags &= ~MD_An_nosplit; outflags |= MD_An_split; return 0; case AUTH_nosplit: outflags &= ~MD_An_split; outflags |= MD_An_nosplit; return 0; default: if (outflags & MD_An_split) outflags |= MD_br; else if (n->sec == SEC_AUTHORS && ! (outflags & MD_An_nosplit)) outflags |= MD_An_split; return 1; } } static int md_pre_Ap(struct roff_node *n) { outflags &= ~MD_spc; md_word("'"); outflags &= ~MD_spc; return 0; } static int md_pre_Bd(struct roff_node *n) { switch (n->norm->Bd.type) { case DISP_unfilled: case DISP_literal: return md_pre_Dl(n); default: return md_pre_D1(n); } } static int md_pre_Bk(struct roff_node *n) { switch (n->type) { case ROFFT_BLOCK: return 1; case ROFFT_BODY: outflags |= MD_Bk; return 1; default: return 0; } } static void md_post_Bk(struct roff_node *n) { if (n->type == ROFFT_BODY) outflags &= ~MD_Bk; } static int md_pre_Bl(struct roff_node *n) { n->norm->Bl.count = 0; if (n->norm->Bl.type == LIST_column) md_pre_Dl(n); outflags |= MD_sp; return 1; } static void md_post_Bl(struct roff_node *n) { n->norm->Bl.count = 0; if (n->norm->Bl.type == LIST_column) md_post_D1(n); outflags |= MD_sp; } static int md_pre_D1(struct roff_node *n) { /* * Markdown blockquote syntax does not work inside code blocks. * The best we can do is fall back to another nested code block. */ if (code_blocks) { md_stack('\t'); code_blocks++; } else { md_stack('>'); quote_blocks++; } outflags |= MD_sp; return 1; } static void md_post_D1(struct roff_node *n) { md_stack((char)-1); if (code_blocks) code_blocks--; else quote_blocks--; outflags |= MD_sp; } static int md_pre_Dl(struct roff_node *n) { /* * Markdown code block syntax does not work inside blockquotes. * The best we can do is fall back to another nested blockquote. */ if (quote_blocks) { md_stack('>'); quote_blocks++; } else { md_stack('\t'); code_blocks++; } outflags |= MD_sp; return 1; } static int md_pre_En(struct roff_node *n) { if (n->norm->Es == NULL || n->norm->Es->child == NULL) return 1; md_word(n->norm->Es->child->string); outflags &= ~MD_spc; return 1; } static void md_post_En(struct roff_node *n) { if (n->norm->Es == NULL || n->norm->Es->child == NULL || n->norm->Es->child->next == NULL) return; outflags &= ~MD_spc; md_word(n->norm->Es->child->next->string); } static int md_pre_Eo(struct roff_node *n) { if (n->end == ENDBODY_NOT && n->parent->head->child == NULL && n->child != NULL && n->child->end != ENDBODY_NOT) md_preword(); else if (n->end != ENDBODY_NOT ? n->child != NULL : n->parent->head->child != NULL && (n->child != NULL || (n->parent->tail != NULL && n->parent->tail->child != NULL))) outflags &= ~(MD_spc | MD_nl); return 1; } static void md_post_Eo(struct roff_node *n) { if (n->end != ENDBODY_NOT) { outflags |= MD_spc; return; } if (n->child == NULL && n->parent->head->child == NULL) return; if (n->parent->tail != NULL && n->parent->tail->child != NULL) outflags &= ~MD_spc; else outflags |= MD_spc; } static int md_pre_Fa(struct roff_node *n) { int am_Fa; am_Fa = n->tok == MDOC_Fa; if (am_Fa) n = n->child; while (n != NULL) { md_rawword("*"); outflags &= ~MD_spc; md_node(n); outflags &= ~MD_spc; md_rawword("*"); if ((n = n->next) != NULL) md_word(","); } return 0; } static void md_post_Fa(struct roff_node *n) { if (n->next != NULL && n->next->tok == MDOC_Fa) md_word(","); } static int md_pre_Fd(struct roff_node *n) { md_pre_syn(n); md_pre_raw(n); return 1; } static void md_post_Fd(struct roff_node *n) { md_post_raw(n); outflags |= MD_br; } static void md_post_Fl(struct roff_node *n) { md_post_raw(n); if (n->child == NULL && n->next != NULL && n->next->type != ROFFT_TEXT && !(n->next->flags & NODE_LINE)) outflags &= ~MD_spc; } static int md_pre_Fn(struct roff_node *n) { md_pre_syn(n); if ((n = n->child) == NULL) return 0; md_rawword("**"); outflags &= ~MD_spc; md_node(n); outflags &= ~MD_spc; md_rawword("**"); outflags &= ~MD_spc; md_word("("); if ((n = n->next) != NULL) md_pre_Fa(n); return 0; } static void md_post_Fn(struct roff_node *n) { md_word(")"); if (n->flags & NODE_SYNPRETTY) { md_word(";"); outflags |= MD_sp; } } static int md_pre_Fo(struct roff_node *n) { switch (n->type) { case ROFFT_BLOCK: md_pre_syn(n); break; case ROFFT_HEAD: if (n->child == NULL) return 0; md_pre_raw(n); break; case ROFFT_BODY: outflags &= ~(MD_spc | MD_nl); md_word("("); break; default: break; } return 1; } static void md_post_Fo(struct roff_node *n) { switch (n->type) { case ROFFT_HEAD: if (n->child != NULL) md_post_raw(n); break; case ROFFT_BODY: md_post_Fn(n); break; default: break; } } static int md_pre_In(struct roff_node *n) { if (n->flags & NODE_SYNPRETTY) { md_pre_syn(n); md_rawword("**"); outflags &= ~MD_spc; md_word("#include <"); } else { md_word("<"); outflags &= ~MD_spc; md_rawword("*"); } outflags &= ~MD_spc; return 1; } static void md_post_In(struct roff_node *n) { if (n->flags & NODE_SYNPRETTY) { outflags &= ~MD_spc; md_rawword(">**"); outflags |= MD_nl; } else { outflags &= ~MD_spc; md_rawword("*>"); } } static int md_pre_It(struct roff_node *n) { struct roff_node *bln; switch (n->type) { case ROFFT_BLOCK: return 1; case ROFFT_HEAD: bln = n->parent->parent; if (bln->norm->Bl.comp == 0 && bln->norm->Bl.type != LIST_column) outflags |= MD_sp; outflags |= MD_nl; switch (bln->norm->Bl.type) { case LIST_item: outflags |= MD_br; return 0; case LIST_inset: case LIST_diag: case LIST_ohang: outflags |= MD_br; return 1; case LIST_tag: case LIST_hang: outflags |= MD_sp; return 1; case LIST_bullet: md_rawword("*\t"); break; case LIST_dash: case LIST_hyphen: md_rawword("-\t"); break; case LIST_enum: md_preword(); if (bln->norm->Bl.count < 99) bln->norm->Bl.count++; printf("%d.\t", bln->norm->Bl.count); escflags &= ~ESC_FON; break; case LIST_column: outflags |= MD_br; return 0; default: return 0; } outflags &= ~MD_spc; outflags |= MD_nonl; outcount = 0; md_stack('\t'); if (code_blocks || quote_blocks) list_blocks++; return 0; case ROFFT_BODY: bln = n->parent->parent; switch (bln->norm->Bl.type) { case LIST_ohang: outflags |= MD_br; break; case LIST_tag: case LIST_hang: md_pre_D1(n); break; default: break; } return 1; default: return 0; } } static void md_post_It(struct roff_node *n) { struct roff_node *bln; int i, nc; if (n->type != ROFFT_BODY) return; bln = n->parent->parent; switch (bln->norm->Bl.type) { case LIST_bullet: case LIST_dash: case LIST_hyphen: case LIST_enum: md_stack((char)-1); if (code_blocks || quote_blocks) list_blocks--; break; case LIST_tag: case LIST_hang: md_post_D1(n); break; case LIST_column: if (n->next == NULL) break; /* Calculate the array index of the current column. */ i = 0; while ((n = n->prev) != NULL && n->type != ROFFT_HEAD) i++; /* * If a width was specified for this column, * subtract what printed, and * add the same spacing as in mdoc_term.c. */ nc = bln->norm->Bl.ncols; i = i < nc ? strlen(bln->norm->Bl.cols[i]) - outcount + (nc < 5 ? 4 : nc == 5 ? 3 : 1) : 1; if (i < 1) i = 1; while (i-- > 0) putchar(' '); outflags &= ~MD_spc; escflags &= ~ESC_FON; outcount = 0; break; default: break; } } static void md_post_Lb(struct roff_node *n) { if (n->sec == SEC_LIBRARY) outflags |= MD_br; } static void md_uri(const char *s) { while (*s != '\0') { if (strchr("%()<>", *s) != NULL) { printf("%%%2.2hhX", *s); outcount += 3; } else { putchar(*s); outcount++; } s++; } } static int md_pre_Lk(struct roff_node *n) { const struct roff_node *link, *descr, *punct; if ((link = n->child) == NULL) return 0; /* Find beginning of trailing punctuation. */ punct = n->last; while (punct != link && punct->flags & NODE_DELIMC) punct = punct->prev; punct = punct->next; /* Link text. */ descr = link->next; if (descr == punct) descr = link; /* no text */ md_rawword("["); outflags &= ~MD_spc; do { md_word(descr->string); descr = descr->next; } while (descr != punct); outflags &= ~MD_spc; /* Link target. */ md_rawword("]("); md_uri(link->string); outflags &= ~MD_spc; md_rawword(")"); /* Trailing punctuation. */ while (punct != NULL) { md_word(punct->string); punct = punct->next; } return 0; } static int md_pre_Mt(struct roff_node *n) { const struct roff_node *nch; md_rawword("["); outflags &= ~MD_spc; for (nch = n->child; nch != NULL; nch = nch->next) md_word(nch->string); outflags &= ~MD_spc; md_rawword("](mailto:"); for (nch = n->child; nch != NULL; nch = nch->next) { md_uri(nch->string); if (nch->next != NULL) { putchar(' '); outcount++; } } outflags &= ~MD_spc; md_rawword(")"); return 0; } static int md_pre_Nd(struct roff_node *n) { outflags &= ~MD_nl; outflags |= MD_spc; md_word("-"); return 1; } static int md_pre_Nm(struct roff_node *n) { switch (n->type) { case ROFFT_BLOCK: outflags |= MD_Bk; md_pre_syn(n); break; case ROFFT_HEAD: case ROFFT_ELEM: md_pre_raw(n); break; default: break; } return 1; } static void md_post_Nm(struct roff_node *n) { switch (n->type) { case ROFFT_BLOCK: outflags &= ~MD_Bk; break; case ROFFT_HEAD: case ROFFT_ELEM: md_post_raw(n); break; default: break; } } static int md_pre_No(struct roff_node *n) { outflags |= MD_spc_force; return 1; } static int md_pre_Ns(struct roff_node *n) { outflags &= ~MD_spc; return 0; } static void md_post_Pf(struct roff_node *n) { if (n->next != NULL && (n->next->flags & NODE_LINE) == 0) outflags &= ~MD_spc; } static int md_pre_Pp(struct roff_node *n) { outflags |= MD_sp; return 0; } static int md_pre_Rs(struct roff_node *n) { if (n->sec == SEC_SEE_ALSO) outflags |= MD_sp; return 1; } static int md_pre_Sh(struct roff_node *n) { switch (n->type) { case ROFFT_BLOCK: if (n->sec == SEC_AUTHORS) outflags &= ~(MD_An_split | MD_An_nosplit); break; case ROFFT_HEAD: outflags |= MD_sp; md_rawword(n->tok == MDOC_Sh ? "#" : "##"); break; case ROFFT_BODY: outflags |= MD_sp; break; default: break; } return 1; } static int md_pre_Sm(struct roff_node *n) { if (n->child == NULL) outflags ^= MD_Sm; else if (strcmp("on", n->child->string) == 0) outflags |= MD_Sm; else outflags &= ~MD_Sm; if (outflags & MD_Sm) outflags |= MD_spc; return 0; } static int md_pre_Vt(struct roff_node *n) { switch (n->type) { case ROFFT_BLOCK: md_pre_syn(n); return 1; case ROFFT_BODY: case ROFFT_ELEM: md_pre_raw(n); return 1; default: return 0; } } static void md_post_Vt(struct roff_node *n) { switch (n->type) { case ROFFT_BODY: case ROFFT_ELEM: md_post_raw(n); break; default: break; } } static int md_pre_Xr(struct roff_node *n) { n = n->child; if (n == NULL) return 0; md_node(n); n = n->next; if (n == NULL) return 0; outflags &= ~MD_spc; md_word("("); md_node(n); md_word(")"); return 0; } static int md_pre__T(struct roff_node *n) { if (n->parent->tok == MDOC_Rs && n->parent->norm->Rs.quote_T) md_word("\""); else md_rawword("*"); outflags &= ~MD_spc; return 1; } static void md_post__T(struct roff_node *n) { outflags &= ~MD_spc; if (n->parent->tok == MDOC_Rs && n->parent->norm->Rs.quote_T) md_word("\""); else md_rawword("*"); md_post_pc(n); } static int md_pre_br(struct roff_node *n) { outflags |= MD_br; return 0; }
Upload File
Create Folder