/* ** Copyright (c) 2007 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code to do formatting of wiki text. */ #include "config.h" #include #include "wikiformat.h" #if INTERFACE /* ** Allowed wiki transformation operations */ #define WIKI_HTMLONLY 0x0001 /* HTML markup only. No wiki */ #define WIKI_INLINE 0x0002 /* Do not surround with

..

*/ /* available for reuse: 0x0004 --- formerly WIKI_NOBLOCK */ #define WIKI_BUTTONS 0x0008 /* Allow sub-menu buttons */ #define WIKI_NOBADLINKS 0x0010 /* Ignore broken hyperlinks */ #define WIKI_LINKSONLY 0x0020 /* No markup. Only decorate links */ #define WIKI_NEWLINE 0x0040 /* Honor \n - break lines at each \n */ #define WIKI_MARKDOWNLINKS 0x0080 /* Resolve hyperlinks as in markdown */ #define WIKI_SAFE 0x0100 /* Make the result safe for embedding */ #define WIKI_TARGET_BLANK 0x0200 /* Hyperlinks go to a new window */ #define WIKI_NOBRACKET 0x0400 /* Omit extra [..] around hyperlinks */ #define WIKI_ADMIN 0x0800 /* Ignore g.perm.Hyperlink */ #define WIKI_MARK 0x1000 /* Add .. around problems */ /* ** Return values from wiki_convert */ #define RENDER_LINK 0x0001 /* One or more hyperlinks rendered */ #define RENDER_ENTITY 0x0002 /* One or more HTML entities (ex: <) */ #define RENDER_TAG 0x0004 /* One or more HTML tags */ #define RENDER_BLOCKTAG 0x0008 /* One or more HTML block tags (ex:

) */ #define RENDER_BLOCK 0x0010 /* Block wiki (paragraphs, etc.) */ #define RENDER_MARK 0x0020 /* Output contains .. */ #define RENDER_BADLINK 0x0100 /* Bad hyperlink syntax seen */ #define RENDER_BADTARGET 0x0200 /* Bad hyperlink target */ #define RENDER_BADTAG 0x0400 /* Bad HTML tag or tag syntax */ #define RENDER_BADENTITY 0x0800 /* Bad HTML entity syntax */ #define RENDER_BADHTML 0x1000 /* Bad HTML seen */ #define RENDER_ERROR 0x8000 /* Some other kind of error */ /* Composite values: */ #define RENDER_ANYERROR 0x9f00 /* Mask for any kind of error */ #endif /* INTERFACE */ /* ** These are the only markup attributes allowed. */ enum allowed_attr_t { ATTR_ALIGN = 1, ATTR_ALT, ATTR_BGCOLOR, ATTR_BORDER, ATTR_CELLPADDING, ATTR_CELLSPACING, ATTR_CITE, ATTR_CLASS, ATTR_CLEAR, ATTR_COLOR, ATTR_COLSPAN, ATTR_COMPACT, ATTR_DATETIME, ATTR_FACE, ATTR_FOR, ATTR_HEIGHT, ATTR_HIGH, ATTR_HREF, ATTR_HSPACE, ATTR_ID, ATTR_LINKS, ATTR_LOW, ATTR_MAX, ATTR_MEDIA, ATTR_MIN, ATTR_NAME, ATTR_OPEN, ATTR_OPTIMUM, ATTR_ROWSPAN, ATTR_SIZE, ATTR_SIZES, ATTR_SRC, ATTR_SRCSET, ATTR_START, ATTR_STYLE, ATTR_TARGET, ATTR_TITLE, ATTR_TYPE, ATTR_VALIGN, ATTR_VALUE, ATTR_VSPACE, ATTR_WIDTH }; typedef uint64_t amsk_t; #define AMSK_ALIGN ((amsk_t)1 << 0) #define AMSK_ALT ((amsk_t)1 << 1) #define AMSK_BGCOLOR ((amsk_t)1 << 2) #define AMSK_BORDER ((amsk_t)1 << 3) #define AMSK_CELLPADDING ((amsk_t)1 << 4) #define AMSK_CELLSPACING ((amsk_t)1 << 5) #define AMSK_CLASS ((amsk_t)1 << 6) #define AMSK_CLEAR ((amsk_t)1 << 7) #define AMSK_COLOR ((amsk_t)1 << 8) #define AMSK_COLSPAN ((amsk_t)1 << 9) #define AMSK_COMPACT ((amsk_t)1 << 10) #define AMSK_FACE ((amsk_t)1 << 11) #define AMSK_HEIGHT ((amsk_t)1 << 12) #define AMSK_HREF ((amsk_t)1 << 13) #define AMSK_HSPACE ((amsk_t)1 << 14) #define AMSK_ID ((amsk_t)1 << 15) #define AMSK_LINKS ((amsk_t)1 << 16) #define AMSK_NAME ((amsk_t)1 << 17) #define AMSK_OPEN ((amsk_t)1 << 18) #define AMSK_ROWSPAN ((amsk_t)1 << 19) #define AMSK_SIZE ((amsk_t)1 << 20) #define AMSK_SRC ((amsk_t)1 << 21) #define AMSK_START ((amsk_t)1 << 22) #define AMSK_STYLE ((amsk_t)1 << 23) #define AMSK_TARGET ((amsk_t)1 << 24) #define AMSK_TITLE ((amsk_t)1 << 25) #define AMSK_TYPE ((amsk_t)1 << 26) #define AMSK_VALIGN ((amsk_t)1 << 27) #define AMSK_VALUE ((amsk_t)1 << 28) #define AMSK_VSPACE ((amsk_t)1 << 29) #define AMSK_WIDTH ((amsk_t)1 << 30) #define AMSK_CITE ((amsk_t)1 << 31) #define AMSK_DATETIME ((amsk_t)1 << 32) static const struct AllowedAttribute { const char *zName; amsk_t iMask; } aAttribute[] = { /* These indexes MUST line up with their corresponding allowed_attr_t enum values. */ { 0, 0 }, { "align", AMSK_ALIGN }, { "alt", AMSK_ALT }, { "bgcolor", AMSK_BGCOLOR }, { "border", AMSK_BORDER }, { "cellpadding", AMSK_CELLPADDING }, { "cellspacing", AMSK_CELLSPACING }, { "cite", AMSK_CITE }, { "class", AMSK_CLASS }, { "clear", AMSK_CLEAR }, { "color", AMSK_COLOR }, { "colspan", AMSK_COLSPAN }, { "compact", AMSK_COMPACT }, { "datetime", AMSK_DATETIME }, { "face", AMSK_FACE }, { "for", 0 }, { "height", AMSK_HEIGHT }, { "high", 0 }, { "href", AMSK_HREF }, { "hspace", AMSK_HSPACE }, { "id", AMSK_ID }, { "links", AMSK_LINKS }, { "low", 0 }, { "max", 0 }, { "media", 0 }, { "min", 0 }, { "name", AMSK_NAME }, { "open", AMSK_OPEN }, { "optimum", 0 }, { "rowspan", AMSK_ROWSPAN }, { "size", AMSK_SIZE }, { "sizes", 0 }, { "src", AMSK_SRC }, { "srcset", 0 }, { "start", AMSK_START }, { "style", AMSK_STYLE }, { "target", AMSK_TARGET }, { "title", AMSK_TITLE }, { "type", AMSK_TYPE }, { "valign", AMSK_VALIGN }, { "value", AMSK_VALUE }, { "vspace", AMSK_VSPACE }, { "width", AMSK_WIDTH }, }; /* ** Use binary search to locate a tag in the aAttribute[] table. */ static int findAttr(const char *z){ int i, c, first, last; first = 1; last = count(aAttribute) - 1; while( first<=last ){ i = (first+last)/2; c = fossil_strcmp(aAttribute[i].zName, z); if( c==0 ){ return i; }else if( c<0 ){ first = i+1; }else{ last = i-1; } } return 0; } /* ** Allowed markup. ** ** Except for MARKUP_INVALID, this must all be in alphabetical order ** and in numerical sequence. The first markup type must be zero. ** The value for MARKUP_XYZ must correspond to the entry ** in aMarkup[]. */ enum markup_t { MARKUP_INVALID = 0, MARKUP_A, MARKUP_ABBR, MARKUP_ADDRESS, MARKUP_HTML5_ARTICLE, MARKUP_HTML5_ASIDE, MARKUP_B, MARKUP_BIG, MARKUP_BLOCKQUOTE, MARKUP_BR, MARKUP_CAPTION, MARKUP_CENTER, MARKUP_CITE, MARKUP_CODE, MARKUP_COL, MARKUP_COLGROUP, MARKUP_DD, MARKUP_DEL, MARKUP_DETAILS, MARKUP_DFN, MARKUP_DIV, MARKUP_DL, MARKUP_DT, MARKUP_EM, MARKUP_FIGCAPTION, MARKUP_FIGURE, MARKUP_FONT, MARKUP_HTML5_FOOTER, MARKUP_H1, MARKUP_H2, MARKUP_H3, MARKUP_H4, MARKUP_H5, MARKUP_H6, MARKUP_HTML5_HEADER, MARKUP_HR, MARKUP_I, MARKUP_IMG, MARKUP_INS, MARKUP_KBD, MARKUP_LABEL, MARKUP_LI, MARKUP_MARK, MARKUP_METER, MARKUP_HTML5_NAV, MARKUP_NOBR, MARKUP_NOWIKI, MARKUP_OL, MARKUP_P, MARKUP_PICTURE, MARKUP_PRE, MARKUP_PROGRESS, MARKUP_Q, MARKUP_S, MARKUP_SAMP, MARKUP_HTML5_SECTION, MARKUP_SMALL, MARKUP_SOURCE, MARKUP_SPAN, MARKUP_STRIKE, MARKUP_STRONG, MARKUP_SUB, MARKUP_SUMMARY, MARKUP_SUP, MARKUP_TABLE, MARKUP_TBODY, MARKUP_TD, MARKUP_TFOOT, MARKUP_TH, MARKUP_THEAD, MARKUP_TIME, MARKUP_TITLE, MARKUP_TR, MARKUP_TT, MARKUP_U, MARKUP_UL, MARKUP_VAR, MARKUP_VERBATIM, MARKUP_WBR }; /* ** The various markup is divided into the following types: */ #define MUTYPE_SINGLE 0x0001 /* ,
, or


*/ #define MUTYPE_BLOCK 0x0002 /* Forms a new paragraph. ex:

,

*/ #define MUTYPE_FONT 0x0004 /* Font changes. ex: , , */ #define MUTYPE_LIST 0x0010 /* Lists.
    ,