Overview
SHA1 Hash: | f08adf3d58c4afc0bc526618440f0e460278e3b1 |
---|---|
Date: | 2007-10-28 23:27:12 |
User: | drh |
Comment: | Added a "wiki" link to the main menu. Added built-in description of wiki formatting rules. Added a wiki "homepage" that displays when the "wiki" URI is used without a pagename. Added support for a wiki sandbox that does not save to the repository. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/style.c from [dd33d05f02] to [7ae579f21d].
@@ -95,10 +95,13 @@ @ <div id="main-menu"> @ <a href="%s(g.zBaseURL)/home">Home</a> if( g.okRead ){ @ | <a href="%s(g.zBaseURL)/leaves">Leaves</a> @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a> + } + if( g.okRdWiki ){ + @ | <a href="%s(g.zBaseURL)/wiki">Wiki</a> } #if 0 @ | <font color="#888888">Search</font> @ | <font color="#888888">Ticket</font> @ | <font color="#888888">Reports</font>
Modified src/wiki.c from [fbea7b5b38] to [06781e499d].
@@ -98,16 +98,25 @@ @ will be displayed in place of this message. style_footer(); } /* +** Return true if the given pagename is the name of the sandbox +*/ +static int is_sandbox(const char *zPagename){ + return strcasecmp(zPagename,"sandbox")==0 || + strcasecmp(zPagename,"sand box")==0; +} + +/* ** WEBPAGE: wiki ** URL: /wiki?name=PAGENAME */ void wiki_page(void){ char *zTag; int rid; + int isSandbox; Blob wiki; Manifest m; const char *zPageName; char *zHtmlPageName; char *zBody = mprintf("%s","<i>Empty Page</i>"); @@ -114,49 +123,67 @@ login_check_credentials(); if( !g.okRdWiki ){ login_needed(); return; } zPageName = P("name"); if( zPageName==0 ){ - wcontent_page(); + style_header("Wiki"); + @ <ul> + @ <li> <a href="%s(g.zBaseURL)/timeline?y=w">Recent changes</a> to wiki + @ pages. </li> + @ <li> <a href="%s(g.zBaseURL)/wiki_rules">Formatting rules</a> for + @ wiki.</li> + @ <li> Use the <a href="%s(g.zBaseURL)/wiki?name=Sandbox">Sandbox</a> + @ to experiment.</li> + @ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a> + @ available on this server.</li> + @ </ul> + style_footer(); return; } if( check_name(zPageName) ) return; - zTag = mprintf("wiki-%s", zPageName); - rid = db_int(0, - "SELECT rid FROM tagxref" - " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" - " ORDER BY mtime DESC", zTag - ); - free(zTag); - memset(&m, 0, sizeof(m)); - blob_zero(&m.content); - if( rid ){ - Blob content; - content_get(rid, &content); - manifest_parse(&m, &content); - if( m.type==CFTYPE_WIKI ){ - zBody = m.zWiki; + isSandbox = is_sandbox(zPageName); + if( isSandbox ){ + zBody = db_get("sandbox",zBody); + }else{ + zTag = mprintf("wiki-%s", zPageName); + rid = db_int(0, + "SELECT rid FROM tagxref" + " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" + " ORDER BY mtime DESC", zTag + ); + free(zTag); + memset(&m, 0, sizeof(m)); + blob_zero(&m.content); + if( rid ){ + Blob content; + content_get(rid, &content); + manifest_parse(&m, &content); + if( m.type==CFTYPE_WIKI ){ + zBody = m.zWiki; + } } } - if( (rid && g.okWrWiki) || (!rid && g.okNewWiki) ){ + if( isSandbox || (rid && g.okWrWiki) || (!rid && g.okNewWiki) ){ style_submenu_element("Edit", "Edit Wiki Page", mprintf("%s/wikiedit?name=%T", g.zTop, zPageName)); } - if( rid && g.okApndWiki ){ + if( isSandbox || (rid && g.okApndWiki) ){ style_submenu_element("Append", "Add A Comment", mprintf("%s/wikiappend?name=%T", g.zTop, zPageName)); } - if( g.okHistory ){ + if( !isSandbox && g.okHistory ){ style_submenu_element("History", "History", mprintf("%s/whistory?name=%T", g.zTop, zPageName)); } zHtmlPageName = mprintf("%h", zPageName); style_header(zHtmlPageName); blob_init(&wiki, zBody, -1); wiki_convert(&wiki, 0, 0); blob_reset(&wiki); - manifest_clear(&m); + if( !isSandbox ){ + manifest_clear(&m); + } style_footer(); } /* ** WEBPAGE: wikiedit @@ -163,10 +190,11 @@ ** URL: /wikiedit?name=PAGENAME */ void wikiedit_page(void){ char *zTag; int rid; + int isSandbox; Blob wiki; Manifest m; const char *zPageName; char *zHtmlPageName; int n; @@ -177,59 +205,70 @@ zBody = mprintf("%s", zBody); } login_check_credentials(); zPageName = PD("name",""); if( check_name(zPageName) ) return; - zTag = mprintf("wiki-%s", zPageName); - rid = db_int(0, - "SELECT rid FROM tagxref" - " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" - " ORDER BY mtime DESC", zTag - ); - free(zTag); - if( (rid && !g.okWrWiki) || (!rid && !g.okNewWiki) ){ - login_needed(); - return; - } - memset(&m, 0, sizeof(m)); - blob_zero(&m.content); - if( rid && zBody==0 ){ - Blob content; - content_get(rid, &content); - manifest_parse(&m, &content); - if( m.type==CFTYPE_WIKI ){ - zBody = m.zWiki; + isSandbox = is_sandbox(zPageName); + if( isSandbox ){ + if( zBody==0 ){ + zBody = db_get("sandbox",""); + } + }else{ + zTag = mprintf("wiki-%s", zPageName); + rid = db_int(0, + "SELECT rid FROM tagxref" + " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" + " ORDER BY mtime DESC", zTag + ); + free(zTag); + if( (rid && !g.okWrWiki) || (!rid && !g.okNewWiki) ){ + login_needed(); + return; + } + memset(&m, 0, sizeof(m)); + blob_zero(&m.content); + if( rid && zBody==0 ){ + Blob content; + content_get(rid, &content); + manifest_parse(&m, &content); + if( m.type==CFTYPE_WIKI ){ + zBody = m.zWiki; + } } } if( P("submit")!=0 && zBody!=0 ){ char *zDate; Blob cksum; int nrid; blob_zero(&wiki); db_begin_transaction(); - zDate = db_text(0, "SELECT datetime('now')"); - zDate[10] = 'T'; - blob_appendf(&wiki, "D %s\n", zDate); - free(zDate); - blob_appendf(&wiki, "L %F\n", zPageName); - if( rid ){ - char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); - blob_appendf(&wiki, "P %s\n", zUuid); - free(zUuid); - } - if( g.zLogin ){ - blob_appendf(&wiki, "U %F\n", g.zLogin); - } - blob_appendf(&wiki, "W %d\n%s\n", strlen(zBody), zBody); - md5sum_blob(&wiki, &cksum); - blob_appendf(&wiki, "Z %b\n", &cksum); - blob_reset(&cksum); - nrid = content_put(&wiki, 0, 0); - db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid); - manifest_crosslink(nrid, &wiki); - blob_reset(&wiki); - content_deltify(rid, nrid, 0); + if( isSandbox ){ + db_set("sandbox",zBody,0); + }else{ + zDate = db_text(0, "SELECT datetime('now')"); + zDate[10] = 'T'; + blob_appendf(&wiki, "D %s\n", zDate); + free(zDate); + blob_appendf(&wiki, "L %F\n", zPageName); + if( rid ){ + char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); + blob_appendf(&wiki, "P %s\n", zUuid); + free(zUuid); + } + if( g.zLogin ){ + blob_appendf(&wiki, "U %F\n", g.zLogin); + } + blob_appendf(&wiki, "W %d\n%s\n", strlen(zBody), zBody); + md5sum_blob(&wiki, &cksum); + blob_appendf(&wiki, "Z %b\n", &cksum); + blob_reset(&cksum); + nrid = content_put(&wiki, 0, 0); + db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid); + manifest_crosslink(nrid, &wiki); + blob_reset(&wiki); + content_deltify(rid, nrid, 0); + } db_end_transaction(0); cgi_redirectf("wiki?name=%T", zPageName); } if( P("cancel")!=0 ){ cgi_redirectf("wiki?name=%T", zPageName); @@ -260,11 +299,13 @@ @ <br> @ <input type="submit" name="preview" value="Preview Your Changes"> @ <input type="submit" name="submit" value="Apply These Changes"> @ <input type="submit" name="cancel" value="Cancel"> @ </form> - manifest_clear(&m); + if( !isSandbox ){ + manifest_clear(&m); + } style_footer(); } /* ** Append the wiki text for an remark to the end of the given BLOB. @@ -273,44 +314,48 @@ char *zDate; const char *zUser; const char *zRemark; zDate = db_text(0, "SELECT datetime('now')"); - blob_appendf(p, "On %s UTC %h", zDate, g.zLogin); + blob_appendf(p, "\n\n<hr><i>On %s UTC %h", zDate, g.zLogin); free(zDate); zUser = PD("u",g.zLogin); if( zUser[0] && strcmp(zUser,g.zLogin) ){ blob_appendf(p, " (claiming to be %h)", zUser); } zRemark = PD("r",""); - blob_appendf(p, " added:\n\n%s", zRemark); + blob_appendf(p, " added:</i><br />\n%s", zRemark); } /* ** WEBPAGE: wikiappend ** URL: /wikiappend?name=PAGENAME */ void wikiappend_page(void){ char *zTag; int rid; + int isSandbox; const char *zPageName; char *zHtmlPageName; const char *zUser; login_check_credentials(); zPageName = PD("name",""); if( check_name(zPageName) ) return; - zTag = mprintf("wiki-%s", zPageName); - rid = db_int(0, - "SELECT rid FROM tagxref" - " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" - " ORDER BY mtime DESC", zTag - ); - free(zTag); - if( !rid ){ - cgi_redirect("index"); - return; + isSandbox = is_sandbox(zPageName); + if( !isSandbox ){ + zTag = mprintf("wiki-%s", zPageName); + rid = db_int(0, + "SELECT rid FROM tagxref" + " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" + " ORDER BY mtime DESC", zTag + ); + free(zTag); + if( !rid ){ + cgi_redirect("index"); + return; + } } if( !g.okApndWiki ){ login_needed(); return; } @@ -321,43 +366,49 @@ Blob body; Blob content; Blob wiki; Manifest m; - content_get(rid, &content); - manifest_parse(&m, &content); blob_zero(&body); - if( m.type==CFTYPE_WIKI ){ - blob_appendf(&body, m.zWiki, -1); - } - manifest_clear(&m); - blob_zero(&wiki); - db_begin_transaction(); - zDate = db_text(0, "SELECT datetime('now')"); - zDate[10] = 'T'; - blob_appendf(&wiki, "D %s\n", zDate); - blob_appendf(&wiki, "L %F\n", zPageName); - if( rid ){ - char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); - blob_appendf(&wiki, "P %s\n", zUuid); - free(zUuid); - } - if( g.zLogin ){ - blob_appendf(&wiki, "U %F\n", g.zLogin); - } - blob_appendf(&body, "\n<hr>\n"); - appendRemark(&body); - blob_appendf(&wiki, "W %d\n%s\n", blob_size(&body), blob_str(&body)); - md5sum_blob(&wiki, &cksum); - blob_appendf(&wiki, "Z %b\n", &cksum); - blob_reset(&cksum); - nrid = content_put(&wiki, 0, 0); - db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid); - manifest_crosslink(nrid, &wiki); - blob_reset(&wiki); - content_deltify(rid, nrid, 0); - db_end_transaction(0); + if( isSandbox ){ + blob_appendf(&body, db_get("sandbox","")); + appendRemark(&body); + db_set("sandbox", blob_str(&body), 0); + }else{ + content_get(rid, &content); + manifest_parse(&m, &content); + if( m.type==CFTYPE_WIKI ){ + blob_appendf(&body, m.zWiki, -1); + } + manifest_clear(&m); + blob_zero(&wiki); + db_begin_transaction(); + zDate = db_text(0, "SELECT datetime('now')"); + zDate[10] = 'T'; + blob_appendf(&wiki, "D %s\n", zDate); + blob_appendf(&wiki, "L %F\n", zPageName); + if( rid ){ + char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); + blob_appendf(&wiki, "P %s\n", zUuid); + free(zUuid); + } + if( g.zLogin ){ + blob_appendf(&wiki, "U %F\n", g.zLogin); + } + blob_appendf(&body, "\n<hr>\n"); + appendRemark(&body); + blob_appendf(&wiki, "W %d\n%s\n", blob_size(&body), blob_str(&body)); + md5sum_blob(&wiki, &cksum); + blob_appendf(&wiki, "Z %b\n", &cksum); + blob_reset(&cksum); + nrid = content_put(&wiki, 0, 0); + db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid); + manifest_crosslink(nrid, &wiki); + blob_reset(&wiki); + content_deltify(rid, nrid, 0); + db_end_transaction(0); + } cgi_redirectf("wiki?name=%T", zPageName); } if( P("cancel")!=0 ){ cgi_redirectf("wiki?name=%T", zPageName); return; @@ -440,5 +491,111 @@ } db_finalize(&q); @ </ul> style_footer(); } + +/* +** WEBPAGE: wiki_rules +*/ +void wikirules_page(void){ + style_header("Wiki Formatting Rules"); + @ <h2>Formatting Rule Summary</h2> + @ <ol> + @ <li> Blank lines are paragraph breaks + @ <li> Bullet list items are a "*" at the beginning of the line. + @ <li> Enumeration list items are a number at the beginning of a line. + @ <li> Indented pargraphs begin with a tab or two spaces. + @ <li> Hyperlinks are contained with square brackets: "[target]" + @ <li> Most ordinary HTML works. + @ <li> <verbatim> and <nowiki>. + @ </ol> + @ <p>We call the first five rules above "wiki" formatting rules. The + @ last two rules are the HTML formatting rule.</p> + @ <h2>Formatting Rule Details</h2> + @ <ol> + @ <li> <p><b>Paragraphs</b>. Any sequence of one or more blank lines forms + @ a paragraph break. Centered or right-justified paragraphs are not + @ supported by wiki markup, but you can do these things if you need them + @ using HTML.</p> + @ <li> <p><b>Bullet Lists</b>. + @ A bullet list item begins with a single "*" character surrounded on + @ both sides by two or more spaces or by a tab. Only a single level + @ of bullet list is supported by wiki. For tested lists, use HTML.</p> + @ <li> <p><b>Enumeration Lists</b>. + @ An enumeration list item begins with one or more digits optionally + @ followed by a "." surrounded on both sides by two or more spaces or + @ by a tab. The number is significant and becomes the number shown + @ in the rendered enumeration item. Only a single level of enumeration + @ list is supported by wiki. For nested enumerations or for + @ enumerations that count using letters or roman numerials, use HTML.</p> + @ <li> <p><b>Indented Paragraphs</b>. + @ Any paragraph that begins with two or more spaces or a tab and + @ which is not a bullet or enumeration list item is rendered + @ indented. Only a single level of indentation is supported by</p> + @ <li> <p><b>Hyperlinks</b>. + @ Text within square brackets ("[...]") becomes a hyperlink. The + @ target can be a wiki page name, the UUID of a check-in or ticket, + @ the name of an image, or a URL. By default, the target is displayed + @ as the text of the hyperlink. But you can specify alternative text + @ after the target name separated by a "|" character.</p> + @ <li> <p><b>HTML</b>. + @ The following standard HTML elements may be used: + @ <a> + @ <address> + @ <b> + @ <big> + @ <blockquote> + @ <br> + @ <center> + @ <cite> + @ <code> + @ <dd> + @ <dfn> + @ <dl> + @ <dt> + @ <em> + @ <font> + @ <h1> + @ <h2> + @ <h3> + @ <h4> + @ <h5> + @ <h6> + @ <hr> + @ <img> + @ <i> + @ <kbd> + @ <li> + @ <nobr> + @ <ol> + @ <p> + @ <pre> + @ <s> + @ <samp> + @ <small> + @ <strike> + @ <strong> + @ <sub> + @ <sup> + @ <table> + @ <td> + @ <th> + @ <tr> + @ <tt> + @ <u> + @ <ul> + @ <var>. + @ In addition, there are two non-standard elements available: + @ <verbatim> and <nowiki>. + @ No other elements are allowed. All attributes are checked and + @ only a few benign attributes are allowed on each element. + @ In particular, any attributes that specify javascript or CSS + @ are elided.</p> + @ <p>The <verbatim> tag disables all wiki and HTML markup + @ up through the next </verbatim>. The <nowiki> tag + @ disables all wiki formatting rules through the matching + @ </nowiki> element. + @ </ol> + style_footer(); +} +