| | @@ -35,19 +35,21 @@ |
| 35 | 35 | #define WIKI_MARKDOWNLINKS 0x0080 /* Resolve hyperlinks as in markdown */ |
| 36 | 36 | #define WIKI_SAFE 0x0100 /* Make the result safe for embedding */ |
| 37 | 37 | #define WIKI_TARGET_BLANK 0x0200 /* Hyperlinks go to a new window */ |
| 38 | 38 | #define WIKI_NOBRACKET 0x0400 /* Omit extra [..] around hyperlinks */ |
| 39 | 39 | #define WIKI_ADMIN 0x0800 /* Ignore g.perm.Hyperlink */ |
| 40 | +#define WIKI_MARK 0x1000 /* Add <mark>..</mark> around problems */ |
| 40 | 41 | |
| 41 | 42 | /* |
| 42 | 43 | ** Return values from wiki_convert |
| 43 | 44 | */ |
| 44 | 45 | #define RENDER_LINK 0x0001 /* One or more hyperlinks rendered */ |
| 45 | 46 | #define RENDER_ENTITY 0x0002 /* One or more HTML entities (ex: <) */ |
| 46 | 47 | #define RENDER_TAG 0x0004 /* One or more HTML tags */ |
| 47 | 48 | #define RENDER_BLOCKTAG 0x0008 /* One or more HTML block tags (ex: <p>) */ |
| 48 | 49 | #define RENDER_BLOCK 0x0010 /* Block wiki (paragraphs, etc.) */ |
| 50 | +#define RENDER_MARK 0x0020 /* Output contains <mark>..</mark> */ |
| 49 | 51 | #define RENDER_BADLINK 0x0100 /* Bad hyperlink syntax seen */ |
| 50 | 52 | #define RENDER_BADTARGET 0x0200 /* Bad hyperlink target */ |
| 51 | 53 | #define RENDER_BADTAG 0x0400 /* Bad HTML tag or tag syntax */ |
| 52 | 54 | #define RENDER_BADENTITY 0x0800 /* Bad HTML entity syntax */ |
| 53 | 55 | #define RENDER_BADHTML 0x1000 /* Bad HTML seen */ |
| | @@ -754,18 +756,24 @@ |
| 754 | 756 | } |
| 755 | 757 | if( z[0]=='[' ){ |
| 756 | 758 | if( (n = linkLength(z))>0 ){ |
| 757 | 759 | *pTokenType = TOKEN_LINK; |
| 758 | 760 | return n; |
| 761 | + }else if( p->state & WIKI_MARK ){ |
| 762 | + blob_append_string(p->pOut, "<mark>"); |
| 763 | + p->mRender |= RENDER_BADLINK|RENDER_MARK; |
| 759 | 764 | }else{ |
| 760 | 765 | p->mRender |= RENDER_BADLINK; |
| 761 | 766 | } |
| 762 | 767 | } |
| 763 | 768 | }else if( (p->state & ALLOW_LINKS)!=0 && z[0]=='[' ){ |
| 764 | 769 | if( (n = linkLength(z))>0 ){ |
| 765 | 770 | *pTokenType = TOKEN_LINK; |
| 766 | 771 | return n; |
| 772 | + }else if( p->state & WIKI_MARK ){ |
| 773 | + blob_append_string(p->pOut, "<mark>"); |
| 774 | + p->mRender |= RENDER_BADLINK|RENDER_MARK; |
| 767 | 775 | }else{ |
| 768 | 776 | p->mRender |= RENDER_BADLINK; |
| 769 | 777 | } |
| 770 | 778 | } |
| 771 | 779 | *pTokenType = TOKEN_TEXT; |
| | @@ -1358,10 +1366,14 @@ |
| 1358 | 1366 | } |
| 1359 | 1367 | } |
| 1360 | 1368 | }else if( !in_this_repo(zTarget) ){ |
| 1361 | 1369 | if( (mFlags & (WIKI_LINKSONLY|WIKI_NOBADLINKS))!=0 ){ |
| 1362 | 1370 | zTerm = ""; |
| 1371 | + }else if( (mFlags & WIKI_MARK)!=0 ){ |
| 1372 | + blob_appendf(pOut, "<mark>%s", zLB); |
| 1373 | + zTerm = "]</mark>"; |
| 1374 | + rc |= RENDER_MARK; |
| 1363 | 1375 | }else{ |
| 1364 | 1376 | blob_appendf(pOut, "<span class=\"brokenlink\">%s", zLB); |
| 1365 | 1377 | zTerm = "]</span>"; |
| 1366 | 1378 | } |
| 1367 | 1379 | rc |= RENDER_BADTARGET; |
| | @@ -1390,10 +1402,14 @@ |
| 1390 | 1402 | blob_appendf(pOut, "<a href=\"%R/timeline?c=%T\"%s>", zTarget, zExtra); |
| 1391 | 1403 | }else if( mFlags & WIKI_MARKDOWNLINKS ){ |
| 1392 | 1404 | /* If none of the above, and if rendering links for markdown, then |
| 1393 | 1405 | ** create a link to the literal text of the target */ |
| 1394 | 1406 | blob_appendf(pOut, "<a href=\"%h\"%s>", zTarget, zExtra); |
| 1407 | + }else if( mFlags & WIKI_MARK ){ |
| 1408 | + blob_appendf(pOut, "<mark>["); |
| 1409 | + zTerm = "]</mark>"; |
| 1410 | + rc |= RENDER_BADTARGET|RENDER_MARK; |
| 1395 | 1411 | }else if( zOrig && zTarget>=&zOrig[2] |
| 1396 | 1412 | && zTarget[-1]=='[' && !fossil_isspace(zTarget[-2]) ){ |
| 1397 | 1413 | /* If the hyperlink markup is not preceded by whitespace, then it |
| 1398 | 1414 | ** is probably a C-language subscript or similar, not really a |
| 1399 | 1415 | ** hyperlink. Just ignore it. */ |
| | @@ -1628,15 +1644,28 @@ |
| 1628 | 1644 | } |
| 1629 | 1645 | break; |
| 1630 | 1646 | } |
| 1631 | 1647 | case TOKEN_CHARACTER: { |
| 1632 | 1648 | startAutoParagraph(p); |
| 1649 | + if( p->state & WIKI_MARK ){ |
| 1650 | + blob_append_string(p->pOut, "<mark>"); |
| 1651 | + p->mRender |= RENDER_MARK; |
| 1652 | + } |
| 1633 | 1653 | if( z[0]=='<' ){ |
| 1634 | 1654 | blob_append_string(p->pOut, "<"); |
| 1635 | 1655 | }else if( z[0]=='&' ){ |
| 1636 | 1656 | blob_append_string(p->pOut, "&"); |
| 1637 | 1657 | } |
| 1658 | + if( p->state & WIKI_MARK ){ |
| 1659 | + if( fossil_isalnum(z[1]) || (z[1]=='/' && fossil_isalnum(z[2])) ){ |
| 1660 | + int kk; |
| 1661 | + for(kk=2; fossil_isalnum(z[kk]); kk++){} |
| 1662 | + blob_append(p->pOut, &z[1], kk-1); |
| 1663 | + n = kk; |
| 1664 | + } |
| 1665 | + blob_append_string(p->pOut, "</mark>"); |
| 1666 | + } |
| 1638 | 1667 | break; |
| 1639 | 1668 | } |
| 1640 | 1669 | case TOKEN_LINK: { |
| 1641 | 1670 | char *zTarget; |
| 1642 | 1671 | char *zDisplay = 0; |
| | @@ -1755,12 +1784,19 @@ |
| 1755 | 1784 | */ |
| 1756 | 1785 | if( markup.iCode==MARKUP_INVALID ){ |
| 1757 | 1786 | p->mRender |= RENDER_BADTAG; |
| 1758 | 1787 | unparseMarkup(&markup); |
| 1759 | 1788 | startAutoParagraph(p); |
| 1760 | | - blob_append_string(p->pOut, "<"); |
| 1761 | | - n = 1; |
| 1789 | + if( p->state & WIKI_MARK ){ |
| 1790 | + p->mRender |= RENDER_MARK; |
| 1791 | + blob_append_string(p->pOut, "<mark>"); |
| 1792 | + htmlize_to_blob(p->pOut, z, n); |
| 1793 | + blob_append_string(p->pOut, "</mark>"); |
| 1794 | + }else{ |
| 1795 | + blob_append_string(p->pOut, "<"); |
| 1796 | + htmlize_to_blob(p->pOut, z+1, n-1); |
| 1797 | + } |
| 1762 | 1798 | }else |
| 1763 | 1799 | |
| 1764 | 1800 | /* If the markup is not font-change markup ignore it if the |
| 1765 | 1801 | ** font-change-only flag is set. |
| 1766 | 1802 | */ |
| | @@ -1941,56 +1977,69 @@ |
| 1941 | 1977 | ** the resulting HTML on standard output. |
| 1942 | 1978 | ** |
| 1943 | 1979 | ** Options: |
| 1944 | 1980 | ** --buttons Set the WIKI_BUTTONS flag |
| 1945 | 1981 | ** --dark-pikchr Render pikchrs in dark mode |
| 1982 | +** --flow Render as text using comment_format |
| 1946 | 1983 | ** --htmlonly Set the WIKI_HTMLONLY flag |
| 1947 | 1984 | ** --inline Set the WIKI_INLINE flag |
| 1948 | 1985 | ** --linksonly Set the WIKI_LINKSONLY flag |
| 1986 | +** --mark Add <mark>...</mark> around problems |
| 1949 | 1987 | ** --nobadlinks Set the WIKI_NOBADLINKS flag |
| 1950 | | -** --noblock Set the WIKI_NOBLOCK flag |
| 1951 | | -** --text Run the output through html_to_plaintext(). |
| 1952 | | -** --type Break down the return code from wiki_convert(). |
| 1988 | +** --text Run the output through html_to_plaintext() |
| 1989 | +** --type Break down the return code from wiki_convert() |
| 1953 | 1990 | */ |
| 1954 | 1991 | void test_wiki_render(void){ |
| 1955 | 1992 | Blob in, out; |
| 1956 | 1993 | int flags = 0; |
| 1957 | 1994 | int bText; |
| 1995 | + int bFlow = 0; |
| 1958 | 1996 | int showType = 0; |
| 1959 | 1997 | int mType; |
| 1960 | 1998 | if( find_option("buttons",0,0)!=0 ) flags |= WIKI_BUTTONS; |
| 1961 | 1999 | if( find_option("htmlonly",0,0)!=0 ) flags |= WIKI_HTMLONLY; |
| 1962 | 2000 | if( find_option("linksonly",0,0)!=0 ) flags |= WIKI_LINKSONLY; |
| 1963 | 2001 | if( find_option("nobadlinks",0,0)!=0 ) flags |= WIKI_NOBADLINKS; |
| 1964 | 2002 | if( find_option("inline",0,0)!=0 ) flags |= WIKI_INLINE; |
| 1965 | | - if( find_option("noblock",0,0)!=0 ) flags |= WIKI_NOBLOCK; |
| 2003 | + if( find_option("mark",0,0)!=0 ) flags |= WIKI_MARK; |
| 1966 | 2004 | if( find_option("dark-pikchr",0,0)!=0 ){ |
| 1967 | 2005 | pikchr_to_html_add_flags( PIKCHR_PROCESS_DARK_MODE ); |
| 1968 | 2006 | } |
| 1969 | 2007 | bText = find_option("text",0,0)!=0; |
| 2008 | + bFlow = find_option("flow",0,0)!=0; |
| 1970 | 2009 | showType = find_option("type",0,0)!=0; |
| 1971 | 2010 | db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0); |
| 1972 | 2011 | verify_all_options(); |
| 1973 | 2012 | if( g.argc!=3 ) usage("FILE"); |
| 1974 | 2013 | blob_zero(&out); |
| 1975 | 2014 | blob_read_from_file(&in, g.argv[2], ExtFILE); |
| 1976 | 2015 | mType = wiki_convert(&in, &out, flags); |
| 1977 | 2016 | if( bText ){ |
| 1978 | 2017 | Blob txt; |
| 2018 | + int htot = 0; |
| 2019 | + if( terminal_is_vt100() ) htot |= HTOT_VT100; |
| 2020 | + if( bFlow ) htot |= HTOT_NO_WS; |
| 1979 | 2021 | blob_init(&txt, 0, 0); |
| 1980 | | - html_to_plaintext(blob_str(&out),&txt, HTOT_VT100); |
| 2022 | + html_to_plaintext(blob_str(&out),&txt, htot); |
| 1981 | 2023 | blob_reset(&out); |
| 1982 | 2024 | out = txt; |
| 1983 | 2025 | } |
| 1984 | | - blob_write_to_file(&out, "-"); |
| 2026 | + if( bFlow ){ |
| 2027 | + fossil_print(" "); |
| 2028 | + comment_print(blob_str(&out), 0, 3, terminal_get_width(80)-3, |
| 2029 | + get_comment_format()); |
| 2030 | + }else{ |
| 2031 | + blob_write_to_file(&out, "-"); |
| 2032 | + } |
| 1985 | 2033 | if( showType ){ |
| 1986 | 2034 | fossil_print("%.*c\nResult Codes:", terminal_get_width(80)-1, '*'); |
| 1987 | 2035 | if( mType & RENDER_LINK ) fossil_print(" LINK"); |
| 1988 | 2036 | if( mType & RENDER_ENTITY ) fossil_print(" ENTITY"); |
| 1989 | 2037 | if( mType & RENDER_TAG ) fossil_print(" TAG"); |
| 1990 | 2038 | if( mType & RENDER_BLOCKTAG ) fossil_print(" BLOCKTAG"); |
| 1991 | 2039 | if( mType & RENDER_BLOCK ) fossil_print(" BLOCK"); |
| 2040 | + if( mType & RENDER_MARK ) fossil_print(" MARK"); |
| 1992 | 2041 | if( mType & RENDER_BADLINK ) fossil_print(" BADLINK"); |
| 1993 | 2042 | if( mType & RENDER_BADTARGET ) fossil_print(" BADTARGET"); |
| 1994 | 2043 | if( mType & RENDER_BADTAG ) fossil_print(" BADTAG"); |
| 1995 | 2044 | if( mType & RENDER_BADENTITY ) fossil_print(" BADENTITY"); |
| 1996 | 2045 | if( mType & RENDER_BADHTML ) fossil_print(" BADHTML"); |
| 1997 | 2046 | |