Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Merge in the ability to add submenu buttons on embedded documentation using hyperlinks with the "button" class. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
18c310afd84c5c9b60652bc51718ed54 |
| User & Date: | drh 2012-10-22 13:38:54.779 |
Context
|
2012-10-22
| ||
| 17:29 | Merge the changes to use various UTF encodings for win32 check-in comment editor into trunk. ... (check-in: cc01ec5094 user: drh tags: trunk) | |
| 14:56 | merge trunk ... (Closed-Leaf check-in: c7703868b3 user: jan.nijtmans tags: use-utf8-in-win-external-editor) | |
| 13:38 | Merge in the ability to add submenu buttons on embedded documentation using hyperlinks with the "button" class. ... (check-in: 18c310afd8 user: drh tags: trunk) | |
| 13:23 | Merge the changes to show unresolved conflicts in "fossil status" and to prevent committing unresolved conflicts. ... (check-in: 7d34d1748a user: drh tags: trunk) | |
|
2012-10-19
| ||
| 18:35 | Add a mention of the ability to do dynamic loading of Tcl to the change log. ... (Closed-Leaf check-in: 5678565bec user: drh tags: embedded-doc-buttons) | |
Changes
Changes to src/doc.c.
| ︙ | ︙ | |||
487 488 489 490 491 492 493 |
" FROM blob WHERE rid=%d", vid));
Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
" WHERE objid=%d AND type='ci'", vid));
if( fossil_strcmp(zMime, "application/x-fossil-wiki")==0 ){
Blob title, tail;
if( wiki_find_title(&filebody, &title, &tail) ){
style_header(blob_str(&title));
| | | | 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 |
" FROM blob WHERE rid=%d", vid));
Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
" WHERE objid=%d AND type='ci'", vid));
if( fossil_strcmp(zMime, "application/x-fossil-wiki")==0 ){
Blob title, tail;
if( wiki_find_title(&filebody, &title, &tail) ){
style_header(blob_str(&title));
wiki_convert(&tail, 0, WIKI_BUTTONS);
}else{
style_header("Documentation");
wiki_convert(&filebody, 0, WIKI_BUTTONS);
}
style_footer();
}else if( fossil_strcmp(zMime, "text/plain")==0 ){
style_header("Documentation");
@ <blockquote><pre>
@ %h(blob_str(&filebody))
@ </pre></blockquote>
|
| ︙ | ︙ |
Changes to src/wikiformat.c.
| ︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* ** Allowed wiki transformation operations */ #define WIKI_NOFOLLOW 0x001 #define WIKI_HTML 0x002 #define WIKI_INLINE 0x004 /* Do not surround with <p>..</p> */ #define WIKI_NOBLOCK 0x008 /* No block markup of any kind */ #endif /* ** These are the only markup attributes allowed. */ #define ATTR_ALIGN 1 | > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | /* ** Allowed wiki transformation operations */ #define WIKI_NOFOLLOW 0x001 #define WIKI_HTML 0x002 #define WIKI_INLINE 0x004 /* Do not surround with <p>..</p> */ #define WIKI_NOBLOCK 0x008 /* No block markup of any kind */ #define WIKI_BUTTONS 0x010 /* Allow sub-menu buttons */ #endif /* ** These are the only markup attributes allowed. */ #define ATTR_ALIGN 1 |
| ︙ | ︙ | |||
376 377 378 379 380 381 382 | #define TOKEN_NUM_LI 7 /* " # " */ #define TOKEN_ENUM 8 /* " \(?\d+[.)]? " */ #define TOKEN_INDENT 9 /* " " */ #define TOKEN_RAW 10 /* Output exactly (used when wiki-use-html==1) */ #define TOKEN_TEXT 11 /* None of the above */ /* | | | | | | | | | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
#define TOKEN_NUM_LI 7 /* " # " */
#define TOKEN_ENUM 8 /* " \(?\d+[.)]? " */
#define TOKEN_INDENT 9 /* " " */
#define TOKEN_RAW 10 /* Output exactly (used when wiki-use-html==1) */
#define TOKEN_TEXT 11 /* None of the above */
/*
** 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 FONT_MARKUP_ONLY 0x0080000 /* Only allow MUTYPE_FONT markup */
#define INLINE_MARKUP_ONLY 0x0100000 /* Allow only "inline" markup */
#define IN_LIST 0x0200000 /* Within wiki <ul> or <ol> */
#define WIKI_USE_HTML 0x0400000 /* wiki-use-html option = on */
/*
** Current state of the rendering engine
*/
typedef struct Renderer Renderer;
struct Renderer {
Blob *pOut; /* Output appended to this blob */
|
| ︙ | ︙ | |||
823 824 825 826 827 828 829 |
if( z==0 ) continue;
n = strlen(z);
z[n] = p->aAttr[i].cTerm;
}
}
/*
| | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 |
if( z==0 ) continue;
n = strlen(z);
z[n] = p->aAttr[i].cTerm;
}
}
/*
** Return the value of attribute attrId. Return NULL if there is no
** ID attribute.
*/
static const char *attributeValue(ParsedMarkup *p, int attrId){
int i;
for(i=0; i<p->nAttr; i++){
if( p->aAttr[i].iACode==attrId ){
return p->aAttr[i].zValue;
}
}
return 0;
}
/*
** Return the ID attribute for markup. Return NULL if there is no
** ID attribute.
*/
static const char *markupId(ParsedMarkup *p){
return attributeValue(p, ATTR_ID);
}
/*
** Check markup pMarkup to see if it is a hyperlink with class "button"
** that is follows by simple text and an </a> only. Example:
**
** <a class="button" href="../index.wiki">Index</a>
**
** If the markup matches this pattern, and if the WIKI_BUTTONS flag was
** passed to wiki_convert(), then transform this link into a submenu
** button, skip the text, and set *pN equal to the total length of the
** text through the end of </a> and return true. If the markup does
** not match or if WIKI_BUTTONS is not set, then make no changes to *pN
** and return false.
*/
static int isButtonHyperlink(
Renderer *p, /* Renderer state */
ParsedMarkup *pMarkup, /* Potential button markup */
const char *z, /* Complete text of Wiki */
int *pN /* Characters of z[] consumed */
){
const char *zClass;
const char *zHref;
char *zTag;
int i, j;
if( (p->state & WIKI_BUTTONS)==0 ) return 0;
zClass = attributeValue(pMarkup, ATTR_CLASS);
if( zClass==0 ) return 0;
if( fossil_strcmp(zClass, "button")!=0 ) return 0;
zHref = attributeValue(pMarkup, ATTR_HREF);
if( zHref==0 ) return 0;
i = *pN;
while( z[i] && z[i]!='<' ){ i++; }
if( fossil_strnicmp(&z[i], "</a>",4)!=0 ) return 0;
for(j=*pN; fossil_isspace(z[j]); j++){}
zTag = mprintf("%.*s", i-j, &z[j]);
j = (int)strlen(zTag);
while( j>0 && fossil_isspace(zTag[j-1]) ){ j--; }
if( j==0 ) return 0;
style_submenu_element(zTag, zTag, "%s", zHref);
*pN = i+4;
return 1;
}
/*
** Pop a single element off of the stack. As the element is popped,
** output its end tag if it is not a </div> tag.
*/
static void popStack(Renderer *p){
if( p->nStack ){
|
| ︙ | ︙ | |||
1451 1452 1453 1454 1455 1456 1457 |
blob_append(p->pOut, "<tr>", 4);
}
pushStack(p, markup.iCode);
renderMarkup(p->pOut, &markup);
}
}else
if( markup.iType==MUTYPE_HYPERLINK ){
| > | | | | > | 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 |
blob_append(p->pOut, "<tr>", 4);
}
pushStack(p, markup.iCode);
renderMarkup(p->pOut, &markup);
}
}else
if( markup.iType==MUTYPE_HYPERLINK ){
if( !isButtonHyperlink(p, &markup, z, &n) ){
popStackToTag(p, markup.iCode);
startAutoParagraph(p);
renderMarkup(p->pOut, &markup);
pushStack(p, markup.iCode);
}
}else
{
if( markup.iType==MUTYPE_FONT ){
startAutoParagraph(p);
}else if( markup.iType==MUTYPE_BLOCK || markup.iType==MUTYPE_LIST ){
p->wantAutoParagraph = 0;
}
|
| ︙ | ︙ | |||
1506 1507 1508 1509 1510 1511 1512 |
** reply.
*/
void wiki_convert(Blob *pIn, Blob *pOut, int flags){
char *z;
Renderer renderer;
memset(&renderer, 0, sizeof(renderer));
| | | 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 |
** reply.
*/
void wiki_convert(Blob *pIn, Blob *pOut, int flags){
char *z;
Renderer renderer;
memset(&renderer, 0, sizeof(renderer));
renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH|flags;
if( flags & WIKI_NOBLOCK ){
renderer.state |= INLINE_MARKUP_ONLY;
}
if( flags & WIKI_INLINE ){
renderer.wantAutoParagraph = 0;
}else{
renderer.wantAutoParagraph = 1;
|
| ︙ | ︙ | |||
1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 |
}
blob_append(renderer.pOut, "\n", 1);
free(renderer.aStack);
}
/*
** COMMAND: test-wiki-render
*/
void test_wiki_render(void){
Blob in, out;
if( g.argc!=3 ) usage("FILE");
blob_zero(&out);
blob_read_from_file(&in, g.argv[2]);
| > > > > > > > > | | 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 |
}
blob_append(renderer.pOut, "\n", 1);
free(renderer.aStack);
}
/*
** COMMAND: test-wiki-render
**
** %fossil test-wiki-render FILE [OPTIONS]
**
** Options:
** --buttons Set the WIKI_BUTTONS flag
*/
void test_wiki_render(void){
Blob in, out;
int flags = 0;
if( find_option("buttons",0,0)!=0 ) flags |= WIKI_BUTTONS;
verify_all_options();
if( g.argc!=3 ) usage("FILE");
blob_zero(&out);
blob_read_from_file(&in, g.argv[2]);
wiki_convert(&in, &out, flags);
blob_write_to_file(&out, "-");
}
/*
** Search for a <title>...</title> at the beginning of a wiki page.
** Return true (nonzero) if a title is found. Return zero if there is
** not title.
|
| ︙ | ︙ |