Fossil

Diff
Login

Differences From Artifact [ae8551d084]:

To Artifact [ec6e1ead10]:


23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37







-
+








#if INTERFACE
/*
** Allowed wiki transformation operations
*/
#define WIKI_HTMLONLY      0x0001  /* HTML markup only.  No wiki */
#define WIKI_INLINE        0x0002  /* Do not surround with <p>..</p> */
#define WIKI_NOBLOCK       0x0004  /* No block markup of any kind */
/* avalable 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 */
463
464
465
466
467
468
469
470
471

472
473
474
475
476
477
478
463
464
465
466
467
468
469


470
471
472
473
474
475
476
477







-
-
+







** State flags.  Save the lower 16 bits for the WIKI_* flags.
*/
#define AT_NEWLINE          0x0010000  /* At start of a line */
#define AT_PARAGRAPH        0x0020000  /* At start of a paragraph */
#define ALLOW_WIKI          0x0040000  /* Allow wiki markup */
#define ALLOW_LINKS         0x0080000  /* Allow [...] hyperlinks */
#define FONT_MARKUP_ONLY    0x0100000  /* Only allow MUTYPE_FONT markup */
#define INLINE_MARKUP_ONLY  0x0200000  /* Allow only "inline" markup */
#define IN_LIST             0x0400000  /* Within wiki <ul> or <ol> */
#define IN_LIST             0x0200000  /* Within wiki <ul> or <ol> */

