2 #// converts bbcode to html.
\r
5 #// Copyright (C) 2015 Balthasar Szczepański
\r
7 #// This program is free software: you can redistribute it and/or modify
\r
8 #// it under the terms of the GNU Affero General Public License as
\r
9 #// published by the Free Software Foundation, either version 3 of the
\r
10 #// License, or (at your option) any later version.
\r
12 #// This program is distributed in the hope that it will be useful,
\r
13 #// but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 #// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
15 #// GNU Affero General Public License for more details.
\r
17 #// You should have received a copy of the GNU Affero General Public License
\r
18 #// along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
23 debug="debug=bb2html.awk:"
\r
24 automome="/eizm/pro/ong1/mome.pl"
\r
25 memepath="/eizm/mem/ong1/mome.txt"
\r
30 hex=sprintf("%02X",i)
\r
38 argtab[substr($0,1,eq-1)]=substr($0,eq+1)
\r
41 if(argtab["disable_bbcode"]!="")
\r
43 debug=debug"###nl;BBcode disabled"
\r
44 print debug>>outfile
\r
49 print "HTML="html>>outfile
\r
50 print debug>>outfile
\r
54 # text=argtab["message"]
\r
55 # gsub(/%5Bbr%5D/,"\n",text)
\r
56 # while(sub(/%5Bong%5D/,ong(),text)>0){print text}
\r
57 # while(sub(/%5Bung%5D/,ung(),text)>0){print text}
\r
58 # while(sub(/%5Bong%3Ddecree%5D/,ong("decree"),text)>0){print text}
\r
59 # while(sub(/%5Bung%3Ddecree%5D/,ung("decree"),text)>0){print text}
\r
60 # if(text!=argtab["message"])
\r
61 # print "message="text >> outfile
\r
65 function bb2html(text, depth,count,bbtree,html,tag,tagstart,taglength,elm,tagv,tagname,tagvalue,matchname)
\r
71 bbtree["0.t"]="post"
\r
72 bbtree["0.v"]=argtab["subject"]
\r
74 gsub(/=/,"=",text)
\r
75 debug = debug "###nl;###nl;Build BBcode tree:"
\r
76 while(length(text)!=0)
\r
78 tag=match(text, /\[\/?[a-z0-9\*]+(=(([^\[<>\"\]]*)|(\"[^\"<>]*\")))?\]/)
\r
80 # debug = debug "###nl;" RSTART " " RLENGTH
\r
83 debug = debug "###nl;text: " text
\r
84 bbtree[ind(count,depth)]=text
\r
85 bbtree[indt(count,depth)".n"]=count[depth]
\r
94 elm=substr(text,1,tagstart-1)
\r
95 debug = debug "###nl;text: " elm
\r
96 bbtree[ind(count,depth)]=elm
\r
97 bbtree[indt(count,depth)".n"]=count[depth]
\r
100 tag=substr(text,tagstart,taglength)
\r
101 text=substr(text,tagstart+taglength)
\r
102 debug = debug "###nl;tag: " tag
\r
105 tagv=index(tag,"=")
\r
108 tagname=substr(tag,2,length(tag)-2)
\r
113 tagname=substr(tag,2,tagv-2)
\r
114 tagvalue=substr(tag,tagv+1,length(tag)-tagv-1)
\r
116 if(tagname !~ /^((quote)|b|i|u|(code)|(img)|(url)|(size)|(color)|(center)|(right)|(sub)|(sup)|(s)|(spoiler)|(list)|(\*))$/)
\r
118 debug = debug "###nl;unknown tag"
\r
119 bbtree[ind(count,depth)]=tag
\r
120 bbtree[indt(count,depth)".n"]=count[depth]
\r
124 if((bbtree[indt(count,depth)".t"] == "code" && tagname!="code")||bbtree[indt(count,depth)".t"] == "img"||(bbtree[indt(count,depth)".t"] == "spoiler" && tagname=="spoiler")||(bbtree[indt(count,depth)".t"] == "size" && tagname=="size"))
\r
126 debug = debug "###nl;this tag forbidden here"
\r
127 bbtree[ind(count,depth)]=tag
\r
128 bbtree[indt(count,depth)".n"]=count[depth]
\r
134 if(bbtree[indt(count,depth)".t"]==tagname)
\r
136 debug = debug "###nl;implied tag: [/"tagname"]"
\r
137 debug = debug "###nl;matched"
\r
138 bbtree[ind(count,depth)]="[/"tagname"]"
\r
139 bbtree[ind(count,depth)".k"]="e"
\r
140 bbtree[ind(count,depth)".m"]=1
\r
141 bbtree[ind(count,depth)".t"]=tagname
\r
142 bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"]
\r
143 bbtree[indt(count,depth)".n"]=count[depth]
\r
144 bbtree[indt(count,depth)".m"]=1
\r
149 else if(bbtree[indt(count,depth)".t"]!="list")
\r
151 debug = debug "###nl;this tag forbidden here"
\r
152 bbtree[ind(count,depth)]=tag
\r
153 bbtree[indt(count,depth)".n"]=count[depth]
\r
158 debug = debug "###nl;name: " tagname " value: " tagvalue
\r
159 bbtree[ind(count,depth)]=tagname" "tagvalue
\r
160 bbtree[ind(count,depth)".k"]="s"
\r
161 bbtree[indt(count,depth)".n"]=count[depth]
\r
164 bbtree[indt(count,depth)]=tag
\r
165 bbtree[indt(count,depth)".n"]=0
\r
166 bbtree[indt(count,depth)".t"]=tagname
\r
167 bbtree[indt(count,depth)".v"]=tagvalue
\r
173 debug = debug "###nl;""unmatched"
\r
174 bbtree[ind(count,depth)]=tag
\r
175 bbtree[indt(count,depth)".n"]=count[depth]
\r
179 tagname=substr(tag,3,length(tag)-3)
\r
180 if(tagname=="list"&&bbtree[indt(count,depth)".t"]=="*")
\r
182 debug = debug "###nl;implied tag: [/*]"
\r
183 debug = debug "###nl;matched"
\r
184 bbtree[ind(count,depth)]="[/*]"
\r
185 bbtree[ind(count,depth)".k"]="e"
\r
186 bbtree[ind(count,depth)".m"]=1
\r
187 bbtree[ind(count,depth)".t"]="*"
\r
188 bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"]
\r
189 bbtree[indt(count,depth)".n"]=count[depth]
\r
190 bbtree[indt(count,depth)".m"]=1
\r
195 debug = debug "###nl;name: " tagname
\r
196 matchname=bbtree[indt(count,depth)".t"]
\r
197 if((bbtree[indt(count,depth)".t"] == "code" && tagname!="code")||(bbtree[indt(count,depth)".t"] == "img" && tagname != "img"))
\r
199 debug = debug "###nl;this tag forbidden here"
\r
200 bbtree[ind(count,depth)]=tag
\r
201 bbtree[indt(count,depth)".n"]=count[depth]
\r
205 if(tagname!=matchname)
\r
207 debug = debug "###nl;mismatched: " matchname
\r
208 # bbtree[ind(count,depth)]=tag
\r
209 # bbtree[indt(count,depth)".n"]=count[depth]
\r
212 bbtree[ind(count,depth)]=tag
\r
213 bbtree[ind(count,depth)".k"]="e"
\r
214 bbtree[ind(count,depth)".t"]=bbtree[indt(count,depth)".t"]
\r
215 bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"]
\r
216 bbtree[indt(count,depth)".n"]=count[depth]
\r
222 debug = debug "###nl;matched"
\r
223 bbtree[ind(count,depth)]=tag
\r
224 bbtree[ind(count,depth)".k"]="e"
\r
225 bbtree[ind(count,depth)".m"]=1
\r
226 bbtree[ind(count,depth)".t"]=tagname
\r
227 bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"]
\r
228 bbtree[indt(count,depth)".n"]=count[depth]
\r
229 bbtree[indt(count,depth)".m"]=1
\r
236 debug = debug "###nl;unclosed tags: " depth
\r
238 debug = debug "###nl;###nl;""generate HTML:"
\r
241 while(count[0]<=bbtree["0.n"]&&depth>=0)
\r
243 if(count[depth]==0)
\r
245 tag=bbtree[indt(count,depth)]
\r
246 tagname=bbtree[indt(count,depth)".t"]
\r
247 tagvalue=bbtree[indt(count,depth)".v"]
\r
248 debug = debug "###nl;name: "tagname" value: "tagvalue" elements: "bbtree[indt(count,depth)".n"]
\r
249 if(tagname == "post")
\r
252 else if(bbtree[indt(count,depth)".m"]=="")
\r
254 debug = debug "###nl;unmatched"
\r
257 else if(tagname == "quote")
\r
261 html = html "<blockquote class=\"pq\"><div>"
\r
265 if(tagvalue !~ /^\".*\"$/)
\r
267 tagvalue="You forgot about the quote marks, "tagvalue
\r
269 tagvalue=bb2html(substr(tagvalue,2,length(tagvalue)-2))
\r
270 html = html "<blockquote class=\"pq\"><div><cite class=\"pq\"><b class=\"br\">"tagvalue"</b> wrote:</cite><br>"
\r
273 else if (tagname == "b")
\r
275 html = html"<span style=\"font-weight: bold\">"
\r
277 html=html"This tag shouldn't have any value. "
\r
279 else if (tagname == "i")
\r
281 html = html"<span style=\"font-style: italic\">"
\r
283 html=html"This tag shouldn't have any value. "
\r
285 else if (tagname == "u")
\r
287 html = html"<span style=\"text-decoration: underline\">"
\r
289 html=html"This tag shouldn't have any value. "
\r
291 else if (tagname == "code")
\r
293 if(bbtree[indtu(count,depth)".t"] == "code")
\r
296 debug = debug "###nl;not a tag, actually"
\r
300 html=html"<dl class=\"pq\"><dt class=\"pq\">Code: <a href=\"#\" onclick=\"selectCode(this); return false;\">Select all</a></dt><dd><code class=\"pq\">"
\r
302 html=html"This tag shouldn't have any value. "
\r
305 else if (tagname == "img")
\r
306 html=html"<img src=\""
\r
307 else if (tagname == "url")
\r
312 tagvalue=bbtree[ind(count,depth)]
\r
314 debug = debug "###nl;implied value: " tagvalue
\r
316 html=html"<a href=\""tagvalue"\" class=\"postlink\">"
\r
318 else if (tagname == "size")
\r
320 if (tagvalue==""||(tagvalue !~ /^[0-9]+$/)||(tagvalue+0)>200)
\r
321 html=html"<span style=\"font-size: 130%; line-height: 116%;\"> This tag should have a correct value. "
\r
323 html=html"<span style=\"font-size: "tagvalue"%; line-height: 116%;\">"
\r
325 else if (tagname == "color")
\r
327 if (tagvalue==""||tagvalue !~ /^#[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]$/) #for some reason /^([0-9A-F]{6})$/ doesn't work.
\r
328 html=html"<span style=\"color: #EE0000\"> This tag should have a correct value. "
\r
330 html=html"<span style=\"color: "tagvalue"\">"
\r
332 else if (tagname ~ /^((center)|(right))$/)
\r
334 html=html"<div align=\""tagname"\">"
\r
336 html=html"This tag shouldn't have any value. "
\r
338 else if (tagname =="s")
\r
340 html=html"<strike>"
\r
342 html=html"This tag shouldn't have any value. "
\r
344 else if (tagname =="sub")
\r
348 html=html"This tag shouldn't have any value. "
\r
350 else if (tagname =="sup")
\r
354 html=html"This tag shouldn't have any value. "
\r
356 else if (tagname=="spoiler")
\r
358 html=html"<div style=\"margin:20px; margin-top:5px\"><div class=\"quotetitle\"><b>Spoiler:</b> <input type=\"button\" class=\"pk\" value=\"Show\" style=\"width:45px;font-size:10px;margin:0px;padding:0px;\" onclick=\"if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.innerText = ''; this.value = 'Hide'; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value = 'Show'; }\" /></div><div class=\"quotecontent\"><div style=\"display: none;\">"
\r
360 html=html"This tag shouldn't have any value. "
\r
362 else if (tagname=="list")
\r
370 else if (tagvalue=="i")
\r
371 tagvalue="lower-roman"
\r
372 else if (tagvalue=="I")
\r
373 tagvalue="upper-roman"
\r
374 else if (tagvalue=="a")
\r
375 tagvalue="lower-alpha"
\r
376 else if (tagvalue=="A")
\r
377 tagvalue="upper-alpha"
\r
380 html=html"This tag should have a correct value. "
\r
383 html=html"<ol style=\"list-style-type: "tagvalue"\">"
\r
386 else if (tagname=="*")
\r
390 html=html"This tag shouldn't have any value. "
\r
394 debug = debug "###nl;unknown tag"
\r
399 else if(bbtree[ind(count,depth)".k"]=="s")
\r
401 debug = debug "###nl;entering tag:"
\r
405 else if(bbtree[ind(count,depth)".k"]=="e")
\r
407 debug = debug "###nl;leaving tag:"
\r
408 tag=bbtree[ind(count,depth)]
\r
409 tagname=bbtree[ind(count,depth)".t"]
\r
410 tagvalue=bbtree[ind(count,depth)".v"]
\r
411 debug = debug "###nl;name: "tagname" value: "tagvalue
\r
412 if (tagname == "post")
\r
415 else if(bbtree[ind(count,depth)".m"]=="")
\r
417 debug = debug "###nl;unmatched"
\r
420 else if(tagname == "quote")
\r
421 html = html "</div></blockquote>"
\r
422 else if (tagname ~/^(b|i|u|(size)|(color))$/)
\r
423 html = html"</span>"
\r
424 else if (tagname == "code")
\r
426 if(bbtree[indtu(count,depth)".t"] == "code")
\r
429 debug = debug "###nl;not a tag, actually"
\r
432 html = html"</code></dd></dl>"
\r
434 else if (tagname == "img")
\r
436 html = html"\" alt=\"Image\" />"
\r
438 html=html"This tag shouldn't have any value. "
\r
440 else if(tagname=="url")
\r
442 else if (tagname ~ /^((center)|(right))$/)
\r
444 else if (tagname =="s")
\r
445 html=html"</strike>"
\r
446 else if (tagname =="sub")
\r
448 else if (tagname =="sup")
\r
450 else if (tagname=="spoiler")
\r
451 html=html"</div></div></div>"
\r
452 else if (tagname=="list")
\r
459 else if (tagname=="*")
\r
463 debug = debug "###nl;unknown tag"
\r
470 else if(count[depth]>bbtree[indt(count,depth)".n"])
\r
472 debug = debug "###nl;run out of elements in this tag; leaving"
\r
479 tag=bbtree[ind(count,depth)]
\r
480 debug = debug "###nl;text: "tag
\r
481 if(bbtree[indt(count,depth)".t"] == "code")
\r
483 # gsub(/ ?<br> ?/,"<br>",tag)
\r
484 gsub(/ /,"\\ ",tag)
\r
485 gsub(/\t/,"\\ \\ ",tag)
\r
487 if(argtab["disable_magic_url"]==""&& bbtree[indt(count,depth)".t"] !~ /^((code)|(img)|(url))$/)
\r
488 gsub(/https?:\/\/[^\n\r\t<> ]+/,"<a href=\"&\" class=\"postlink\">&</a>",tag)
\r
489 if(argtab["disable_smilies"]=="" && bbtree[indt(count,depth)".t"] !~ /^((code)|(img))$/)
\r
491 gsub(/(^|[\n\r\t ]):D($|[\n\r\t ])/," <img title=\"Very Happy\" alt=\":D\" src=\"/ott/prosilver/smilies/icon_biggrin.gif\" /> ",tag)
\r
492 gsub(/(^|[\n\r\t ]):\)($|[\n\r\t ])/," <img title=\"Smile\" alt=\":)\" src=\"/ott/prosilver/smilies/icon_smile.gif\" /> ",tag)
\r
493 gsub(/(^|[\n\r\t ]):\(($|[\n\r\t ])/," <img title=\"Sad\" alt=\":(\" src=\"/ott/prosilver/smilies/icon_sad.gif\" /> ",tag)
\r
494 gsub(/(^|[\n\r\t ]):o($|[\n\r\t ])/," <img title=\"Surprised\" alt=\":o\" src=\"/ott/prosilver/smilies/icon_surprised.gif\" /> ",tag)
\r
495 gsub(/(^|[\n\r\t ]):shock:($|[\n\r\t ])/," <img title=\"Shocked\" alt=\":shock:\" src=\"/ott/prosilver/smilies/icon_eek.gif\" /> ",tag)
\r
496 gsub(/(^|[\n\r\t ]):\?($|[\n\r\t ])/," <img title=\"Confused\" alt=\":?\" src=\"/ott/prosilver/smilies/icon_confused.gif\" /> ",tag)
\r
497 gsub(/(^|[\n\r\t ])8-\)($|[\n\r\t ])/," <img title=\"Cool\" alt=\"8-)\" src=\"/ott/prosilver/smilies/icon_cool.gif\" /> ",tag)
\r
498 gsub(/(^|[\n\r\t ]):lol:($|[\n\r\t ])/," <img title=\"Laughing\" alt=\":lol:\" src=\"/ott/prosilver/smilies/icon_lol.gif\" /> ",tag)
\r
499 gsub(/(^|[\n\r\t ]):x($|[\n\r\t ])/," <img title=\"Mad\" alt=\":x\" src=\"/ott/prosilver/smilies/icon_mad.gif\" /> ",tag)
\r
500 gsub(/(^|[\n\r\t ]):P($|[\n\r\t ])/," <img title=\"Razz\" alt=\":P\" src=\"/ott/prosilver/smilies/icon_razz.gif\" /> ",tag)
\r
501 gsub(/(^|[\n\r\t ]):oops:($|[\n\r\t ])/," <img title=\"Embarassed\" alt=\":oops:\" src=\"/ott/prosilver/smilies/icon_redface.gif\" /> ",tag)
\r
502 gsub(/(^|[\n\r\t ]):cry:($|[\n\r\t ])/," <img title=\"Crying or Very Sad\" alt=\":cry:\" src=\"/ott/prosilver/smilies/icon_cry.gif\" /> ",tag)
\r
503 gsub(/(^|[\n\r\t ]):evil:($|[\n\r\t ])/," <img title=\"Evil or Very Mad\" alt=\":evil:\" src=\"/ott/prosilver/smilies/icon_evil.gif\" /> ",tag)
\r
504 gsub(/(^|[\n\r\t ]):twisted:($|[\n\r\t ])/," <img title=\"Twisted Evil\" alt=\":twisted:\" src=\"/ott/prosilver/smilies/icon_twisted.gif\" /> ",tag)
\r
505 gsub(/(^|[\n\r\t ]):roll:($|[\n\r\t ])/," <img title=\"Rolling Eyes\" alt=\":roll:\" src=\"/ott/prosilver/smilies/icon_rolleyes.gif\" /> ",tag)
\r
506 gsub(/(^|[\n\r\t ]):wink:($|[\n\r\t ])/," <img title=\"Wink\" alt=\":wink:\" src=\"/ott/prosilver/smilies/icon_wink.gif\" /> ",tag)
\r
507 gsub(/(^|[\n\r\t ]);\)($|[\n\r\t ])/," <img title=\"Wink\" alt=\":wink:\" src=\"/ott/prosilver/smilies/icon_wink.gif\" /> ",tag)
\r
508 gsub(/(^|[\n\r\t ]):!:($|[\n\r\t ])/," <img title=\"Exclamation\" alt=\":!:\" src=\"/ott/prosilver/smilies/icon_exclaim.gif\" /> ",tag)
\r
509 gsub(/(^|[\n\r\t ]):\?:($|[\n\r\t ])/," <img title=\"Question\" alt=\":?:\" src=\"/ott/prosilver/smilies/icon_question.gif\" /> ",tag)
\r
510 gsub(/(^|[\n\r\t ]):idea:($|[\n\r\t ])/," <img title=\"Idea\" alt=\":idea:\" src=\"/ott/prosilver/smilies/icon_idea.gif\" /> ",tag)
\r
511 gsub(/(^|[\n\r\t ]):arrow:($|[\n\r\t ])/," <img title=\"Arrow\" alt=\":arrow:\" src=\"/ott/prosilver/smilies/icon_arrow.gif\" /> ",tag)
\r
512 gsub(/(^|[\n\r\t ]):\|($|[\n\r\t ])/," <img title=\"Neutral\" alt=\":|\" src=\"/ott/prosilver/smilies/icon_neutral.gif\" /> ",tag)
\r
513 gsub(/(^|[\n\r\t ]):mrgreen:($|[\n\r\t ])/," <img title=\"Mr. Green\" alt=\":mrgreen:\" src=\"/ott/prosilver/smilies/icon_mrgreen.gif\" /> ",tag)
\r
520 debug = debug "###nl;done"
\r
524 function ind(count,depth, ii,iindex)
\r
527 for(ii=0;ii<=depth;++ii)
\r
530 iindex = iindex "."
\r
531 iindex = iindex count[ii]
\r
533 # debug = debug "###nl;" iindex
\r
536 function indt(count,depth, ii,iindex)
\r
539 for(ii=0;ii<depth;++ii)
\r
542 iindex = iindex "."
\r
543 iindex = iindex count[ii]
\r
547 iindex = iindex "0"
\r
548 # debug = debug "###nl;" iindex
\r
551 function indtu(count,depth, ii,iindex)
\r
554 for(ii=0;ii<depth-1;++ii)
\r
557 iindex = iindex "."
\r
558 iindex = iindex count[ii]
\r
562 iindex = iindex "0"
\r
563 # debug = debug "###nl;" iindex
\r
566 function ong(decree, line)
\r
568 system (automome" -lc 256 -n 67 -d "memepath(decree!=""?" -t \"[decr]\"":"")" > "tempfile)
\r
570 while((getline line < tempfile)>0)
\r
572 gsub(/[\r\n]/,"",line)
\r
573 if(sub(/[AEIOUY]-N-G/,"#O-N-G#",line)>0)
\r
576 return preparebb(line)
\r
578 if(sub(/O+N+G+/,"#&#",line)>0)
\r
581 return preparebb(line)
\r
583 if(sub(/DON'T/,"D#ON'G#T",line)>0)
\r
586 return preparebb(line)
\r
588 if(sub(/[AEIOUY]NG/,"#ONG#",line)>0)
\r
590 if($0!~/TH\[b\]ONG/)
\r
591 return preparebb(line)
\r
593 if(sub(/ON /,"#ONG# ",line)>0)
\r
596 return preparebb(line)
\r
598 if(sub(/O\.?$/,"#ONG# ",$0)>0)
\r
601 return preparebb(line)
\r
608 function ung(decree, line)
\r
610 system (automome" -lc 256 -n 67 -d "memepath(decree!=""?" -t \"[decr]\"":"")" > "tempfile)
\r
612 while((getline line < tempfile)>0)
\r
614 gsub(/[\r\n]/,"",line)
\r
615 if(sub(/[AEIOUY]-N-G/,"#U-N-G#",line)>0)
\r
618 return preparebb(line)
\r
620 if(sub(/U+N+G+/,"#&#",line)>0)
\r
623 return preparebb(line)
\r
625 if(sub(/[AEIOUY]NG/,"#UNG#",line)>0)
\r
628 return preparebb(line)
\r
630 if(sub(/UN /,"#UNG# ",line)>0)
\r
633 return preparebb(line)
\r
635 if(sub(/U\.?$/,"#UNG# ",$0)>0)
\r
638 return preparebb(line)
\r
645 function preparebb(rh)
\r
649 gsub(/\*\*/,"¤",rh)
\r
650 gsub(/\*[^\*]+\*/,"±&±",rh)
\r
651 gsub(/±\*/,"[i]",rh)
\r
652 gsub(/\*±/,"[/i]",rh)
\r
656 gsub(/_[^_]+_/,"±&±",rh)
\r
657 gsub(/±_/,"[u]",rh)
\r
658 gsub(/_±/,"[/u]",rh)
\r
662 gsub(/#[^#]+#/,"±&±",rh)
\r
663 gsub(/±#/,"[b]",rh)
\r
664 gsub(/#±/,"[/b]",rh)
\r
667 gsub(/\$\$/,"¤",rh)
\r
668 gsub(/\$[^\$]+\$/,"±&±",rh)
\r
669 gsub(/±\$/,"[size=80]",rh)
\r
670 gsub(/\$±/,"[/size]",rh)
\r
674 return rh (nobb==""?" -- [url=http://mrob.com/time/automome]automome[/url]":" -- automome")
\r
676 function urlencode(name,all, len,iii,escaped,ch)
\r
680 for(iii=1;iii<=len;++iii)
\r
682 ch=substr(name,iii,1);
\r
683 if ((ch ~ /[a-zA-Z0-9\.\-_~]/)&&(all==""))
\r
684 escaped = escaped ch
\r
686 escaped = escaped "%" ch2hex[ch]
\r