UnitTest( textile.asp )

Output

Header 1

Right-aligned padded Header 2

Red centred Header 3

A single paragraph.

Followed by another.

Some inline bold HTML, inside paragraph tags.

  A pre Section.

“A quoted passage with — assorted – replaced entities… , including 2 × 2 , ™, ® and ©. ”

A block quotation.

Finished with a new paragraph.

a multi-line block quotation.

With a second line

Finished with a paragraph with a class of ’biggreen’

This has an id of ’italic’

This is both class ’biggreen’ and id ’italic’

Some inline styling, using CSS.

rouge

This is covered elsewhere1.

1Down here, in fact.

I believe every word. And then? She fell! I know. I really know. Cat’s Cradle by Vonnegut. Convert with r.to_html I’m sure not sure. You are a pleasant child. a 2 + b 2 = c 2 log 2 x

I’m unaware of most soft drinks. I’m unaware of most soft drinks. I seriously blushed when I sprouted that corn stalk from my cabeza.

align left

align right

centered

justified

left indent 1em

left indent 2em

right indent 3em

  1. A first item
  2. A second item
  3. A third
  1. Fuel could be:
    1. Coal
    2. Gasoline
    3. Electricity
  2. Humans need only:
    1. Water
    2. Protein

I searched Google

Snoopy.

This Snoopy is right-aligned, and a link to boot.

name age Hair colour
joan 24 Grey
archie 29 Red
bella 45 Black
attribute list, spanning 2 cols
align left align right
center justify
valign top bottom
spans 3 rows a
b
c

Sources

/axe-ut/textile.unit.test.asp

<!--#include virtual="/lib/unit-tests.asp"-->
<!--#include virtual="/lib/axe/classes/Parsers/textile.asp"-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en">
    <head>
        <title>AXE - Unit Test - Textile</title>
        <!--// meta tags //-->
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
        <!--// link tags //-->
        <link rel="stylesheet" type="text/css" media="screen" href="/lib/unit-tests.css" />
    </head>
    <body>
        <div id="container">
            <div id="container-hd">
                <h1>UnitTest( textile.asp )</h1>
            </div>
            <div id="container-bd">
 
<h2>Output</h2>
<%
 
dim sTextile : sTextile = loadTextFile( Server.mapPath("/axe-ut/textile.unit.test.dat") )
dim Converter : set Converter = new Textile
 
Response.write Converter.makeHtml(sTextile)
 
set Converter = nothing
 
%>
 
            </div>
            <div id="container-ft">
                <h2>Sources</h2>
                <h3><%= Request.ServerVariables("SCRIPT_NAME") %></h3>
                <div class="code"><%= geshify( loadTextFile( Server.mapPath( Request.ServerVariables("SCRIPT_NAME") ) ), "asp" ) %></div>
                <h3>/lib/axe/classes/Parsers/textile.asp</h3>
                <div class="code"><%= geshify( loadTextFile( Server.mapPath( "/lib/axe/classes/Parsers/textile.asp" ) ), "javascript" ) %></div>
                <h3><%= replace(Request.ServerVariables("SCRIPT_NAME"), "asp", "dat") %></h3>
                <div class="code"><%= geshify( loadTextFile( replace(Server.mapPath( Request.ServerVariables("SCRIPT_NAME") ), "asp", "dat") ), "asp" ) %></div>
            </div>
        </div>
        <!--// javascript tags //-->
    </body>
</html>
 

/lib/axe/classes/Parsers/textile.asp

<%
 
' File: textile.asp
'
' AXE(ASP Xtreme Evolution) implementation of Textile parser.
'
' License:
'
' This file is part of ASP Xtreme Evolution.
' Copyright (C) 2007-2012 Fabio Zendhi Nagao
'
' ASP Xtreme Evolution is free software: you can redistribute it and/or modify
' it under the terms of the GNU Lesser General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' ASP Xtreme Evolution is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU Lesser General Public License for more details.
'
' You should have received a copy of the GNU Lesser General Public License
' along with ASP Xtreme Evolution. If not, see <http://www.gnu.org/licenses/>.
 
 
 
