Markup: merged in latest changes (bugfix in preformatted layout, support for
authorTimm S. Mueller <tmueller@neoscientists.org>
Fri, 02 May 2008 14:42:18 +0200
changeset 241c6c81629f54e
parent 240 b13d977255cb
child 242 cba82ca82420
Markup: merged in latest changes (bugfix in preformatted layout, support for
numbers in headnode Ids), source code documentation added, format description
slightly cleaned up; Makefiles: markup class installation path corrected;
luahtml parser: corrected to no longer bail out with "too many syntax levels"
when >200 variables were included; posix: minor source code cleanup
MARKUP
cgi-bin/Makefile
cgi-bin/tek/class/markup.lua
cgi-bin/tek/lib/luahtml.c
cgi-bin/tek/os/posix.c
     1.1 --- a/MARKUP	Fri Jan 04 06:30:34 2008 +0100
     1.2 +++ b/MARKUP	Fri May 02 14:42:18 2008 +0200
     1.3 @@ -16,7 +16,7 @@
     1.4  
     1.5  Text of a consistent indentation level running uninterrupted by empty
     1.6  lines is combined into ''blocks''. Lines in blocks can break at any
     1.7 -position; the line breaks are not included to the result:
     1.8 +position; the line breaks are not included in the result:
     1.9  
    1.10  ---------------------------------------------------------------------
    1.11  
    1.12 @@ -153,10 +153,10 @@
    1.13   * [[@@/images/loona.png@@][http://loona.neoscientists.org/]] -
    1.14   Image link
    1.15  
    1.16 -As for external links, LOona's configuration file offers a global
    1.17 -option to decide whether external links should open in a new browser
    1.18 -window or not. (Many people disregard this feature, while businesses
    1.19 -seem to swear by it.)
    1.20 +As for external links, LOona's configuration file offers an option
    1.21 +to decide whether external links should open in a new browser window
    1.22 +or not. Many people disregard this feature, while businesses seem
    1.23 +to swear by it.
    1.24  
    1.25  
    1.26  ===( Tables )===
    1.27 @@ -174,7 +174,7 @@
    1.28  
    1.29  It is also possible to create empty cells as long as the separators
    1.30  are present. Note, by the way, that cell separators do not
    1.31 -necessarily need to be aligned exactly below each other:
    1.32 +necessarily have to be aligned exactly below each other:
    1.33  
    1.34  ---------------------------------------------------------------------
    1.35  
    1.36 @@ -204,7 +204,7 @@
    1.37  ===( Rules )===
    1.38  
    1.39  A minimum of four dashes is interpreted as a horizontal rule. Rules
    1.40 -may occur at arbitrary indentation levels, but otherwise, they must
    1.41 +may occur at arbitrary indentation levels, but otherwise they must
    1.42  occupy the whole line:
    1.43  
    1.44  ---------------------------------------------------------------------
    1.45 @@ -240,7 +240,7 @@
    1.46  ''Nodes'' translate to anchors in a document, and a browser will
    1.47  usually interprete them as jump targets. Visually, nodes translate
    1.48  to headlines also; as usual, the number of equal signs with which
    1.49 -the markup is paired determines the significance and therefore
    1.50 +the heading is paired determines the significance and therefore
    1.51  size of a headline:
    1.52  
    1.53  ---------------------------------------------------------------------
    1.54 @@ -251,9 +251,9 @@
    1.55  
    1.56  ---------------------------------------------------------------------
    1.57  
    1.58 -In addition to normal node/headlines, there are nodes which are
    1.59 -displayed as code markup. This is especially useful for jump
    1.60 -targets in a technical documentation:
    1.61 +In addition to normal node headlines, there is also a variant which
    1.62 +is marked up as code. This is especially useful for jump targets in
    1.63 +technical documentation:
    1.64  
    1.65  ---------------------------------------------------------------------
    1.66  
    1.67 @@ -264,7 +264,7 @@
    1.68  ---------------------------------------------------------------------
    1.69  
    1.70  When referencing a node, use a number sign {{#}} followed by the
    1.71 -Node name. This by the way also works for referencing nodes in
    1.72 +node name. This, by the way, also works when referencing nodes in
    1.73  other documents.
    1.74  
    1.75  For example, this link will take you to the beginning of this
    1.76 @@ -277,7 +277,7 @@
    1.77  ---------------------------------------------------------------------
    1.78  
    1.79  '''NOTE''': Don't be too adventurous when selecting a node name;
    1.80 -if you need blanks or punctuation or if in doubt, use the alternate
    1.81 +if you need blanks or punctuation or if in doubt use the alternate
    1.82  text notation.
    1.83  
    1.84  
    1.85 @@ -287,12 +287,3 @@
    1.86  elements usually leads to better readability and stylistic clarity.
    1.87  If you can't produce the looks you project, first and foremost think
    1.88  of improving your stylesheet.
    1.89 -
    1.90 -Ok, for the desperate: There's a single lone hack in LOona's markup
    1.91 -format which allows you to produce additional padding between
    1.92 -elements, list items which may appear to be empty, etc. It can come
    1.93 -to the rescue in some darned situations. It's the non-breaking space;
    1.94 -produce it either by inserting the character code 160 (see your
    1.95 -browser or operating system manuals on how to achieve this), or by
    1.96 -writing the HTML equivalent (' &nbsp; '). (See the plain text
    1.97 -representation of this document, as it cannot be escaped.)
     2.1 --- a/cgi-bin/Makefile	Fri Jan 04 06:30:34 2008 +0100
     2.2 +++ b/cgi-bin/Makefile	Fri May 02 14:42:18 2008 +0200
     2.3 @@ -43,7 +43,7 @@
     2.4  	-luac -s -o $(INSTPATH)/tek/class/cgi/request.lua tek/class/cgi/request.lua
     2.5  	-luac -s -o $(INSTPATH)/tek/class/loona.lua tek/class/loona.lua
     2.6  	-luac -s -o $(INSTPATH)/tek/class/loona/buffer.lua tek/class/loona/buffer.lua
     2.7 -	-luac -s -o $(INSTPATH)/tek/class/loona/markup.lua tek/class/loona/markup.lua
     2.8 +	-luac -s -o $(INSTPATH)/tek/class/markup.lua tek/class/markup.lua
     2.9  	-luac -s -o $(INSTPATH)/tek/class/loona/util.lua tek/class/loona/util.lua
    2.10  
    2.11  tek/lib/luahtml.so: tek/lib/luahtml.o
     3.1 --- a/cgi-bin/tek/class/markup.lua	Fri Jan 04 06:30:34 2008 +0100
     3.2 +++ b/cgi-bin/tek/class/markup.lua	Fri May 02 14:42:18 2008 +0200
     3.3 @@ -5,8 +5,188 @@
     3.4  --	See copyright notice in COPYRIGHT
     3.5  --
     3.6  --	OVERVIEW::
     3.7 ---	Markup parser - produces fancy HTML from plain text with special
     3.8 ---	formattings.
     3.9 +--		[[#ClassOverview : Lineage]] :
    3.10 +--		[[#tek.class : Class]] /
    3.11 +--		Markup - Markup parser producing fancy HTML from plain text with
    3.12 +--		special formattings
    3.13 +--
    3.14 +--	FUNCTIONS::
    3.15 +--	- Markup:new()
    3.16 +--	- Markup:run()
    3.17 +--
    3.18 +--	FORMAT DESCRIPTION::
    3.19 +--
    3.20 +--	=== Block ===
    3.21 +--
    3.22 +--	Text of a consistent indentation level running uninterrupted by empty
    3.23 +--	lines is combined into ''blocks''. Lines in blocks can break at any
    3.24 +--	position; the line breaks are not included in the result:
    3.25 +--
    3.26 +--		This is a block.
    3.27 +--
    3.28 +--		This is another
    3.29 +--		block.
    3.30 +--
    3.31 +--	=== Indentation ===
    3.32 +--
    3.33 +--	The ''indentation depth'' is measured in the consecutive number of
    3.34 +--	''indentation characters'' (tabs or spaces, which may depend on
    3.35 +--	the application) at the beginning of a line; different indentation
    3.36 +--	levels are taken into account accordingly:
    3.37 +--
    3.38 +--	This is a block.
    3.39 +--
    3.40 +--		This is another
    3.41 +--		block.
    3.42 +--
    3.43 +--			This is a third
    3.44 +--			block.
    3.45 +--
    3.46 +--	=== Preformatted ===
    3.47 +--
    3.48 +--	For blocks of code and other kinds of ''preformatted text'' use an
    3.49 +--	indentation that is ''two levels deeper'' than the current level,
    3.50 +--	e.g.:
    3.51 +--
    3.52 +--	Normal text
    3.53 +--
    3.54 +--			/* Code markup */
    3.55 +--
    3.56 +--	Back to normal
    3.57 +--
    3.58 +--	=== Code ===
    3.59 +--
    3.60 +--	Inlined ''code'' is marked up between double braces. It may occur at
    3.61 +--	any position in a line, but it must be the same line in which the
    3.62 +--	opening and the closing of the markup occurs:
    3.63 +--
    3.64 +--	This is {{code_markup}} in running text.
    3.65 +--
    3.66 +--	=== Lists ===
    3.67 +--
    3.68 +--	There are two types of items in ''lists''; ''soft'' and ''bulleted''
    3.69 +--	items. They are recognized by their initiatory character (dash or
    3.70 +--	asterisk), followed by a whitespace at the beginning of a line:
    3.71 +--
    3.72 +--		- soft item
    3.73 +--		* bulleted item
    3.74 +--
    3.75 +--	Soft items are, by the way, a natural means to enforce line breaks:
    3.76 +--
    3.77 +--		- this is a line,
    3.78 +--		- this is another line,
    3.79 +--		- this is a third line.
    3.80 +--
    3.81 +--	Lists follow the same indentation rules as normal text:
    3.82 +--
    3.83 +--		* one
    3.84 +--		* two
    3.85 +--		* three
    3.86 +--			* eins
    3.87 +--			* zwei
    3.88 +--				- ichi
    3.89 +--				- ni
    3.90 +--				- san
    3.91 +--			* drei
    3.92 +--
    3.93 +--	'''NOTE''': Although not striclty required, it is recommended to
    3.94 +--	indent lists by one level. This will help the parser to avoid
    3.95 +--	ambiguities; otherwise, when a regular block follows an unindented
    3.96 +--	list, it would be concatenated with the last item, as empty lines are
    3.97 +--	not sufficient to break out from a list.
    3.98 +--
    3.99 +--	=== Links ===
   3.100 +--
   3.101 +--	Links are enclosed in double squared brackets:
   3.102 +--
   3.103 +--		* [[home]] -
   3.104 +--		Internal link: Link target is description at the same time.
   3.105 +--
   3.106 +--		* [[Home page][home]] -
   3.107 +--		Internal link with alternate description
   3.108 +--
   3.109 +--		* [[http://www.foo.bar/]] -
   3.110 +--		External link
   3.111 +--
   3.112 +--		* [[You know what cool is][http://www.foo.bar/]] -
   3.113 +--		External link with alternate description
   3.114 +--
   3.115 +--	=== Tables ===
   3.116 +--
   3.117 +--	Lines running uninterrupted with at least one cell separator in each
   3.118 +--	of them automatically form a table. The cell separator is a double
   3.119 +--	vertical bar:
   3.120 +--
   3.121 +--		First cell || Second cell
   3.122 +--		Third cell || Fourth cell
   3.123 +--
   3.124 +--	It is also possible to create empty cells as long as the separators
   3.125 +--	are present. Note, by the way, that cell separators do not
   3.126 +--	necessarily have to be aligned exactly below each other.
   3.127 +--
   3.128 +--	=== Headings ===
   3.129 +--
   3.130 +--	Headings occupy an entire line. They are enclosed by at least one
   3.131 +--	equal sign and a whitspace on each side; the more equal signs, the
   3.132 +--	less significant the section:
   3.133 +--
   3.134 +--		= Heading 1 =
   3.135 +--
   3.136 +--		== Heading 2 ==
   3.137 +--
   3.138 +--		=== Heading 3 ===
   3.139 +--
   3.140 +--	=== Rules ===
   3.141 +--
   3.142 +--	A minimum of four dashes is interpreted as a horizontal rule. Rules
   3.143 +--	may occur at arbitrary indentation levels, but otherwise they must
   3.144 +--	occupy the whole line:
   3.145 +--
   3.146 +--		before the rule
   3.147 +--		----------------------------------------------
   3.148 +--		after the rule
   3.149 +--
   3.150 +--	=== Emphasis ===
   3.151 +--
   3.152 +--	An emphasized portion of text may occur at any position in a line,
   3.153 +--	but the opening and the closing of the markup must occur in the same
   3.154 +--	line to be recognized.
   3.155 +--
   3.156 +--	The emphasized text is surrounded by at least two ticks on each side;
   3.157 +--	the more ticks, the stronger the emphasis.
   3.158 +--
   3.159 +--		- normal
   3.160 +--		- ''emphasis''
   3.161 +--		- '''strong emphasis'''
   3.162 +--		- ''''very strong emphasis''''
   3.163 +--
   3.164 +--	=== Nodes ===
   3.165 +--
   3.166 +--	''Nodes'' translate to anchors in a document, and a browser will
   3.167 +--	usually interprete them as jump targets. Visually, nodes translate
   3.168 +--	to headlines also; as usual, the number of equal signs with which
   3.169 +--	the heading is paired determines the significance and therefore
   3.170 +--	size of a headline:
   3.171 +--
   3.172 +--		=( Large )=
   3.173 +--		==( Medium )==
   3.174 +--		===( Small : Small node with alternate text )===
   3.175 +--
   3.176 +--	In addition to normal node headlines, there is also a variant which
   3.177 +--	is marked up as code. This is especially useful for jump targets in
   3.178 +--	technical documentation:
   3.179 +--
   3.180 +--		={ LargeCode : Large code node }=
   3.181 +--		=={ MediumCode : Medium code node }==
   3.182 +--		==={ SmallCode : Small code node }===
   3.183 +--
   3.184 +--	When referencing a node, use a number sign {{#}} followed by the
   3.185 +--	node name. This, by the way, also works when referencing nodes in
   3.186 +--	other documents.
   3.187 +--
   3.188 +--	'''NOTE''': Don't be too adventurous when selecting a node name;
   3.189 +--	if you need blanks or punctuation or if in doubt use the alternate
   3.190 +--	text notation.
   3.191  --
   3.192  -------------------------------------------------------------------------------
   3.193  
   3.194 @@ -25,7 +205,7 @@
   3.195  
   3.196  module("tek.class.markup", tek.class)
   3.197  
   3.198 -_VERSION = "Markup 2.1"
   3.199 +_VERSION = "Markup 2.5"
   3.200  local Markup = _M
   3.201  
   3.202  -------------------------------------------------------------------------------
   3.203 @@ -584,8 +764,11 @@
   3.204  			if not self.preindent or self.indentlevel < self.preindent then
   3.205  				local i = self.indentlevel
   3.206  				while i < self.previndent do
   3.207 +					i = i + 1
   3.208 +					if top() == "pre" then
   3.209 +						i = i + 1
   3.210 +					end
   3.211  					popuntil("indent", "pre")
   3.212 -					i = i + 1
   3.213  				end
   3.214  				self.preindent = nil
   3.215  			end
   3.216 @@ -642,7 +825,7 @@
   3.217  					function(s1, id, text, s2)
   3.218  					local l = min(s1:len() - 1, s2:len() - 1, 5)
   3.219  					popwhilenot("document")
   3.220 -					id = id:gsub("[^a-zA-Z%_%-%.%:]", "")
   3.221 +					id = id:gsub("[^a-zA-Z%d%_%-%.%:]", "")
   3.222  					push("headnode", id, text, l, s2:sub(1, 1) == "}")
   3.223  					return ""
   3.224  				end)
   3.225 @@ -651,7 +834,7 @@
   3.226  					function(s1, text, s2)
   3.227  					local l = min(s1:len() - 1, s2:len() - 1, 5)
   3.228  					popwhilenot("document")
   3.229 -					local id = text:gsub("[^a-zA-Z%_%-%.%:]", "")
   3.230 +					local id = text:gsub("[^a-zA-Z%d%_%-%.%:]", "")
   3.231  					push("headnode", id, text, l, s2:sub(1, 1) == "}")
   3.232  					return ""
   3.233  				end)
   3.234 @@ -818,9 +1001,12 @@
   3.235  								end
   3.236  								if not link then -- [[....]]
   3.237  									a, link, b = line:match("^(.-)%[%[([^%]]-)%]%](.*)%s*$")
   3.238 +									if link then
   3.239 +										title = link:match("^#?(.*)$")
   3.240 +									end
   3.241  								end
   3.242  								if not link then -- class:function()
   3.243 -									a, link, b = line:match("^(.-)(%a[%w_:]-%(%))(.*)%s*$")
   3.244 +									a, link, b = line:match("^(.-)(%a[%w_:.]-%(%))(.*)%s*$")
   3.245  								end
   3.246  								if not link then -- prot://foo/bar
   3.247  									a, link, b = line:match(
     4.1 --- a/cgi-bin/tek/lib/luahtml.c	Fri Jan 04 06:30:34 2008 +0100
     4.2 +++ b/cgi-bin/tek/lib/luahtml.c	Fri May 02 14:42:18 2008 +0200
     4.3 @@ -104,13 +104,13 @@
     4.4  		}
     4.5  		else
     4.6  			c = rd->readchar(rd);
     4.7 -		
     4.8 +
     4.9  		if (c < 0)
    4.10  			return c;
    4.11  
    4.12  		if (c == 254 || c == 255)
    4.13  			break;
    4.14 -		
    4.15 +
    4.16  		if (c < 128)
    4.17  		{
    4.18  			if (rd->numa > 0)
    4.19 @@ -144,7 +144,7 @@
    4.20  				rd->bufc = c;
    4.21  				break;
    4.22  			}
    4.23 -			
    4.24 +
    4.25  			if (c < 224)
    4.26  			{
    4.27  				rd->min = 128;
    4.28 @@ -202,7 +202,7 @@
    4.29  	}
    4.30  	else if (c > 127)
    4.31  		luaL_error(L, "Non-ASCII character outside code or HTML context");
    4.32 -	
    4.33 +
    4.34  	*buf++ = c;
    4.35  	return buf;
    4.36  }
    4.37 @@ -226,7 +226,7 @@
    4.38  	struct readdata *rd = udata;
    4.39  	parser_state_t news = rd->state;
    4.40  	int c;
    4.41 -	
    4.42 +
    4.43  	while ((c = readutf8(&rd->utf8)) >= 0)
    4.44  	{
    4.45  		switch (news)
    4.46 @@ -242,7 +242,7 @@
    4.47  				rd->buf[1] = '[';
    4.48  				*sz = outchar(L, rd->buf + 2, rd->state, c) - rd->buf0;
    4.49  				return (char *) rd->buf0;
    4.50 -			
    4.51 +
    4.52  			case PARSER_HTML:
    4.53  				if (c == '<')
    4.54  				{
    4.55 @@ -250,7 +250,7 @@
    4.56  					continue;
    4.57  				}
    4.58  				break;
    4.59 -			
    4.60 +
    4.61  			case PARSER_OPEN1:
    4.62  				if (c == '%')
    4.63  				{
    4.64 @@ -272,11 +272,12 @@
    4.65  						return (char *) rd->buf0;
    4.66  					}
    4.67  					rd->state = PARSER_VAR;
    4.68 -					strcpy((char *) rd->buf, "]]..(");
    4.69 -					*sz = 5;
    4.70 +					strcpy((char *) rd->buf, "]])");
    4.71 +					memcpy(rd->buf + 3, rd->buf0, rd->buf - rd->buf0);
    4.72 +					*sz = 3 + rd->buf - rd->buf0;
    4.73  					return (char *) rd->buf;
    4.74  				}
    4.75 -				
    4.76 +
    4.77  				if (rd->state == PARSER_UNDEF)
    4.78  					rd->state = PARSER_CODE;
    4.79  				else
    4.80 @@ -291,7 +292,7 @@
    4.81  					return (char *) rd->buf;
    4.82  				}
    4.83  				break;
    4.84 -			
    4.85 +
    4.86  			case PARSER_VAR:
    4.87  			case PARSER_CODE:
    4.88  				if (c == '%')
    4.89 @@ -300,10 +301,11 @@
    4.90  					continue;
    4.91  				}
    4.92  				break;
    4.93 -			
    4.94 +
    4.95  			case PARSER_CLOSE:
    4.96  				if (c == '>')
    4.97  				{
    4.98 +					size_t len;
    4.99  					if (rd->state == PARSER_CODE)
   4.100  					{
   4.101  						rd->state = PARSER_HTML;
   4.102 @@ -313,8 +315,12 @@
   4.103  						return (char *) rd->buf0;
   4.104  					}
   4.105  					rd->state = PARSER_HTML;
   4.106 -					strcpy((char *) rd->buf, " or \"nil\")..[[");
   4.107 -					*sz = 14;
   4.108 +					strcpy((char *) rd->buf, " or \"nil\")");
   4.109 +					memcpy(rd->buf + 10, rd->buf0, rd->buf - rd->buf0);
   4.110 +					len = 10 + rd->buf - rd->buf0;
   4.111 +					rd->buf[len++] = '[';
   4.112 +					rd->buf[len++] = '[';
   4.113 +					*sz = len;
   4.114  					return (char *) rd->buf;
   4.115  				}
   4.116  				rd->buf[0] = '%';
   4.117 @@ -322,18 +328,18 @@
   4.118  				*sz = 2;
   4.119  				return (char *) rd->buf;
   4.120  		}
   4.121 -		
   4.122 +
   4.123  		*sz = outchar(L, rd->buf, rd->state, c) - rd->buf;
   4.124  		return (char *) rd->buf;
   4.125  	}
   4.126 -			
   4.127 +
   4.128  	rd->state = PARSER_UNDEF;
   4.129  	if (news == PARSER_HTML)
   4.130  	{
   4.131  		*sz = 4;
   4.132  		return "]]) ";
   4.133  	}
   4.134 -	
   4.135 +
   4.136  	return NULL;
   4.137  }
   4.138  
   4.139 @@ -344,7 +350,7 @@
   4.140  	const char *outfunc = lua_tostring(L, 2);
   4.141  	const char *chunkname = lua_tostring(L, 3);
   4.142  	int res;
   4.143 -	
   4.144 +
   4.145  	if (lua_isuserdata(L, 1))
   4.146  	{
   4.147  		rd.utf8.file = tofile(L);
   4.148 @@ -355,21 +361,21 @@
   4.149  		rd.utf8.src = (unsigned char *) lua_tolstring(L, 1, &rd.utf8.srclen);
   4.150  		rd.utf8.readchar = readstring;
   4.151  	}
   4.152 -	
   4.153 +
   4.154  	rd.utf8.accu = 0;
   4.155  	rd.utf8.numa = 0;
   4.156  	rd.utf8.bufc = -1;
   4.157 -	
   4.158 +
   4.159  	rd.state = PARSER_UNDEF;
   4.160  	strcpy((char *) rd.buf0, " ");
   4.161  	strcat((char *) rd.buf0, outfunc);
   4.162  	strcat((char *) rd.buf0, "(");
   4.163  	rd.buf = rd.buf0 + strlen((char *) rd.buf0);
   4.164 -	
   4.165 +
   4.166  	res = lua_load(L, readparsed, &rd, chunkname);
   4.167  	if (res == 0)
   4.168  		return 1;
   4.169 -	
   4.170 +
   4.171  	lua_pushnil(L);
   4.172  	lua_insert(L, -2);
   4.173  	/* nil, message on stack */
     5.1 --- a/cgi-bin/tek/os/posix.c	Fri Jan 04 06:30:34 2008 +0100
     5.2 +++ b/cgi-bin/tek/os/posix.c	Fri May 02 14:42:18 2008 +0200
     5.3 @@ -419,7 +419,7 @@
     5.4  
     5.5  static void
     5.6  addclass(lua_State *L, const char *libname, const char *classname,
     5.7 -	luaL_Reg *functions, luaL_Reg *methods, void *userdata)
     5.8 +	const luaL_Reg *functions, const luaL_Reg *methods, void *userdata)
     5.9  {
    5.10  	luaL_newmetatable(L, classname); /* classtab */
    5.11  	lua_pushliteral(L, "__index"); /* classtab, "__index" */
    5.12 @@ -448,7 +448,6 @@
    5.13  
    5.14  int luaopen_tek_os_posix(lua_State *L)
    5.15  {
    5.16 -	addclass(L, "tek.os.posix", DIRCLASSNAME,
    5.17 -		(luaL_Reg *) lib, (luaL_Reg *) methods, NULL);
    5.18 +	addclass(L, "tek.os.posix", DIRCLASSNAME, lib, methods, NULL);
    5.19  	return 0;
    5.20  }