Changes On Branch embedded-doc-buttons
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch embedded-doc-buttons Excluding Merge-Ins

This is equivalent to a diff from 2116906fb1 to 5678565bec

2012-10-22
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
2012-10-19
18:36
Add a mention of the ability to do dynamic loading of Tcl to the change log. (This change originally checked into the wrong branch.) check-in: e40e4faabb user: drh tags: trunk
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
18:33
All submenu buttons on embedded documentation pages using markup of the form: <a class="button" href="...">LABEL</a>. check-in: 563b3ccb7b user: drh tags: embedded-doc-buttons
17:34
Simple changes that allows embedded documentation *.wiki files to contain unrestricted HTML. This is on a branch because I don't believe we want to go this way, but I might change my mind later. Leaf check-in: 463df97c06 user: drh tags: full-html-for-embedded-docs
17:04
Fix a typo in the Style document. check-in: 2116906fb1 user: drh tags: trunk
15:29
Further edits to the change log for 1.24. check-in: 5ea7a3ec56 user: drh tags: trunk

Changes to src/doc.c.

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, 0);
    }else{
      style_header("Documentation");
      wiki_convert(&filebody, 0, 0);
    }
    style_footer();
  }else if( fossil_strcmp(zMime, "text/plain")==0 ){
    style_header("Documentation");
    @ <blockquote><pre>
    @ %h(blob_str(&filebody))
    @ </pre></blockquote>






|


|







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
...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
...
823
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
....
1451
1452
1453
1454
1455
1456
1457

1458
1459
1460
1461

1462
1463
1464
1465
1466
1467
1468
....
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
....
1536
1537
1538
1539
1540
1541
1542





1543
1544
1545



1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
/*
** 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
................................................................................
#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
*/
#define AT_NEWLINE          0x001  /* At start of a line */
#define AT_PARAGRAPH        0x002  /* At start of a paragraph */
#define ALLOW_WIKI          0x004  /* Allow wiki markup */
#define FONT_MARKUP_ONLY    0x008  /* Only allow MUTYPE_FONT markup */
#define INLINE_MARKUP_ONLY  0x010  /* Allow only "inline" markup */
#define IN_LIST             0x020  /* Within wiki <ul> or <ol> */
#define WIKI_USE_HTML       0x040  /* wiki-use-html option = on */

/*
** Current state of the rendering engine
*/
typedef struct Renderer Renderer;
struct Renderer {
  Blob *pOut;                 /* Output appended to this blob */
................................................................................
    if( z==0 ) continue;
    n = strlen(z);
    z[n] = p->aAttr[i].cTerm;
  }
}

/*
** Return the ID attribute for markup.  Return NULL if there is no
** ID attribute.
*/
static const char *markupId(ParsedMarkup *p){
  int i;
  for(i=0; i<p->nAttr; i++){
    if( p->aAttr[i].iACode==ATTR_ID ){
      return p->aAttr[i].zValue;
    }
  }
  return 0;
}



















































/*
** 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 ){
................................................................................
              blob_append(p->pOut, "<tr>", 4);
            }
            pushStack(p, markup.iCode);
            renderMarkup(p->pOut, &markup);
          }
        }else
        if( markup.iType==MUTYPE_HYPERLINK ){

          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;
          }
................................................................................
** 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;
  if( flags & WIKI_NOBLOCK ){
    renderer.state |= INLINE_MARKUP_ONLY;
  }
  if( flags & WIKI_INLINE ){
    renderer.wantAutoParagraph = 0;
  }else{
    renderer.wantAutoParagraph = 1;
................................................................................
  }
  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]);
  wiki_convert(&in, &out, 0);
  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.






>







 







|

|
|
|
|
|
|
|







 







|


|


|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
|
|
|
|
>







 







|







 







>
>
>
>
>



>
>
>



|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
...
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
....
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
....
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
....
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
/*
** 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
................................................................................
#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 */
................................................................................
    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 ){
................................................................................
              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;
          }
................................................................................
** 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;
................................................................................
  }
  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.

Changes to www/changes.wiki.

60
61
62
63
64
65
66



67
68
69
70
71
72
73
     merge to occur even if it would be a no-op.  This is sometimes useful for
     documentation purposes.
  *  Add another built-in skin:  "Enhanced Default".  Other minor tweaks to
     the existing skins.
  *  Add the "urllist" webpage, showing a list of URLs by which a server
     instance of Fossil has been accessed.  Requires "Administrator" privileges.
     A link is on the "Setup" main page.



  *  Merge the latest SQLite changes from upstream.
  *  Lots of minor bug fixes.

<h2>Changes For Version 1.23 (2012-08-08)</h2>
  *  The default checkout database name is now ".fslckout" instead of
     "_FOSSIL_" on unix.  Both names continue to work.
  *  Added the "fossil all changes" command






>
>
>







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
     merge to occur even if it would be a no-op.  This is sometimes useful for
     documentation purposes.
  *  Add another built-in skin:  "Enhanced Default".  Other minor tweaks to
     the existing skins.
  *  Add the "urllist" webpage, showing a list of URLs by which a server
     instance of Fossil has been accessed.  Requires "Administrator" privileges.
     A link is on the "Setup" main page.
  *  Enable dynamic loading of the Tcl runtime for installations that want
     to use Tcl as part of their configuration.  This reduces the size of
     the Fossil binary and allows any version of Tcl 8.4 or later to be used.
  *  Merge the latest SQLite changes from upstream.
  *  Lots of minor bug fixes.

<h2>Changes For Version 1.23 (2012-08-08)</h2>
  *  The default checkout database name is now ".fslckout" instead of
     "_FOSSIL_" on unix.  Both names continue to work.
  *  Added the "fossil all changes" command