' Class: Textile
'
' Textile is a lightweight markup language originally developed by Dean Allen
' and billed as a "humane Web text generator". Textile converts its marked-up
' text input to valid, well-formed XHTML and also inserts character entity
' references for apostrophes, opening and closing single and double quotation
' marks, ellipses and em dashes.
'
' About:
'
'	- This class uses the Textile javascript implementation of Ben Daglish
'	- More info about textile visit <http://textile.thresholdstate.com>
'	- Written by Fabio Zendhi Nagao <http://zend.lojcomm.com.br> @ Dec 2010
'
class Textile
 
' --[ Public section ]----------------------------------------------------------
 
	' Property: classType
	'
	' Class type.
	'
	' Contains:
	'
	'	(string) - type
	'
	public property get classType
		classType = typename(Me)
	end property
 
	' Property: classVersion
	'
	' Class version.
	'
	' Contains:
	'
	'	(string) - version in terms of http://semver.org/#semantic-versioning-200
	'
	public property get classVersion
		classVersion = "1.0.1"
	end property
 
	' Function: makeHtml
	'
	' Converts Textile into XHTML.
	'
	' Parameters:
	'
	'	(string) - textile
	'
	' Returns:
	'
	'	(string) - html
	'
	' Example:
	'
	' (start code)
	'
	' dim sTextile : sTextile = "Textile _rocks_."
	' dim Converter : set Converter = new Textile
	'
	' Response.write Converter.makeHtml(sTextile)
	'
	' set Converter = nothing
	'
	' (end code)
	'
	public function makeHtml(byVal text)
		makeHtml = [_ζ].makeHtml(text)
	end function
 
' --[ Private section ]---------------------------------------------------------
 
	private []
 
	private sub Class_initialize()
		set [] = new_Textile()
	end sub
 
	private sub Class_terminate()
		set [] = nothing
	end sub
 
end class
 
%>
<script language="javascript" runat="server">
 
