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
22 debug="debug=bb2html.awk:"
\r
23 automome="/eizm/pro/ong1/mome.pl"
\r
24 memepath="/eizm/mem/ong1/mome.txt"
\r
29 hex=sprintf("%02X",i)
\r
37 argtab[substr($0,1,eq-1)]=substr($0,eq+1)
\r
40 if(argtab["disable_bbcode"]!="")
\r
42 debug=debug"###nl;BBcode disabled"
\r
43 print debug>>outfile
\r
48 print "HTML="html>>outfile
\r
49 print debug>>outfile
\r
53 # text=argtab["message"]
\r
54 # gsub(/%5Bbr%5D/,"\n",text)
\r
55 # while(sub(/%5Bong%5D/,ong(),text)>0){print text}
\r
56 # while(sub(/%5Bung%5D/,ung(),text)>0){print text}
\r
57 # while(sub(/%5Bong%3Ddecree%5D/,ong("decree"),text)>0){print text}
\r
58 # while(sub(/%5Bung%3Ddecree%5D/,ung("decree"),text)>0){print text}
\r
59 # if(text!=argtab["message"])
\r
60 # print "message="text >> outfile
\r
64 function bb2html(text, depth,count,bbtree,html,tag,tagstart,taglength,elm,tagv,tagname,tagvalue,matchname)
\r
70 bbtree["0.t"]="post"
\r
71 bbtree["0.v"]=argtab["subject"]
\r
73 gsub(/=/,"=",text)
\r
74 debug = debug "###nl;###nl;Build BBcode tree:"
\r
75 while(length(text)!=0)
\r
77 tag=match(text, /\[\/?[a-z0-9\*]+(=(([^\[<>\"\]]*)|(\"[^\"<>]*\")))?\]/)
\r
79 # debug = debug "###nl;" RSTART " " RLENGTH
\r
82 debug = debug "###nl;text: " text
\r
83 bbtree[ind(count,depth)]=text
\r
84 bbtree[indt(count,depth)".n"]=count[depth]
\r
93 elm=substr(text,1,tagstart-1)
\r
94 debug = debug "###nl;text: " elm
\r
95 bbtree[ind(count,depth)]=elm
\r
96 bbtree[indt(count,depth)".n"]=count[depth]
\r
99 tag=substr(text,tagstart,taglength)
\r
100 text=substr(text,tagstart+taglength)
\r
101 debug = debug "###nl;tag: " tag
\r
104 tagv=index(tag,"=")
\r
107 tagname=substr(tag,2,length(tag)-2)
\r
112 tagname=substr(tag,2,tagv-2)
\r
113 tagvalue=substr(tag,tagv+1,length(tag)-tagv-1)
\r
115 if(tagname !~ /^((quote)|b|i|u|(code)|(img)|(url)|(size)|(color)|(center)|(right)|(sub)|(sup)|(s)|(spoiler)|(list)|(\*))$/)
\r
117 debug = debug "###nl;unknown tag"
\r
118 bbtree[ind(count,depth)]=tag
\r
119 bbtree[indt(count,depth)".n"]=count[depth]
\r
123 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
125 debug = debug "###nl;this tag forbidden here"
\r
126 bbtree[ind(count,depth)]=tag
\r
127 bbtree[indt(count,depth)".n"]=count[depth]
\r
133 if(bbtree[indt(count,depth)".t"]==tagname)
\r
135 debug = debug "###nl;implied tag: [/"tagname"]"
\r
136 debug = debug "###nl;matched"
\r
137 bbtree[ind(count,depth)]="[/"tagname"]"
\r
138 bbtree[ind(count,depth)".k"]="e"
\r
139 bbtree[ind(count,depth)".m"]=1
\r
140 bbtree[ind(count,depth)".t"]=tagname
\r
141 bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"]
\r
142 bbtree[indt(count,depth)".n"]=count[depth]
\r
143 bbtree[indt(count,depth)".m"]=1
\r
148 else if(bbtree[indt(count,depth)".t"]!="list")
\r
150 debug = debug "###nl;this tag forbidden here"
\r
151 bbtree[ind(count,depth)]=tag
\r
152 bbtree[indt(count,depth)".n"]=count[depth]
\r
157 debug = debug "###nl;name: " tagname " value: " tagvalue
\r
158 bbtree[ind(count,depth)]=tagname" "tagvalue
\r
159 bbtree[ind(count,depth)".k"]="s"
\r
160 bbtree[indt(count,depth)".n"]=count[depth]
\r
163 bbtree[indt(count,depth)]=tag
\r
164 bbtree[indt(count,depth)".n"]=0
\r
165 bbtree[indt(count,depth)".t"]=tagname
\r
166 bbtree[indt(count,depth)".v"]=tagvalue
\r
172 debug = debug "###nl;""unmatched"
\r
173 bbtree[ind(count,depth)]=tag
\r
174 bbtree[indt(count,depth)".n"]=count[depth]
\r
178 tagname=substr(tag,3,length(tag)-3)
\r
179 if(tagname=="list"&&bbtree[indt(count,depth)".t"]=="*")
\r
181 debug = debug "###nl;implied tag: [/*]"
\r
182 debug = debug "###nl;matched"
\r
183 bbtree[ind(count,depth)]="[/*]"
\r
184 bbtree[ind(count,depth)".k"]="e"
\r
185 bbtree[ind(count,depth)".m"]=1
\r
186 bbtree[ind(count,depth)".t"]="*"
\r
187 bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"]
\r
188 bbtree[indt(count,depth)".n"]=count[depth]
\r
189 bbtree[indt(count,depth)".m"]=1
\r
194 debug = debug "###nl;name: " tagname
\r
195 matchname=bbtree[indt(count,depth)".t"]
\r
196 if((bbtree[indt(count,depth)".t"] == "code" && tagname!="code")||(bbtree[indt(count,depth)".t"] == "img" && tagname != "img"))
\r
198 debug = debug "###nl;this tag forbidden here"
\r
199 bbtree[ind(count,depth)]=tag
\r
200 bbtree[indt(count,depth)".n"]=count[depth]
\r
204 if(tagname!=matchname)
\r
206 debug = debug "###nl;mismatched: " matchname
\r
207 # bbtree[ind(count,depth)]=tag
\r
208 # bbtree[indt(count,depth)".n"]=count[depth]
\r
211 bbtree[ind(count,depth)]=tag
\r
212 bbtree[ind(count,depth)".k"]="e"
\r
213 bbtree[ind(count,depth)".t"]=bbtree[indt(count,depth)".t"]
\r
214 bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"]
\r
215 bbtree[indt(count,depth)".n"]=count[depth]
\r
221 debug = debug "###nl;matched"
\r
222 bbtree[ind(count,depth)]=tag
\r
223 bbtree[ind(count,depth)".k"]="e"
\r
224 bbtree[ind(count,depth)".m"]=1
\r
225 bbtree[ind(count,depth)".t"]=tagname
\r
226 bbtree[ind(count,depth)".v"]=bbtree[indt(count,depth)".v"]
\r
227 bbtree[indt(count,depth)".n"]=count[depth]
\r
228 bbtree[indt(count,depth)".m"]=1
\r
235 debug = debug "###nl;unclosed tags: " depth
\r
237 debug = debug "###nl;###nl;""generate HTML:"
\r
240 while(count[0]<=bbtree["0.n"]&&depth>=0)
\r
242 if(count[depth]==0)
\r
244 tag=bbtree[indt(count,depth)]
\r
245 tagname=bbtree[indt(count,depth)".t"]
\r
246 tagvalue=bbtree[indt(count,depth)".v"]
\r
247 debug = debug "###nl;name: "tagname" value: "tagvalue" elements: "bbtree[indt(count,depth)".n"]
\r
248 if(tagname == "post")
\r
251 else if(bbtree[indt(count,depth)".m"]=="")
\r
253 debug = debug "###nl;unmatched"
\r
256 else if(tagname == "quote")
\r
260 html = html "<blockquote class=\"pq\"><div>"
\r
264 if(tagvalue !~ /^\".*\"$/)
\r
266 tagvalue="You forgot about the quote marks, "tagvalue
\r
268 tagvalue=bb2html(substr(tagvalue,2,length(tagvalue)-2))
\r
269 html = html "<blockquote class=\"pq\"><div><cite class=\"pq\"><b class=\"br\">"tagvalue"</b> wrote:</cite><br>"
\r
272 else if (tagname == "b")
\r
274 html = html"<span style=\"font-weight: bold\">"
\r
276 html=html"This tag shouldn't have any value. "
\r
278 else if (tagname == "i")
\r
280 html = html"<span style=\"font-style: italic\">"
\r
282 html=html"This tag shouldn't have any value. "
\r
284 else if (tagname == "u")
\r
286 html = html"<span style=\"text-decoration: underline\">"
\r
288 html=html"This tag shouldn't have any value. "
\r
290 else if (tagname == "code")
\r
292 if(bbtree[indtu(count,depth)".t"] == "code")
\r
295 debug = debug "###nl;not a tag, actually"
\r
299 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
301 html=html"This tag shouldn't have any value. "
\r
304 else if (tagname == "img")
\r
305 html=html"<img src=\""
\r
306 else if (tagname == "url")
\r
311 tagvalue=bbtree[ind(count,depth)]
\r
313 debug = debug "###nl;implied value: " tagvalue
\r
315 html=html"<a href=\""tagvalue"\" class=\"postlink\">"
\r
317 else if (tagname == "size")
\r
319 if (tagvalue==""||(tagvalue !~ /^[0-9]+$/)||(tagvalue+0)>200)
\r
320 html=html"<span style=\"font-size: 130%; line-height: 116%;\"> This tag should have a correct value. "
\r
322 html=html"<span style=\"font-size: "tagvalue"%; line-height: 116%;\">"
\r
324 else if (tagname == "color")
\r
326 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
327 html=html"<span style=\"color: #EE0000\"> This tag should have a correct value. "
\r
329 html=html"<span style=\"color: "tagvalue"\">"
\r
331 else if (tagname ~ /^((center)|(right))$/)
\r
333 html=html"<div align=\""tagname"\">"
\r
335 html=html"This tag shouldn't have any value. "
\r
337 else if (tagname =="s")
\r
339 html=html"<strike>"
\r
341 html=html"This tag shouldn't have any value. "
\r
343 else if (tagname =="sub")
\r
347 html=html"This tag shouldn't have any value. "
\r
349 else if (tagname =="sup")
\r
353 html=html"This tag shouldn't have any value. "
\r
355 else if (tagname=="spoiler")
\r
357 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
359 html=html"This tag shouldn't have any value. "
\r
361 else if (tagname=="list")
\r
369 else if (tagvalue=="i")
\r
370 tagvalue="lower-roman"
\r
371 else if (tagvalue=="I")
\r
372 tagvalue="upper-roman"
\r
373 else if (tagvalue=="a")
\r
374 tagvalue="lower-alpha"
\r
375 else if (tagvalue=="A")
\r
376 tagvalue="upper-alpha"
\r
379 html=html"This tag should have a correct value. "
\r
382 html=html"<ol style=\"list-style-type: "tagvalue"\">"
\r
385 else if (tagname=="*")
\r
389 html=html"This tag shouldn't have any value. "
\r
393 debug = debug "###nl;unknown tag"
\r
398 else if(bbtree[ind(count,depth)".k"]=="s")
\r
400 debug = debug "###nl;entering tag:"
\r
404 else if(bbtree[ind(count,depth)".k"]=="e")
\r
406 debug = debug "###nl;leaving tag:"
\r
407 tag=bbtree[ind(count,depth)]
\r
408 tagname=bbtree[ind(count,depth)".t"]
\r
409 tagvalue=bbtree[ind(count,depth)".v"]
\r
410 debug = debug "###nl;name: "tagname" value: "tagvalue
\r
411 if (tagname == "post")
\r
414 else if(bbtree[ind(count,depth)".m"]=="")
\r
416 debug = debug "###nl;unmatched"
\r
419 else if(tagname == "quote")
\r
420 html = html "</div></blockquote>"
\r
421 else if (tagname ~/^(b|i|u|(size)|(color))$/)
\r
422 html = html"</span>"
\r
423 else if (tagname == "code")
\r
425 if(bbtree[indtu(count,depth)".t"] == "code")
\r
428 debug = debug "###nl;not a tag, actually"
\r
431 html = html"</code></dd></dl>"
\r
433 else if (tagname == "img")
\r
435 html = html"\" alt=\"Image\" />"
\r
437 html=html"This tag shouldn't have any value. "
\r
439 else if(tagname=="url")
\r
441 else if (tagname ~ /^((center)|(right))$/)
\r
443 else if (tagname =="s")
\r
444 html=html"</strike>"
\r
445 else if (tagname =="sub")
\r
447 else if (tagname =="sup")
\r
449 else if (tagname=="spoiler")
\r
450 html=html"</div></div></div>"
\r
451 else if (tagname=="list")
\r
458 else if (tagname=="*")
\r
462 debug = debug "###nl;unknown tag"
\r
469 else if(count[depth]>bbtree[indt(count,depth)".n"])
\r
471 debug = debug "###nl;run out of elements in this tag; leaving"
\r
478 tag=bbtree[ind(count,depth)]
\r
479 debug = debug "###nl;text: "tag
\r
480 if(bbtree[indt(count,depth)".t"] == "code")
\r
482 # gsub(/ ?<br> ?/,"<br>",tag)
\r
483 gsub(/ /,"\\ ",tag)
\r
484 gsub(/\t/,"\\ \\ ",tag)
\r
486 if(argtab["disable_magic_url"]==""&& bbtree[indt(count,depth)".t"] !~ /^((code)|(img)|(url))$/)
\r
487 gsub(/https?:\/\/[^\n\r\t<> ]+/,"<a href=\"&\" class=\"postlink\">&</a>",tag)
\r
488 if(argtab["disable_smilies"]=="" && bbtree[indt(count,depth)".t"] !~ /^((code)|(img))$/)
\r
490 gsub(/(^|[\n\r\t ]):D($|[\n\r\t ])/," <img title=\"Very Happy\" alt=\":D\" src=\"/ott/prosilver/smilies/icon_biggrin.gif\" /> ",tag)
\r
491 gsub(/(^|[\n\r\t ]):\)($|[\n\r\t ])/," <img title=\"Smile\" alt=\":)\" src=\"/ott/prosilver/smilies/icon_smile.gif\" /> ",tag)
\r
492 gsub(/(^|[\n\r\t ]):\(($|[\n\r\t ])/," <img title=\"Sad\" alt=\":(\" src=\"/ott/prosilver/smilies/icon_sad.gif\" /> ",tag)
\r
493 gsub(/(^|[\n\r\t ]):o($|[\n\r\t ])/," <img title=\"Surprised\" alt=\":o\" src=\"/ott/prosilver/smilies/icon_surprised.gif\" /> ",tag)
\r
494 gsub(/(^|[\n\r\t ]):shock:($|[\n\r\t ])/," <img title=\"Shocked\" alt=\":shock:\" src=\"/ott/prosilver/smilies/icon_eek.gif\" /> ",tag)
\r
495 gsub(/(^|[\n\r\t ]):\?($|[\n\r\t ])/," <img title=\"Confused\" alt=\":?\" src=\"/ott/prosilver/smilies/icon_confused.gif\" /> ",tag)
\r
496 gsub(/(^|[\n\r\t ])8-\)($|[\n\r\t ])/," <img title=\"Cool\" alt=\"8-)\" src=\"/ott/prosilver/smilies/icon_cool.gif\" /> ",tag)
\r
497 gsub(/(^|[\n\r\t ]):lol:($|[\n\r\t ])/," <img title=\"Laughing\" alt=\":lol:\" src=\"/ott/prosilver/smilies/icon_lol.gif\" /> ",tag)
\r
498 gsub(/(^|[\n\r\t ]):x($|[\n\r\t ])/," <img title=\"Mad\" alt=\":x\" src=\"/ott/prosilver/smilies/icon_mad.gif\" /> ",tag)
\r
499 gsub(/(^|[\n\r\t ]):P($|[\n\r\t ])/," <img title=\"Razz\" alt=\":P\" src=\"/ott/prosilver/smilies/icon_razz.gif\" /> ",tag)
\r
500 gsub(/(^|[\n\r\t ]):oops:($|[\n\r\t ])/," <img title=\"Embarassed\" alt=\":oops:\" src=\"/ott/prosilver/smilies/icon_redface.gif\" /> ",tag)
\r
501 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
502 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
503 gsub(/(^|[\n\r\t ]):twisted:($|[\n\r\t ])/," <img title=\"Twisted Evil\" alt=\":twisted:\" src=\"/ott/prosilver/smilies/icon_twisted.gif\" /> ",tag)
\r
504 gsub(/(^|[\n\r\t ]):roll:($|[\n\r\t ])/," <img title=\"Rolling Eyes\" alt=\":roll:\" src=\"/ott/prosilver/smilies/icon_rolleyes.gif\" /> ",tag)
\r
505 gsub(/(^|[\n\r\t ]):wink:($|[\n\r\t ])/," <img title=\"Wink\" alt=\":wink:\" src=\"/ott/prosilver/smilies/icon_wink.gif\" /> ",tag)
\r
506 gsub(/(^|[\n\r\t ]);\)($|[\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=\"Exclamation\" alt=\":!:\" src=\"/ott/prosilver/smilies/icon_exclaim.gif\" /> ",tag)
\r
508 gsub(/(^|[\n\r\t ]):\?:($|[\n\r\t ])/," <img title=\"Question\" alt=\":?:\" src=\"/ott/prosilver/smilies/icon_question.gif\" /> ",tag)
\r
509 gsub(/(^|[\n\r\t ]):idea:($|[\n\r\t ])/," <img title=\"Idea\" alt=\":idea:\" src=\"/ott/prosilver/smilies/icon_idea.gif\" /> ",tag)
\r
510 gsub(/(^|[\n\r\t ]):arrow:($|[\n\r\t ])/," <img title=\"Arrow\" alt=\":arrow:\" src=\"/ott/prosilver/smilies/icon_arrow.gif\" /> ",tag)
\r
511 gsub(/(^|[\n\r\t ]):\|($|[\n\r\t ])/," <img title=\"Neutral\" alt=\":|\" src=\"/ott/prosilver/smilies/icon_neutral.gif\" /> ",tag)
\r
512 gsub(/(^|[\n\r\t ]):mrgreen:($|[\n\r\t ])/," <img title=\"Mr. Green\" alt=\":mrgreen:\" src=\"/ott/prosilver/smilies/icon_mrgreen.gif\" /> ",tag)
\r
519 debug = debug "###nl;done"
\r
523 function ind(count,depth, ii,iindex)
\r
526 for(ii=0;ii<=depth;++ii)
\r
529 iindex = iindex "."
\r
530 iindex = iindex count[ii]
\r
532 # debug = debug "###nl;" iindex
\r
535 function indt(count,depth, ii,iindex)
\r
538 for(ii=0;ii<depth;++ii)
\r
541 iindex = iindex "."
\r
542 iindex = iindex count[ii]
\r
546 iindex = iindex "0"
\r
547 # debug = debug "###nl;" iindex
\r
550 function indtu(count,depth, ii,iindex)
\r
553 for(ii=0;ii<depth-1;++ii)
\r
556 iindex = iindex "."
\r
557 iindex = iindex count[ii]
\r
561 iindex = iindex "0"
\r
562 # debug = debug "###nl;" iindex
\r
565 function ong(decree, line)
\r
567 system (automome" -lc 256 -n 67 -d "memepath(decree!=""?" -t \"[decr]\"":"")" > "tempfile)
\r
569 while((getline line < tempfile)>0)
\r
571 gsub(/[\r\n]/,"",line)
\r
572 if(sub(/[AEIOUY]-N-G/,"#O-N-G#",line)>0)
\r
575 return preparebb(line)
\r
577 if(sub(/O+N+G+/,"#&#",line)>0)
\r
580 return preparebb(line)
\r
582 if(sub(/DON'T/,"D#ON'G#T",line)>0)
\r
585 return preparebb(line)
\r
587 if(sub(/[AEIOUY]NG/,"#ONG#",line)>0)
\r
589 if($0!~/TH\[b\]ONG/)
\r
590 return preparebb(line)
\r
592 if(sub(/ON /,"#ONG# ",line)>0)
\r
595 return preparebb(line)
\r
597 if(sub(/O\.?$/,"#ONG# ",$0)>0)
\r
600 return preparebb(line)
\r
607 function ung(decree, line)
\r
609 system (automome" -lc 256 -n 67 -d "memepath(decree!=""?" -t \"[decr]\"":"")" > "tempfile)
\r
611 while((getline line < tempfile)>0)
\r
613 gsub(/[\r\n]/,"",line)
\r
614 if(sub(/[AEIOUY]-N-G/,"#U-N-G#",line)>0)
\r
617 return preparebb(line)
\r
619 if(sub(/U+N+G+/,"#&#",line)>0)
\r
622 return preparebb(line)
\r
624 if(sub(/[AEIOUY]NG/,"#UNG#",line)>0)
\r
627 return preparebb(line)
\r
629 if(sub(/UN /,"#UNG# ",line)>0)
\r
632 return preparebb(line)
\r
634 if(sub(/U\.?$/,"#UNG# ",$0)>0)
\r
637 return preparebb(line)
\r
644 function preparebb(rh)
\r
648 gsub(/\*\*/,"¤",rh)
\r
649 gsub(/\*[^\*]+\*/,"±&±",rh)
\r
650 gsub(/±\*/,"[i]",rh)
\r
651 gsub(/\*±/,"[/i]",rh)
\r
655 gsub(/_[^_]+_/,"±&±",rh)
\r
656 gsub(/±_/,"[u]",rh)
\r
657 gsub(/_±/,"[/u]",rh)
\r
661 gsub(/#[^#]+#/,"±&±",rh)
\r
662 gsub(/±#/,"[b]",rh)
\r
663 gsub(/#±/,"[/b]",rh)
\r
666 gsub(/\$\$/,"¤",rh)
\r
667 gsub(/\$[^\$]+\$/,"±&±",rh)
\r
668 gsub(/±\$/,"[size=80]",rh)
\r
669 gsub(/\$±/,"[/size]",rh)
\r
673 return rh (nobb==""?" -- [url=http://mrob.com/time/automome]automome[/url]":" -- automome")
\r
675 function urlencode(name,all, len,iii,escaped,ch)
\r
679 for(iii=1;iii<=len;++iii)
\r
681 ch=substr(name,iii,1);
\r
682 if ((ch ~ /[a-zA-Z0-9\.\-_~]/)&&(all==""))
\r
683 escaped = escaped ch
\r
685 escaped = escaped "%" ch2hex[ch]
\r