@@ -32,38 +32,40 @@
** Allowed wiki transformation operations
*/
#define WIKI_NOFOLLOW 0x001
#define WIKI_HTML 0x002
+#define WIKI_INLINE 0x004 /* Do not surround with <p>..</p> */
#endif
/*
** These are the only markup attributes allowed.
*/
-#define ATTR_ALIGN 0x000001
-#define ATTR_ALT 0x000002
-#define ATTR_BGCOLOR 0x000004
-#define ATTR_BORDER 0x000008
-#define ATTR_CELLPADDING 0x000010
-#define ATTR_CELLSPACING 0x000020
-#define ATTR_CLEAR 0x000040
-#define ATTR_COLOR 0x000080
-#define ATTR_COLSPAN 0x000100
-#define ATTR_COMPACT 0x000200
-#define ATTR_FACE 0x000400
-#define ATTR_HEIGHT 0x000800
-#define ATTR_HREF 0x001000
-#define ATTR_HSPACE 0x002000
-#define ATTR_ID 0x004000
-#define ATTR_ROWSPAN 0x008000
-#define ATTR_SIZE 0x010000
-#define ATTR_SRC 0x020000
-#define ATTR_START 0x040000
-#define ATTR_TYPE 0x080000
-#define ATTR_VALIGN 0x100000
-#define ATTR_VALUE 0x200000
-#define ATTR_VSPACE 0x400000
-#define ATTR_WIDTH 0x800000
+#define ATTR_ALIGN 0x0000001
+#define ATTR_ALT 0x0000002
+#define ATTR_BGCOLOR 0x0000004
+#define ATTR_BORDER 0x0000008
+#define ATTR_CELLPADDING 0x0000010
+#define ATTR_CELLSPACING 0x0000020
+#define ATTR_CLEAR 0x0000040
+#define ATTR_COLOR 0x0000080
+#define ATTR_COLSPAN 0x0000100
+#define ATTR_COMPACT 0x0000200
+#define ATTR_FACE 0x0000400
+#define ATTR_HEIGHT 0x0000800
+#define ATTR_HREF 0x0001000
+#define ATTR_HSPACE 0x0002000
+#define ATTR_ID 0x0004000
+#define ATTR_NAME 0x0008000
+#define ATTR_ROWSPAN 0x0010000
+#define ATTR_SIZE 0x0020000
+#define ATTR_SRC 0x0040000
+#define ATTR_START 0x0080000
+#define ATTR_TYPE 0x0100000
+#define ATTR_VALIGN 0x0200000
+#define ATTR_VALUE 0x0400000
+#define ATTR_VSPACE 0x0800000
+#define ATTR_WIDTH 0x1000000
static const struct AllowedAttribute {
const char *zName;
unsigned int iMask;
@@ -83,8 +85,9 @@
{ "height", ATTR_HEIGHT, },
{ "href", ATTR_HREF, },
{ "hspace", ATTR_HSPACE, },
{ "id", ATTR_ID, },
+ { "name", ATTR_NAME, },
{ "rowspan", ATTR_ROWSPAN, },
{ "size", ATTR_SIZE, },
{ "src", ATTR_SRC, },
{ "start", ATTR_START, },
@@ -180,9 +183,8 @@
*/
#define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */
#define MUTYPE_BLOCK 0x0002 /* Forms a new paragraph. ex: <p>, <h2> */
#define MUTYPE_FONT 0x0004 /* Font changes. ex: <b>, <font>, <sub> */
-#define MUTYPE_LINK 0x0008 /* Hyperlink: <a> */
#define MUTYPE_LIST 0x0010 /* Lists. <ol>, <ul>, or <dl> */
#define MUTYPE_LI 0x0020 /* List items. <li>, <dd>, <dt> */
#define MUTYPE_TABLE 0x0040 /* <table> */
#define MUTYPE_TR 0x0080 /* <tr> */
@@ -189,8 +191,11 @@
#define MUTYPE_TD 0x0100 /* <td> or <th> */
#define MUTYPE_SPECIAL 0x0200 /* <nowiki> or <verbatim> */
#define MUTYPE_HYPERLINK 0x0400 /* <a> */
+/*
+** These markup types must have an end tag.
+*/
#define MUTYPE_STACK (MUTYPE_BLOCK | MUTYPE_FONT | MUTYPE_LIST | MUTYPE_TABLE)
static const struct AllowedMarkup {
const char *zName; /* Name of the markup */
@@ -198,9 +203,10 @@
short int iType; /* The MUTYPE_* code */
int allowedAttr; /* Allowed attributes on this markup */
} aMarkup[] = {
{ 0, MARKUP_INVALID, 0, 0 },
- { "a", MARKUP_A, MUTYPE_HYPERLINK, ATTR_HREF },
+ { "a", MARKUP_A, MUTYPE_HYPERLINK,
+ ATTR_HREF|ATTR_NAME },
{ "address", MARKUP_ADDRESS, MUTYPE_BLOCK, 0 },
{ "b", MARKUP_B, MUTYPE_FONT, 0 },
{ "big", MARKUP_BIG, MUTYPE_FONT, 0 },
{ "blockquote", MARKUP_BLOCKQUOTE, MUTYPE_BLOCK, 0 },
@@ -315,8 +321,10 @@
int state; /* Flag that govern rendering */
int wikiList; /* Current wiki list type */
int inVerbatim; /* True in <verbatim> mode */
int preVerbState; /* Value of state prior to verbatim */
+ int wantAutoParagraph; /* True if a <p> is desired */
+ int inAutoParagraph; /* True if within an automatic paragraph */
const char *zVerbatimId; /* The id= attribute of <verbatim> */
int nStack; /* Number of elements on the stack */
int nAlloc; /* Space allocated for aStack */
unsigned char *aStack; /* Open markup stack */
@@ -439,9 +447,9 @@
** Syntax:
** * a tab or two or more spaces
** * one or more digits
** * optional "."
-** * another tab or two or more additional spaces
+** * another tab or two ore more spaces.
**
*/
static int enumLength(const char *z){
int i, n;
@@ -742,15 +750,26 @@
return p->aStack[i-1];
}
/*
-** Add missing markup in preparation for writing text.
-**
-** "Missing" markup are things like start tags for table rows
-** or table columns or paragraphs that are omitted from input.
+** Begin a new paragraph if that something that is needed.
+*/
+static void startAutoParagraph(Renderer *p){
+ if( p->wantAutoParagraph==0 ) return;
+ blob_appendf(p->pOut, "<p>", -1);
+ pushStack(p, MARKUP_P);
+ p->wantAutoParagraph = 0;
+ p->inAutoParagraph = 1;
+}
+
+/*
+** End a paragraph if we are in one.
*/
-static void addMissingMarkup(Renderer *p){
- /* TBD */
+static void endAutoParagraph(Renderer *p){
+ if( p->inAutoParagraph ){
+ popStackToTag(p, MARKUP_P);
+ p->inAutoParagraph = 0;
+ }
}
/*
** Resolve a hyperlink. The argument is the content of the [...]
@@ -814,11 +833,12 @@
if( p->wikiList ){
popStackToTag(p, p->wikiList);
p->wikiList = 0;
}
- blob_append(p->pOut, "\n\n<p>", -1);
- p->state |= AT_PARAGRAPH|AT_NEWLINE;
- popStackToTag(p, MARKUP_P);
+ endAutoParagraph(p);
+ blob_appendf(p->pOut, "\n\n", 1);
+ p->wantAutoParagraph = 1;
+ p->state |= AT_PARAGRAPH|AT_NEWLINE;
break;
}
case TOKEN_NEWLINE: {
blob_append(p->pOut, "\n", 1);
@@ -833,8 +853,10 @@
pushStack(p, MARKUP_UL);
blob_append(p->pOut, "<ul>", 4);
p->wikiList = MARKUP_UL;
}
+ popStackToTag(p, MARKUP_LI);
+ startAutoParagraph(p);
pushStack(p, MARKUP_LI);
blob_append(p->pOut, "<li>", 4);
break;
}
@@ -846,8 +868,10 @@
pushStack(p, MARKUP_OL);
blob_append(p->pOut, "<ol>", 4);
p->wikiList = MARKUP_OL;
}
+ popStackToTag(p, MARKUP_LI);
+ startAutoParagraph(p);
pushStack(p, MARKUP_LI);
blob_appendf(p->pOut, "<li value=\"%d\">", atoi(z));
break;
}
@@ -854,12 +878,14 @@
case TOKEN_INDENT: {
assert( p->wikiList==0 );
pushStack(p, MARKUP_BLOCKQUOTE);
blob_append(p->pOut, "<blockquote>", -1);
+ p->wantAutoParagraph = 0;
p->wikiList = MARKUP_BLOCKQUOTE;
break;
}
case TOKEN_CHARACTER: {
+ startAutoParagraph(p);
if( z[0]=='<' ){
blob_append(p->pOut, "<", 4);
}else if( z[0]=='&' ){
blob_append(p->pOut, "&", 5);
@@ -870,9 +896,9 @@
char *zTarget;
char *zDisplay = 0;
int i, j;
int savedState;
- addMissingMarkup(p);
+ startAutoParagraph(p);
zTarget = &z[1];
for(i=1; z[i] && z[i]!=']'; i++){
if( z[i]=='|' && zDisplay==0 ){
zDisplay = &z[i+1];
@@ -897,9 +923,9 @@
blob_append(p->pOut, "</a>", 4);
break;
}
case TOKEN_TEXT: {
- addMissingMarkup(p);
+ startAutoParagraph(p);
blob_append(p->pOut, z, n);
break;
}
case TOKEN_MARKUP: {
@@ -914,8 +940,10 @@
blob_append(p->pOut, "<", 4);
n = 1;
}
}else if( markup.iCode==MARKUP_INVALID ){
+ unparseMarkup(&markup);
+ startAutoParagraph(p);
blob_append(p->pOut, "<", 4);
n = 1;
}else if( (markup.iType&MUTYPE_FONT)==0
&& (p->state & FONT_MARKUP_ONLY)!=0 ){
@@ -937,8 +965,9 @@
p->inVerbatim = 1;
p->preVerbState = p->state;
p->state &= ~ALLOW_WIKI;
blob_append(p->pOut, "<pre>", 5);
+ p->wantAutoParagraph = 0;
}else if( markup.iType==MUTYPE_LI ){
if( backupToType(p, MUTYPE_LIST)==0 ){
pushStack(p, MARKUP_UL);
blob_append(p->pOut, "<ul>", 4);
@@ -958,9 +987,19 @@
}
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 ){
+ p->wantAutoParagraph = 0;
+ }
if( (markup.iType & MUTYPE_STACK )!=0 ){
pushStack(p, markup.iCode);
}
renderMarkup(p->pOut, &markup);
@@ -969,8 +1008,9 @@
}
}
z += n;
}
+ endAutoParagraph(p);
}
/*
@@ -979,14 +1019,15 @@
** initialized. The output is merely appended to pOut.
** If pOut is NULL, then the output is appended to the CGI
** reply.
*/
-void wiki_convert(Blob *pIn, Blob *pOut){
+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;
+ renderer.wantAutoParagraph = (flags & WIKI_INLINE)==0;
if( pOut ){
renderer.pOut = pOut;
}else{
renderer.pOut = cgi_output_blob();
@@ -1008,7 +1049,7 @@
Blob in, out;
if( g.argc!=3 ) usage("FILE");
blob_zero(&out);
blob_read_from_file(&in, g.argv[2]);
- wiki_convert(&in, &out);
+ wiki_convert(&in, &out, 0);
blob_write_to_file(&out, "-");
}