/*
** Current state of the rendering engine
*/
typedef struct Renderer Renderer;
struct Renderer {
  Blob *pOut;                 /* Output appended to this blob */
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559







1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590













1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611













1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632













1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643





1644
1645
1646
1647
1648
1649
1650
1651
1523
1524
1525
1526
1527
1528
1529

1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546











1547
1548
1549
1550
1551
1552
1553

1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
















1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580

1581
1582
1583
1584
















1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597

1598
1599
1600
1601
















1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614

1615
1616
1617
1618






1619
1620
1621
1622
1623

1624
1625
1626
1627
1628
1629
1630







-

















-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-














-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-




-
-
-
-
-
-
+
+
+
+
+
-







**
** This routine will probably modify the content of z[].
*/
static void wiki_render(Renderer *p, char *z){
  int tokenType;
  ParsedMarkup markup;
  int n;
  int inlineOnly = (p->state & INLINE_MARKUP_ONLY)!=0;
  int wikiHtmlOnly = (p->state & (WIKI_HTMLONLY | WIKI_LINKSONLY))!=0;
  int linksOnly = (p->state & WIKI_LINKSONLY)!=0;
  char *zOrig = z;

  /* Make sure the attribute constants and names still align
  ** following changes in the attribute list. */
  assert( fossil_strcmp(aAttribute[ATTR_WIDTH].zName, "width")==0 );

  while( z[0] ){
    if( wikiHtmlOnly ){
      n = nextRawToken(z, p, &tokenType);
    }else{
      n = nextWikiToken(z, p, &tokenType);
    }
    p->state &= ~(AT_NEWLINE|AT_PARAGRAPH);
    switch( tokenType ){
      case TOKEN_PARAGRAPH: {
        if( inlineOnly ){
          /* blob_append_string(p->pOut, " &para; "); */
          blob_append_string(p->pOut, " &nbsp;&nbsp; ");
        }else{
          if( p->wikiList ){
            popStackToTag(p, p->wikiList);
            p->wikiList = 0;
          }
          endAutoParagraph(p);
          blob_append_string(p->pOut, "\n\n");
          p->wantAutoParagraph = 1;
        if( p->wikiList ){
          popStackToTag(p, p->wikiList);
          p->wikiList = 0;
        }
        endAutoParagraph(p);
        blob_append_string(p->pOut, "\n\n");
        p->wantAutoParagraph = 1;
        }
        p->state |= AT_PARAGRAPH|AT_NEWLINE;
        break;
      }
      case TOKEN_NEWLINE: {
        if( p->renderFlags & WIKI_NEWLINE ){
          blob_append_string(p->pOut, "<br>\n");
        }else{
          blob_append_string(p->pOut, "\n");
        }
        p->state |= AT_NEWLINE;
        break;
      }
      case TOKEN_BUL_LI: {
        p->mRender |= RENDER_BLOCK;
        if( inlineOnly ){
          blob_append_string(p->pOut, " &bull; ");
        }else{
          if( p->wikiList!=MARKUP_UL ){
            if( p->wikiList ){
              popStackToTag(p, p->wikiList);
            }
            endAutoParagraph(p);
            pushStack(p, MARKUP_UL);
            blob_append_string(p->pOut, "<ul>");
            p->wikiList = MARKUP_UL;
          }
          popStackToTag(p, MARKUP_LI);
          startAutoParagraph(p);
          pushStack(p, MARKUP_LI);
          blob_append_string(p->pOut, "<li>");
        if( p->wikiList!=MARKUP_UL ){
          if( p->wikiList ){
            popStackToTag(p, p->wikiList);
          }
          endAutoParagraph(p);
          pushStack(p, MARKUP_UL);
          blob_append_string(p->pOut, "<ul>");
          p->wikiList = MARKUP_UL;
        }
        popStackToTag(p, MARKUP_LI);
        startAutoParagraph(p);
        pushStack(p, MARKUP_LI);
        blob_append_string(p->pOut, "<li>");
        }
        break;
      }
      case TOKEN_NUM_LI: {
        p->mRender |= RENDER_BLOCK;
        if( inlineOnly ){
          blob_append_string(p->pOut, " # ");
        }else{
          if( p->wikiList!=MARKUP_OL ){
            if( p->wikiList ){
              popStackToTag(p, p->wikiList);
            }
            endAutoParagraph(p);
            pushStack(p, MARKUP_OL);
            blob_append_string(p->pOut, "<ol>");
            p->wikiList = MARKUP_OL;
          }
          popStackToTag(p, MARKUP_LI);
          startAutoParagraph(p);
          pushStack(p, MARKUP_LI);
          blob_append_string(p->pOut, "<li>");
        if( p->wikiList!=MARKUP_OL ){
          if( p->wikiList ){
            popStackToTag(p, p->wikiList);
          }
          endAutoParagraph(p);
          pushStack(p, MARKUP_OL);
          blob_append_string(p->pOut, "<ol>");
          p->wikiList = MARKUP_OL;
        }
        popStackToTag(p, MARKUP_LI);
        startAutoParagraph(p);
        pushStack(p, MARKUP_LI);
        blob_append_string(p->pOut, "<li>");
        }
        break;
      }
      case TOKEN_ENUM: {
        p->mRender |= RENDER_BLOCK;
        if( inlineOnly ){
          blob_appendf(p->pOut, " (%d) ", atoi(z));
        }else{
          if( p->wikiList!=MARKUP_OL ){
            if( p->wikiList ){
              popStackToTag(p, p->wikiList);
            }
            endAutoParagraph(p);
            pushStack(p, MARKUP_OL);
            blob_append_string(p->pOut, "<ol>");
            p->wikiList = MARKUP_OL;
          }
          popStackToTag(p, MARKUP_LI);
          startAutoParagraph(p);
          pushStack(p, MARKUP_LI);
          blob_appendf(p->pOut, "<li value=\"%d\">", atoi(z));
        if( p->wikiList!=MARKUP_OL ){
          if( p->wikiList ){
            popStackToTag(p, p->wikiList);
          }
          endAutoParagraph(p);
          pushStack(p, MARKUP_OL);
          blob_append_string(p->pOut, "<ol>");
          p->wikiList = MARKUP_OL;
        }
        popStackToTag(p, MARKUP_LI);
        startAutoParagraph(p);
        pushStack(p, MARKUP_LI);
        blob_appendf(p->pOut, "<li value=\"%d\">", atoi(z));
        }
        break;
      }
      case TOKEN_INDENT: {
        p->mRender |= RENDER_BLOCK;
        if( !inlineOnly ){
          assert( p->wikiList==0 );
          pushStack(p, MARKUP_BLOCKQUOTE);
          blob_append_string(p->pOut, "<blockquote>");
          p->wantAutoParagraph = 0;
          p->wikiList = MARKUP_BLOCKQUOTE;
        assert( p->wikiList==0 );
        pushStack(p, MARKUP_BLOCKQUOTE);
        blob_append_string(p->pOut, "<blockquote>");
        p->wantAutoParagraph = 0;
        p->wikiList = MARKUP_BLOCKQUOTE;
        }
        break;
      }
      case TOKEN_CHARACTER: {
        startAutoParagraph(p);
        if( p->state & WIKI_MARK ){
          blob_append_string(p->pOut, "<mark>");
          p->mRender |= RENDER_MARK;
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1787
1788
1789
1790
1791
1792
1793






1794
1795
1796
1797
1798
1799
1800







-
-
-
-
-
-







          if( markup.endTag ){
            p->state |= ALLOW_WIKI;
          }else{
            p->state &= ~ALLOW_WIKI;
          }
        }else

        /* Ignore block markup for in-line rendering.
        */
        if( inlineOnly && (markup.iType&MUTYPE_INLINE)==0 ){
          /* Do nothing */
        }else

        /* Generate end-tags */
        if( markup.endTag ){
          popStackToTag(p, markup.iCode);
        }else

        /* Push <div> markup onto the stack together with the id=ID attribute.
        */
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2130
2131
2132
2133
2134
2135
2136

2137
2138
2139
2140



2141
2142
2143
2144

2145
2146
2147
2148
2149
2150
2151







-




-
-
-




-







  Backlink *pBklnk,  /* Backlink extraction context */
  int flags          /* wiki parsing flags */
){
  Renderer renderer;
  int tokenType;
  ParsedMarkup markup;
  int n;
  int inlineOnly;
  int wikiHtmlOnly = 0;

  memset(&renderer, 0, sizeof(renderer));
  renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH;
  if( flags & WIKI_NOBLOCK ){
    renderer.state |= INLINE_MARKUP_ONLY;
  }
  if( wikiUsesHtml() ){
    renderer.state |= WIKI_HTMLONLY;
    wikiHtmlOnly = 1;
  }
  inlineOnly = (renderer.state & INLINE_MARKUP_ONLY)!=0;

  while( z[0] ){
    if( wikiHtmlOnly ){
      n = nextRawToken(z, &renderer, &tokenType);
    }else{
      n = nextWikiToken(z, &renderer, &tokenType);
    }
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2218
2219
2220
2221
2222
2223
2224






2225
2226
2227
2228
2229
2230
2231







-
-
-
-
-
-







          if( markup.endTag ){
            renderer.state |= ALLOW_WIKI;
          }else{
            renderer.state &= ~ALLOW_WIKI;
          }
        }else

        /* Ignore block markup for in-line rendering.
        */
        if( inlineOnly && (markup.iType&MUTYPE_INLINE)==0 ){
          /* Do nothing */
        }else

        /* Generate end-tags */
        if( markup.endTag ){
          popStackToTag(&renderer, markup.iCode);
        }else

        /* Push <div> markup onto the stack together with the id=ID attribute.
        */