function new_Textile() {
 
 
 
 
 
 
 
 
 
 
/* Ben Daglish <http://www.ben-daglish.net> code starts here */
/* Javascript Textile->HTML conversion
 *
 * ben@ben-daglish.net (with thanks to John Hughes for improvements)
 * Issued under the "do what you like with it - I take no respnsibility" licence
 *
 * Minor fixed and enhancements by Fabio Zendhi Nagao (nagaozen)
 */
var inpr, inbq, inbqq, html,
    aliases = [],
    alg = {
    	'>': 'right',
    	'<': 'left',
    	'=': 'center',
    	'<>': 'justify',
    	'~': 'bottom',
    	'^': 'top'
    },
    ent = {
    	"'": "&#8217;",
    	" - ": " &#8211; ",
    	"--": "&#8212;",
    	" x ": " &#215; ",
    	"\\.\\.\\.": "&#8230;",
    	"\\(C\\)": "&#169;",
    	"\\(R\\)": "&#174;",
    	"\\(TM\\)": "&#8482;"
    },
    tags = {
    	"b": "\\*\\*",
    	"i": "__",
    	"em": "_",
    	"strong": "\\*",
    	"cite": "\\?\\?",
    	"sup": "\\^",
    	"sub": "~",
    	"span": "\\%",
    	"del": "-",
    	"code": "@",
    	"ins": "\\+",
    	"del": "-"
    },
    le = "\n\n",
    lstlev = 0,
    lst = "",
    elst = "",
    intable = 0,
    mm = "",
    para = /^p(\S*)\.\s*(.*)/,
    rfn = /^fn(\d+)\.\s*(.*)/,
    bq = /^bq\.(\.)?\s*/,
    table = /^table\s*{(.*)}\..*/,
    trstyle = /^\{(\S+)\}\.\s*\|/;
 
function convert(t) {
	var lines = t.split("\n");
	html = [];
	inpr = inbq = inbqq = 0;
	for(var i = 0; i < lines.length; i++) {
		if(lines[i].indexOf("[") == 0) {
			var m = lines[i].indexOf("]");
			aliases[lines[i].substring(1, m)] = lines[i].substring(m + 1);
		}
	}
	for(i = 0; i < lines.length; i++) {
		if(lines[i].indexOf("[") == 0) {
			continue;
		}
		if(mm = para.exec(lines[i])) {
			stp(1);
			inpr = 1;
			html.push(lines[i].replace(para, "<p" + make_attr(mm[1]) + ">" + prep(mm[2])));
			continue;
		}
		if(mm = /^h(\d)(\S*)\.\s*(.*)/.exec(lines[i])) {
			stp(1);
			html.push(tag("h" + mm[1], make_attr(mm[2]), prep(mm[3])) + le);
			continue;
		}
		if(mm = rfn.exec(lines[i])) {
			stp(1);
			inpr = 1;
			html.push(lines[i].replace(rfn, '<p id="fn' + mm[1] + '"><sup>' + mm[1] + '<\/sup>' + prep(mm[2])));
			continue;
		}
		if(lines[i].indexOf("*") == 0) {
			lst = "<ul>";
			elst = "<\/ul>";
		} else if(lines[i].indexOf("#") == 0) {
			lst = "<ol>";
			elst = "<\/ol>";
		} else {
			while(lstlev > 0) {
				html.push(elst);
				if(lstlev > 1) {
					html.push("<\/li>");
				} else {
					html.push("\n");
				}
				html.push("\n");
				lstlev--;
			}
			lst = "";
		}
		if(lst) {
			stp(1);
			var m = /^([*#]+)\s*(.*)/.exec(lines[i]);
			var lev = m[1].length;
			while(lev < lstlev) {
				html.push(elst + "<\/li>\n");
				lstlev--;
			}
			while(lstlev < lev) {
				html = [html.join("").replace(/<\/li>\n$/, "\n")];
				html.push(lst);
				lstlev++;
			}
			html.push(tag("li", "", prep(m[2])) + "\n");
			continue;
		}
		if(lines[i].match(table)) {
			stp(1);
			intable = 1;
			html.push(lines[i].replace(table, '<table style="$1;">\n'));
			continue;
		}
		if((lines[i].indexOf("|") == 0) || (lines[i].match(trstyle))) {
			stp(1);
			if(!intable) {
				html.push("<table>\n");
				intable = 1;
			}
			var rowst = "";
			var trow = "";
			var ts = trstyle.exec(lines[i]);
			if(ts) {
				rowst = qat('style', ts[1]);
				lines[i] = lines[i].replace(trstyle, "\|");
			}
			var cells = lines[i].split("|");
			for(j = 1; j < cells.length - 1; j++) {
				var ttag = "td";
				if(cells[j].indexOf("_.") == 0) {
					ttag = "th";
					cells[j] = cells[j].substring(2);
				}
				cells[j] = prep(cells[j]);
				var al = /^([<>=^~\/\\\{]+.*?)\.(.*)/.exec(cells[j]);
				var at = "",
				    st = "";
				if(al != null) {
					cells[j] = al[2];
					var cs = /\\(\d+)/.exec(al[1]);
					if(cs != null) {
						at += qat('colspan', cs[1]);
					}
					var rs = /\/(\d+)/.exec(al[1]);
					if(rs != null) {
						at += qat('rowspan', rs[1]);
					}
					var va = /([\^~])/.exec(al[1]);
					if(va != null) {
						st += "vertical-align:" + alg[va[1]] + ";";
					}
					var ta = /(<>|=|<|>)/.exec(al[1]);
					if(ta != null) {
						st += "text-align:" + alg[ta[1]] + ";";
					}
					var is = /\{([^\}]+)\}/.exec(al[1]);
					if(is != null) {
						st += is[1];
					}
					if(st != "") {
						at += qat('style', st);
					}
				}
				trow += tag(ttag, at, cells[j]);
			}
			html.push("\t" + tag("tr", rowst, trow) + "\n");
			continue;
		}
		if(intable) {
			html.push("<\/table>" + le);
			intable = 0;
		}
		if(lines[i] == "") {
			stp();
		} else if(!inpr) {
			if(mm = bq.exec(lines[i])) {
				lines[i] = lines[i].replace(bq, "");
				html.push("<blockquote>");
				inbq = 1;
				if(mm[1]) {
					inbqq = 1;
				}
			}
			html.push("<p>" + prep(lines[i]));
			inpr = 1;
		} else {
			html.push(prep(lines[i]));
		}
	}
	stp();
	return html.join("");
}
 
function prep(m) {
	for(i in ent) {
		m = m.replace(new RegExp(i, "g"), ent[i]);
	}
	for(i in tags) {
		m = make_tag(m, RegExp("^" + tags[i] + "(.+?)" + tags[i]), i, "");
		m = make_tag(m, RegExp(" " + tags[i] + "(.+?)" + tags[i]), i, " ");
	}
	m = m.replace(/\[(\d+)\]/g, '<sup><a href="#fn$1">$1<\/a><\/sup>');
	m = m.replace(/([A-Z]+)\((.*?)\)/g, '<acronym title="$2">$1<\/acronym>');
	m = m.replace(/\"([^\"]+)\":((http|https|mailto):\S+)/g, '<a href="$2">$1<\/a>');
	m = make_image(m, /!([^!\s]+)!:(\S+)/);
	m = make_image(m, /!([^!\s]+)!/);
	m = m.replace(/"([^\"]+)":(\S+)/g, function($0, $1, $2) {
		return tag("a", qat('href', aliases[$2]), $1)
	});
	m = m.replace(/(=)?"([^\"]+)"/g, function($0, $1, $2) {
		return($1) ? $0 : "&#8220;" + $2 + "&#8221;"
	});
	return m;
}
 
function make_tag(s, re, t, sp) {
	while(m = re.exec(s)) {
		var st = make_attr(m[1]);
		m[1] = m[1].replace(/^[\[\{\(]\S+[\]\}\)]/g, "");
		m[1] = m[1].replace(/^[<>=()]+/, "");
		s = s.replace(re, sp + tag(t, st, m[1]));
	}
	return s;
}
 
function make_image(m, re) {
	var ma = re.exec(m);
	if(ma != null) {
		var attr = "";
		var st = "";
		var at = /\((.*)\)$/.exec(ma[1]);
		if(at != null) {
			attr = qat('alt', at[1]) + qat("title", at[1]);
			ma[1] = ma[1].replace(/\((.*)\)$/, "");
		}
		if(ma[1].match(/^[><]/)) {
			st = "float:" + ((ma[1].indexOf(">") == 0) ? "right;" : "left;");
			ma[1] = ma[1].replace(/^[><]/, "");
		}
		var pdl = /(\(+)/.exec(ma[1]);
		if(pdl) {
			st += "padding-left:" + pdl[1].length + "em;";
		}
		var pdr = /(\)+)/.exec(ma[1]);
		if(pdr) {
			st += "padding-right:" + pdr[1].length + "em;";
		}
		if(st) {
			attr += qat('style', st);
		}
		var im = '<img src="' + ma[1] + '"' + attr + " /" + '>';
		if(ma.length > 2) {
			im = tag('a', qat('href', ma[2]), im);
		}
		m = m.replace(re, im);
	}
	return m;
}
 
function make_attr(s) {
	var st = "";
	var at = "";
	if(!s) {
		return "";
	}
	var l = /\[(\w\w)\]/.exec(s);
	if(l != null) {
		at += qat('lang', l[1]);
	}
	var ci = /\((\S+)\)/.exec(s);
	if(ci != null) {
		s = s.replace(/\((\S+)\)/, "");
		at += ci[1].replace(/#(.*)$/, ' id="$1"').replace(/^(\S+)/, ' class="$1"');
	}
	var ta = /(<>|=|<|>)/.exec(s);
	if(ta) {
		st += "text-align:" + alg[ta[1]] + ";";
	}
	var ss = /\{(\S+)\}/.exec(s);
	if(ss) {
		st += ss[1];
		if(!ss[1].match(/;$/)) {
			st += ";";
		}
	}
	var pdl = /(\(+)/.exec(s);
	if(pdl) {
		st += "padding-left:" + pdl[1].length + "em;";
	}
	var pdr = /(\)+)/.exec(s);
	if(pdr) {
		st += "padding-right:" + pdr[1].length + "em;";
	}
	if(st) {
		at += qat('style', st);
	}
	return at;
}
 
function qat(a, v) {
	return ' ' + a + '="' + v + '"';
}
 
function tag(t, a, c) {
	return "<" + t + a + ">" + c + "</" + t + ">";
}
 
function stp(b) {
	if(b) {
		inbqq = 0;
	}
	if(inpr) {
		html.push("<\/p>" + le);
		inpr = 0;
	}
	if(inbq && !inbqq) {
		html.push("<\/blockquote>" + le);
		inbq = 0;
	}
}
/* Code ends here */
 
 
 
 
 
 
 
 
 
 
	return {
		makeHtml: convert
	};
}
 
</script>
 

/axe-ut/textile.unit.test.dat

h1. Header 1
 
h2)>. Right-aligned padded Header 2
 
h3()=[no]{color:red}. Red centred Header 3
 
A single paragraph.
 
Followed by another.
 
Some inline <b>bold</b> HTML, inside paragraph tags.
 
<pre>
  A <i>pre</i> Section.
</pre>
 
"A quoted passage with -- assorted - replaced entities... , including 2 x 2 , (TM), (R) and (C). "
 
bq. A block quotation.
 
Finished with a new paragraph.
 
bq.. a multi-line block quotation.
 
With a second line
 
p(biggreen). Finished with a paragraph with a class of 'biggreen'
 
p(#italic). This has an id of 'italic'
 
p(biggreen#italic). This is both class 'biggreen' and id 'italic'
 
p{color:blue;margin:30px}. Some inline styling, using CSS(Cascading Style Sheets).
 
p[fr]. rouge
 
This is covered elsewhere[1].
 
fn1. Down here, in fact.
 
I _believe_ every word. And then? She *fell*! I __know__. I **really** __know__. ??Cat's Cradle?? by Vonnegut. Convert with @r.to_html@ I'm -sure- not sure. You are a +pleasant+ child. a ^2^ + b ^2^ = c ^2^ log ~2~ x
 
I'm %unaware% of most soft drinks. I'm %{color:red}unaware% of most soft drinks. I seriously *{color:red}blushed* when I _(big)sprouted_ that corn stalk from my %[es]cabeza%. 
 
p<. align left
 
p>. align right
 
p=. centered
 
p<>. justified
 
p(. left indent 1em
 
p((. left indent 2em
 
p))). right indent 3em
 
# A first item
# A second item
# A third
 
# Fuel could be:
## Coal
## Gasoline
## Electricity
# Humans need only:
## Water
## Protein
 
* A first item
* A second item
* A third
 
* Fuel could be:
** Coal
** Gasoline
** Electricity
* Humans need only:
** Water
** Protein
 
[google]http://google.com
 
I searched "Google":google
 
!http://www.ben-daglish.net/snoopy.png(Snoopy.)!:http://www.ben-daglish.net
 
This Snoopy is right-aligned, and a link to boot.
 
|_. name |_. age |_. Hair colour |
| joan | 24 |{background:#ddd}. Grey |
| archie | 29 |{color:#f00}. Red |
{background:#ff0}. | bella | 45 | Black |
 
table{border:1px solid black;margin-top:20px}.
|_.\2. attribute list, spanning 2 cols |
|<. align left |>. align right|
|=. center |<>. justify |
|^. valign top |~. bottom |
|/3. spans 3 rows | a |
| b |
| c |