Fossil SCM

Add the BACKLINK table and code to populate it. NB: Run "rebuild" when updating to this or later versions.

drh 2010-03-15 14:46 trunk
Commit f2181f5e45b62da9c11fc6258f555593ef7b2b6c
--- src/manifest.c
+++ src/manifest.c
@@ -1032,10 +1032,11 @@
10321032
return 0;
10331033
}
10341034
db_begin_transaction();
10351035
if( m.type==CFTYPE_MANIFEST ){
10361036
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
1037
+ char *zCom;
10371038
for(i=0; i<m.nParent; i++){
10381039
int pid = uuid_to_rid(m.azParent[i], 1);
10391040
db_multi_exec("INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)"
10401041
"VALUES(%d, %d, %d, %.17g)", pid, rid, i==0, m.rDate);
10411042
if( i==0 ){
@@ -1065,10 +1066,14 @@
10651066
rid, m.zUser, m.zComment,
10661067
TAG_BGCOLOR, rid,
10671068
TAG_USER, rid,
10681069
TAG_COMMENT, rid
10691070
);
1071
+ zCom = db_text(0, "SELECT coalesce(ecomment, comment) FROM event"
1072
+ " WHERE rowid=last_insert_rowid()");
1073
+ wiki_extract_links(zCom, rid, 0, m.rDate, 1, WIKI_INLINE);
1074
+ free(zCom);
10701075
}
10711076
}
10721077
if( m.type==CFTYPE_CLUSTER ){
10731078
tag_insert("cluster", 1, 0, rid, m.rDate, rid);
10741079
for(i=0; i<m.nCChild; i++){
10751080
--- src/manifest.c
+++ src/manifest.c
@@ -1032,10 +1032,11 @@
1032 return 0;
1033 }
1034 db_begin_transaction();
1035 if( m.type==CFTYPE_MANIFEST ){
1036 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
 
1037 for(i=0; i<m.nParent; i++){
1038 int pid = uuid_to_rid(m.azParent[i], 1);
1039 db_multi_exec("INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)"
1040 "VALUES(%d, %d, %d, %.17g)", pid, rid, i==0, m.rDate);
1041 if( i==0 ){
@@ -1065,10 +1066,14 @@
1065 rid, m.zUser, m.zComment,
1066 TAG_BGCOLOR, rid,
1067 TAG_USER, rid,
1068 TAG_COMMENT, rid
1069 );
 
 
 
 
1070 }
1071 }
1072 if( m.type==CFTYPE_CLUSTER ){
1073 tag_insert("cluster", 1, 0, rid, m.rDate, rid);
1074 for(i=0; i<m.nCChild; i++){
1075
--- src/manifest.c
+++ src/manifest.c
@@ -1032,10 +1032,11 @@
1032 return 0;
1033 }
1034 db_begin_transaction();
1035 if( m.type==CFTYPE_MANIFEST ){
1036 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
1037 char *zCom;
1038 for(i=0; i<m.nParent; i++){
1039 int pid = uuid_to_rid(m.azParent[i], 1);
1040 db_multi_exec("INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)"
1041 "VALUES(%d, %d, %d, %.17g)", pid, rid, i==0, m.rDate);
1042 if( i==0 ){
@@ -1065,10 +1066,14 @@
1066 rid, m.zUser, m.zComment,
1067 TAG_BGCOLOR, rid,
1068 TAG_USER, rid,
1069 TAG_COMMENT, rid
1070 );
1071 zCom = db_text(0, "SELECT coalesce(ecomment, comment) FROM event"
1072 " WHERE rowid=last_insert_rowid()");
1073 wiki_extract_links(zCom, rid, 0, m.rDate, 1, WIKI_INLINE);
1074 free(zCom);
1075 }
1076 }
1077 if( m.type==CFTYPE_CLUSTER ){
1078 tag_insert("cluster", 1, 0, rid, m.rDate, rid);
1079 for(i=0; i<m.nCChild; i++){
1080
+14
--- src/schema.c
+++ src/schema.c
@@ -308,10 +308,24 @@
308308
@ mtime TIMESTAMP, -- Time of addition or removal
309309
@ rid INTEGER REFERENCE blob, -- Artifact tag is applied to
310310
@ UNIQUE(rid, tagid)
311311
@ );
312312
@ CREATE INDEX tagxref_i1 ON tagxref(tagid, mtime);
313
+@
314
+@ -- When a hyperlink occurs from one artifact to another (for example
315
+@ -- when a check-in comment refers to a ticket) an entry is made in
316
+@ -- the following table for that hyperlink. This table is used to
317
+@ -- facilitate the display of "back links".
318
+@ --
319
+@ CREATE TABLE backlink(
320
+@ target TEXT, -- Where the hyperlink points to
321
+@ srctype INT, -- 0: check-in 1: ticket 2: wiki
322
+@ srcid INT, -- rid for checkin or wiki. tkt_id for ticket.
323
+@ mtime TIMESTAMP, -- time that the hyperlink was added
324
+@ UNIQUE(target, srctype, srcid)
325
+@ );
326
+@ CREATE INDEX backlink_src ON backlink(srcid, srctype);
313327
@
314328
@ -- Template for the TICKET table
315329
@ --
316330
@ -- NB: when changing the schema of the TICKET table here, also make the
317331
@ -- same change in tktsetup.c.
318332
--- src/schema.c
+++ src/schema.c
@@ -308,10 +308,24 @@
308 @ mtime TIMESTAMP, -- Time of addition or removal
309 @ rid INTEGER REFERENCE blob, -- Artifact tag is applied to
310 @ UNIQUE(rid, tagid)
311 @ );
312 @ CREATE INDEX tagxref_i1 ON tagxref(tagid, mtime);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313 @
314 @ -- Template for the TICKET table
315 @ --
316 @ -- NB: when changing the schema of the TICKET table here, also make the
317 @ -- same change in tktsetup.c.
318
--- src/schema.c
+++ src/schema.c
@@ -308,10 +308,24 @@
308 @ mtime TIMESTAMP, -- Time of addition or removal
309 @ rid INTEGER REFERENCE blob, -- Artifact tag is applied to
310 @ UNIQUE(rid, tagid)
311 @ );
312 @ CREATE INDEX tagxref_i1 ON tagxref(tagid, mtime);
313 @
314 @ -- When a hyperlink occurs from one artifact to another (for example
315 @ -- when a check-in comment refers to a ticket) an entry is made in
316 @ -- the following table for that hyperlink. This table is used to
317 @ -- facilitate the display of "back links".
318 @ --
319 @ CREATE TABLE backlink(
320 @ target TEXT, -- Where the hyperlink points to
321 @ srctype INT, -- 0: check-in 1: ticket 2: wiki
322 @ srcid INT, -- rid for checkin or wiki. tkt_id for ticket.
323 @ mtime TIMESTAMP, -- time that the hyperlink was added
324 @ UNIQUE(target, srctype, srcid)
325 @ );
326 @ CREATE INDEX backlink_src ON backlink(srcid, srctype);
327 @
328 @ -- Template for the TICKET table
329 @ --
330 @ -- NB: when changing the schema of the TICKET table here, also make the
331 @ -- same change in tktsetup.c.
332
+5
--- src/tag.c
+++ src/tag.c
@@ -200,10 +200,15 @@
200200
break;
201201
}
202202
}
203203
if( zCol ){
204204
db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
205
+ if( tagid==TAG_COMMENT ){
206
+ char *zCopy = mprintf("%s", zValue);
207
+ wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE);
208
+ free(zCopy);
209
+ }
205210
}
206211
if( tagid==TAG_DATE ){
207212
db_multi_exec("UPDATE event SET mtime=julianday(%Q) WHERE objid=%d",
208213
zValue, rid);
209214
}
210215
--- src/tag.c
+++ src/tag.c
@@ -200,10 +200,15 @@
200 break;
201 }
202 }
203 if( zCol ){
204 db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
 
 
 
 
 
205 }
206 if( tagid==TAG_DATE ){
207 db_multi_exec("UPDATE event SET mtime=julianday(%Q) WHERE objid=%d",
208 zValue, rid);
209 }
210
--- src/tag.c
+++ src/tag.c
@@ -200,10 +200,15 @@
200 break;
201 }
202 }
203 if( zCol ){
204 db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid);
205 if( tagid==TAG_COMMENT ){
206 char *zCopy = mprintf("%s", zValue);
207 wiki_extract_links(zCopy, rid, 0, mtime, 1, WIKI_INLINE);
208 free(zCopy);
209 }
210 }
211 if( tagid==TAG_DATE ){
212 db_multi_exec("UPDATE event SET mtime=julianday(%Q) WHERE objid=%d",
213 zValue, rid);
214 }
215
+182 -2
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -620,11 +620,10 @@
620620
** Parse only Wiki links, return everything else as TOKEN_RAW.
621621
**
622622
** z points to the start of a token. Return the number of
623623
** characters in that token. Write the token type into *pTokenType.
624624
*/
625
-
626625
static int nextRawToken(const char *z, Renderer *p, int *pTokenType){
627626
int n;
628627
if( z[0]=='[' && (n = linkLength(z))>0 ){
629628
*pTokenType = TOKEN_LINK;
630629
return n;
@@ -778,11 +777,11 @@
778777
static void popStack(Renderer *p){
779778
if( p->nStack ){
780779
int iCode;
781780
p->nStack--;
782781
iCode = p->aStack[p->nStack].iCode;
783
- if( iCode!=MARKUP_DIV ){
782
+ if( iCode!=MARKUP_DIV && p->pOut ){
784783
blob_appendf(p->pOut, "</%s>", aMarkup[iCode].zName);
785784
}
786785
}
787786
}
788787
@@ -1447,5 +1446,186 @@
14471446
if( z[i]!='<' ) return 0;
14481447
blob_init(pTitle, &z[iStart], i-iStart);
14491448
blob_init(pTail, &z[i+8], -1);
14501449
return 1;
14511450
}
1451
+
1452
+/*
1453
+** Parse text looking for wiki hyperlinks in one of the formats:
1454
+**
1455
+** [target]
1456
+** [target|...]
1457
+**
1458
+** Where "target" can be either an artifact ID prefix or a wiki page
1459
+** name. For each such hyperlink found, add an entry to the
1460
+** backlink table.
1461
+*/
1462
+void wiki_extract_links(
1463
+ char *z, /* The wiki text from which to extract links */
1464
+ int srcid, /* srcid field for new BACKLINK table entries */
1465
+ int srctype, /* srctype field for new BACKLINK table entries */
1466
+ double mtime, /* mtime field for new BACKLINK table entries */
1467
+ int replaceFlag, /* True first delete prior BACKLINK entries */
1468
+ int flags /* wiki parsing flags */
1469
+){
1470
+ Renderer renderer;
1471
+ int tokenType;
1472
+ ParsedMarkup markup;
1473
+ int n;
1474
+ int inlineOnly;
1475
+ int wikiUseHtml = 0;
1476
+
1477
+ memset(&renderer, 0, sizeof(renderer));
1478
+ renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH;
1479
+ if( flags & WIKI_NOBLOCK ){
1480
+ renderer.state |= INLINE_MARKUP_ONLY;
1481
+ }
1482
+ if( db_get_int("wiki-use-html", 0) ){
1483
+ renderer.state |= WIKI_USE_HTML;
1484
+ wikiUseHtml = 1;
1485
+ }
1486
+ inlineOnly = (renderer.state & INLINE_MARKUP_ONLY)!=0;
1487
+ if( replaceFlag ){
1488
+ db_multi_exec("DELETE FROM backlink WHERE srctype=%d AND srcid=%d",
1489
+ srctype, srcid);
1490
+ }
1491
+
1492
+ while( z[0] ){
1493
+ if( wikiUseHtml ){
1494
+ n = nextRawToken(z, &renderer, &tokenType);
1495
+ }else{
1496
+ n = nextWikiToken(z, &renderer, &tokenType);
1497
+ }
1498
+ switch( tokenType ){
1499
+ case TOKEN_LINK: {
1500
+ char *zTarget;
1501
+ int i, c;
1502
+ char zLink[42];
1503
+
1504
+ zTarget = &z[1];
1505
+ for(i=0; zTarget[i] && zTarget[i]!='|' && zTarget[i]!=']'; i++){}
1506
+ while(i>1 && zTarget[i-1]==' '){ i--; }
1507
+ c = zTarget[i];
1508
+ zTarget[i] = 0;
1509
+ if( is_valid_uuid(zTarget) ){
1510
+ memcpy(zLink, zTarget, i+1);
1511
+ canonical16(zLink, i);
1512
+ db_multi_exec(
1513
+ "REPLACE INTO backlink(target,srctype,srcid,mtime)"
1514
+ "VALUES(%Q,%d,%d,%g)", zLink, srctype, srcid, mtime
1515
+ );
1516
+ }
1517
+ zTarget[i] = c;
1518
+ break;
1519
+ }
1520
+ case TOKEN_MARKUP: {
1521
+ const char *zId;
1522
+ int iDiv;
1523
+ parseMarkup(&markup, z);
1524
+
1525
+ /* Markup of the form </div id=ID> where there is a matching
1526
+ ** ID somewhere on the stack. Exit the verbatim if were are in
1527
+ ** it. Pop the stack up to the matching <div>. Discard the
1528
+ ** </div>
1529
+ */
1530
+ if( markup.iCode==MARKUP_DIV && markup.endTag &&
1531
+ (zId = markupId(&markup))!=0 &&
1532
+ (iDiv = findTagWithId(&renderer, MARKUP_DIV, zId))>=0
1533
+ ){
1534
+ if( renderer.inVerbatim ){
1535
+ renderer.inVerbatim = 0;
1536
+ renderer.state = renderer.preVerbState;
1537
+ }
1538
+ while( renderer.nStack>iDiv+1 ) popStack(&renderer);
1539
+ if( renderer.aStack[iDiv].allowWiki ){
1540
+ renderer.state |= ALLOW_WIKI;
1541
+ }else{
1542
+ renderer.state &= ~ALLOW_WIKI;
1543
+ }
1544
+ renderer.nStack--;
1545
+ }else
1546
+
1547
+ /* If within <verbatim id=ID> ignore everything other than
1548
+ ** </verbatim id=ID> and the </dev id=ID2> above.
1549
+ */
1550
+ if( renderer.inVerbatim ){
1551
+ if( endVerbatim(&renderer, &markup) ){
1552
+ renderer.inVerbatim = 0;
1553
+ renderer.state = renderer.preVerbState;
1554
+ }else{
1555
+ n = 1;
1556
+ }
1557
+ }else
1558
+
1559
+ /* Render invalid markup literally. The markup appears in the
1560
+ ** final output as plain text.
1561
+ */
1562
+ if( markup.iCode==MARKUP_INVALID ){
1563
+ n = 1;
1564
+ }else
1565
+
1566
+ /* If the markup is not font-change markup ignore it if the
1567
+ ** font-change-only flag is set.
1568
+ */
1569
+ if( (markup.iType&MUTYPE_FONT)==0 &&
1570
+ (renderer.state & FONT_MARKUP_ONLY)!=0 ){
1571
+ /* Do nothing */
1572
+ }else
1573
+
1574
+ if( markup.iCode==MARKUP_NOWIKI ){
1575
+ if( markup.endTag ){
1576
+ renderer.state |= ALLOW_WIKI;
1577
+ }else{
1578
+ renderer.state &= ~ALLOW_WIKI;
1579
+ }
1580
+ }else
1581
+
1582
+ /* Ignore block markup for in-line rendering.
1583
+ */
1584
+ if( inlineOnly && (markup.iType&MUTYPE_INLINE)==0 ){
1585
+ /* Do nothing */
1586
+ }else
1587
+
1588
+ /* Generate end-tags */
1589
+ if( markup.endTag ){
1590
+ popStackToTag(&renderer, markup.iCode);
1591
+ }else
1592
+
1593
+ /* Push <div> markup onto the stack together with the id=ID attribute.
1594
+ */
1595
+ if( markup.iCode==MARKUP_DIV ){
1596
+ pushStackWithId(&renderer, markup.iCode, markupId(&markup),
1597
+ (renderer.state & ALLOW_WIKI)!=0);
1598
+ }else
1599
+
1600
+ /* Enter <verbatim> processing. With verbatim enabled, all other
1601
+ ** markup other than the corresponding end-tag with the same ID is
1602
+ ** ignored.
1603
+ */
1604
+ if( markup.iCode==MARKUP_VERBATIM ){
1605
+ int vAttrIdx, vAttrDidAppend=0;
1606
+ renderer.zVerbatimId = 0;
1607
+ renderer.inVerbatim = 1;
1608
+ renderer.preVerbState = renderer.state;
1609
+ renderer.state &= ~ALLOW_WIKI;
1610
+ for (vAttrIdx = 0; vAttrIdx < markup.nAttr; vAttrIdx++){
1611
+ if( markup.aAttr[vAttrIdx].iACode == ATTR_ID ){
1612
+ renderer.zVerbatimId = markup.aAttr[0].zValue;
1613
+ }else if( markup.aAttr[vAttrIdx].iACode == ATTR_TYPE ){
1614
+ vAttrDidAppend=1;
1615
+ }
1616
+ }
1617
+ renderer.wantAutoParagraph = 0;
1618
+ }
1619
+
1620
+ /* Restore the input text to its original configuration
1621
+ */
1622
+ unparseMarkup(&markup);
1623
+ break;
1624
+ }
1625
+ default: {
1626
+ break;
1627
+ }
1628
+ }
1629
+ z += n;
1630
+ }
1631
+}
14521632
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -620,11 +620,10 @@
620 ** Parse only Wiki links, return everything else as TOKEN_RAW.
621 **
622 ** z points to the start of a token. Return the number of
623 ** characters in that token. Write the token type into *pTokenType.
624 */
625
626 static int nextRawToken(const char *z, Renderer *p, int *pTokenType){
627 int n;
628 if( z[0]=='[' && (n = linkLength(z))>0 ){
629 *pTokenType = TOKEN_LINK;
630 return n;
@@ -778,11 +777,11 @@
778 static void popStack(Renderer *p){
779 if( p->nStack ){
780 int iCode;
781 p->nStack--;
782 iCode = p->aStack[p->nStack].iCode;
783 if( iCode!=MARKUP_DIV ){
784 blob_appendf(p->pOut, "</%s>", aMarkup[iCode].zName);
785 }
786 }
787 }
788
@@ -1447,5 +1446,186 @@
1447 if( z[i]!='<' ) return 0;
1448 blob_init(pTitle, &z[iStart], i-iStart);
1449 blob_init(pTail, &z[i+8], -1);
1450 return 1;
1451 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1452
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -620,11 +620,10 @@
620 ** Parse only Wiki links, return everything else as TOKEN_RAW.
621 **
622 ** z points to the start of a token. Return the number of
623 ** characters in that token. Write the token type into *pTokenType.
624 */
 
625 static int nextRawToken(const char *z, Renderer *p, int *pTokenType){
626 int n;
627 if( z[0]=='[' && (n = linkLength(z))>0 ){
628 *pTokenType = TOKEN_LINK;
629 return n;
@@ -778,11 +777,11 @@
777 static void popStack(Renderer *p){
778 if( p->nStack ){
779 int iCode;
780 p->nStack--;
781 iCode = p->aStack[p->nStack].iCode;
782 if( iCode!=MARKUP_DIV && p->pOut ){
783 blob_appendf(p->pOut, "</%s>", aMarkup[iCode].zName);
784 }
785 }
786 }
787
@@ -1447,5 +1446,186 @@
1446 if( z[i]!='<' ) return 0;
1447 blob_init(pTitle, &z[iStart], i-iStart);
1448 blob_init(pTail, &z[i+8], -1);
1449 return 1;
1450 }
1451
1452 /*
1453 ** Parse text looking for wiki hyperlinks in one of the formats:
1454 **
1455 ** [target]
1456 ** [target|...]
1457 **
1458 ** Where "target" can be either an artifact ID prefix or a wiki page
1459 ** name. For each such hyperlink found, add an entry to the
1460 ** backlink table.
1461 */
1462 void wiki_extract_links(
1463 char *z, /* The wiki text from which to extract links */
1464 int srcid, /* srcid field for new BACKLINK table entries */
1465 int srctype, /* srctype field for new BACKLINK table entries */
1466 double mtime, /* mtime field for new BACKLINK table entries */
1467 int replaceFlag, /* True first delete prior BACKLINK entries */
1468 int flags /* wiki parsing flags */
1469 ){
1470 Renderer renderer;
1471 int tokenType;
1472 ParsedMarkup markup;
1473 int n;
1474 int inlineOnly;
1475 int wikiUseHtml = 0;
1476
1477 memset(&renderer, 0, sizeof(renderer));
1478 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH;
1479 if( flags & WIKI_NOBLOCK ){
1480 renderer.state |= INLINE_MARKUP_ONLY;
1481 }
1482 if( db_get_int("wiki-use-html", 0) ){
1483 renderer.state |= WIKI_USE_HTML;
1484 wikiUseHtml = 1;
1485 }
1486 inlineOnly = (renderer.state & INLINE_MARKUP_ONLY)!=0;
1487 if( replaceFlag ){
1488 db_multi_exec("DELETE FROM backlink WHERE srctype=%d AND srcid=%d",
1489 srctype, srcid);
1490 }
1491
1492 while( z[0] ){
1493 if( wikiUseHtml ){
1494 n = nextRawToken(z, &renderer, &tokenType);
1495 }else{
1496 n = nextWikiToken(z, &renderer, &tokenType);
1497 }
1498 switch( tokenType ){
1499 case TOKEN_LINK: {
1500 char *zTarget;
1501 int i, c;
1502 char zLink[42];
1503
1504 zTarget = &z[1];
1505 for(i=0; zTarget[i] && zTarget[i]!='|' && zTarget[i]!=']'; i++){}
1506 while(i>1 && zTarget[i-1]==' '){ i--; }
1507 c = zTarget[i];
1508 zTarget[i] = 0;
1509 if( is_valid_uuid(zTarget) ){
1510 memcpy(zLink, zTarget, i+1);
1511 canonical16(zLink, i);
1512 db_multi_exec(
1513 "REPLACE INTO backlink(target,srctype,srcid,mtime)"
1514 "VALUES(%Q,%d,%d,%g)", zLink, srctype, srcid, mtime
1515 );
1516 }
1517 zTarget[i] = c;
1518 break;
1519 }
1520 case TOKEN_MARKUP: {
1521 const char *zId;
1522 int iDiv;
1523 parseMarkup(&markup, z);
1524
1525 /* Markup of the form </div id=ID> where there is a matching
1526 ** ID somewhere on the stack. Exit the verbatim if were are in
1527 ** it. Pop the stack up to the matching <div>. Discard the
1528 ** </div>
1529 */
1530 if( markup.iCode==MARKUP_DIV && markup.endTag &&
1531 (zId = markupId(&markup))!=0 &&
1532 (iDiv = findTagWithId(&renderer, MARKUP_DIV, zId))>=0
1533 ){
1534 if( renderer.inVerbatim ){
1535 renderer.inVerbatim = 0;
1536 renderer.state = renderer.preVerbState;
1537 }
1538 while( renderer.nStack>iDiv+1 ) popStack(&renderer);
1539 if( renderer.aStack[iDiv].allowWiki ){
1540 renderer.state |= ALLOW_WIKI;
1541 }else{
1542 renderer.state &= ~ALLOW_WIKI;
1543 }
1544 renderer.nStack--;
1545 }else
1546
1547 /* If within <verbatim id=ID> ignore everything other than
1548 ** </verbatim id=ID> and the </dev id=ID2> above.
1549 */
1550 if( renderer.inVerbatim ){
1551 if( endVerbatim(&renderer, &markup) ){
1552 renderer.inVerbatim = 0;
1553 renderer.state = renderer.preVerbState;
1554 }else{
1555 n = 1;
1556 }
1557 }else
1558
1559 /* Render invalid markup literally. The markup appears in the
1560 ** final output as plain text.
1561 */
1562 if( markup.iCode==MARKUP_INVALID ){
1563 n = 1;
1564 }else
1565
1566 /* If the markup is not font-change markup ignore it if the
1567 ** font-change-only flag is set.
1568 */
1569 if( (markup.iType&MUTYPE_FONT)==0 &&
1570 (renderer.state & FONT_MARKUP_ONLY)!=0 ){
1571 /* Do nothing */
1572 }else
1573
1574 if( markup.iCode==MARKUP_NOWIKI ){
1575 if( markup.endTag ){
1576 renderer.state |= ALLOW_WIKI;
1577 }else{
1578 renderer.state &= ~ALLOW_WIKI;
1579 }
1580 }else
1581
1582 /* Ignore block markup for in-line rendering.
1583 */
1584 if( inlineOnly && (markup.iType&MUTYPE_INLINE)==0 ){
1585 /* Do nothing */
1586 }else
1587
1588 /* Generate end-tags */
1589 if( markup.endTag ){
1590 popStackToTag(&renderer, markup.iCode);
1591 }else
1592
1593 /* Push <div> markup onto the stack together with the id=ID attribute.
1594 */
1595 if( markup.iCode==MARKUP_DIV ){
1596 pushStackWithId(&renderer, markup.iCode, markupId(&markup),
1597 (renderer.state & ALLOW_WIKI)!=0);
1598 }else
1599
1600 /* Enter <verbatim> processing. With verbatim enabled, all other
1601 ** markup other than the corresponding end-tag with the same ID is
1602 ** ignored.
1603 */
1604 if( markup.iCode==MARKUP_VERBATIM ){
1605 int vAttrIdx, vAttrDidAppend=0;
1606 renderer.zVerbatimId = 0;
1607 renderer.inVerbatim = 1;
1608 renderer.preVerbState = renderer.state;
1609 renderer.state &= ~ALLOW_WIKI;
1610 for (vAttrIdx = 0; vAttrIdx < markup.nAttr; vAttrIdx++){
1611 if( markup.aAttr[vAttrIdx].iACode == ATTR_ID ){
1612 renderer.zVerbatimId = markup.aAttr[0].zValue;
1613 }else if( markup.aAttr[vAttrIdx].iACode == ATTR_TYPE ){
1614 vAttrDidAppend=1;
1615 }
1616 }
1617 renderer.wantAutoParagraph = 0;
1618 }
1619
1620 /* Restore the input text to its original configuration
1621 */
1622 unparseMarkup(&markup);
1623 break;
1624 }
1625 default: {
1626 break;
1627 }
1628 }
1629 z += n;
1630 }
1631 }
1632

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button