ubb.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. function ubb2html(str)
  2. {
  3. var i=0 ,codes=[], s=''+str, split_str='', tqeUrl='http://www.qs.com/vt/inc/client/js/tqEditor/',
  4. escUrl=function(url){return url.replace(/\[\]/g, function(c){return {'[':'%5b',']':'%5d'}[c];})};//TQE.url;
  5. s=s.replace(/[<>\" ]/g,function(c){return {'<':'&lt;','>':'&gt;','"':'&quot;',' ':'&nbsp;'}[c];} ).replace(/\r?\n/g, '<br>');
  6. do{split_str= '__CODE__'+Math.random()+'_';}while(s.indexOf(split_str)>=0);
  7. s = s.replace(/\[code[=\]].*?\[\/code\]/ig, function(cs){codes.push(cs); return split_str+(i++)+'_'})
  8. .replace(/\[flv(?:\s*=\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+)\s*)?)?\](.*?)\[\/flv\]/ig, function(all,w,h,auto_start,url){
  9. if(!w) w=320;
  10. if(!h) h=240;
  11. return '<embed id="flvPlayer" src="'+tqeUrl+'flvPlayer.swf" flashvars="vcastr_file='+ escUrl(url)+'&IsAutoPlay='+auto_start+'" width="'+w+'" height="'+h+'" quality="high" bgcolor="#0E0E0E" name="play" align="middle" allowscriptaccess="sameDomain" allowfullscreen="true" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" wmode="opaque" />'})
  12. .replace(/\[rm(?:\s*=\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+)\s*)?)?\](.*?)\[\/rm\]/ig, function(all,w,h,auto_start,url){
  13. if(!w) w=320;
  14. if(!h) h=240;
  15. return '<embed src="'+ escUrl(url)+'" width='+w+' height='+h+' autostart="'+auto_start+'}" type="audio/x-pn-realaudio-plugin" console="Clip1" controls="ImageWindow" ></embed>';})
  16. .replace(/\[mp3\](.*?)\[\/mp3\]/ig, '<object id="mp3Player" classid="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6" type="application/x-ms-wmp" width="230" height="64"><PARAM NAME="URL" VALUE="$1" /><PARAM NAME="autoStart" VALUE="0" /><PARAM NAME="invokeURLs" VALUE="false"><PARAM NAME="playCount" VALUE="100"><PARAM NAME="Volume" VALUE="100"><PARAM NAME="defaultFrame" VALUE="datawindow"></object>')
  17. .replace(/\[img\](.*?)\[\/img\]/ig, '<img src=$1 />')
  18. .replace(/\[img(?:=\s*(\d+)\s*,\s*(\d+)\s*)\]\s*([\w_\-\.\/:]*)\s*\[\/img\]/ig, '<img src=$3 width=$1 height=$2 />')
  19. .replace(/\[(color|size)\s*=\s*([^\]]+)\s*\]/ig, '<font $1=$2>').replace(/\[\/(color|size)\]/ig, '</font>')
  20. .replace(/\[bg\s*=\s*([^\]]+)\s*\]/ig, '<span style="background:$1">').replace(/\[\/bg]/ig, '</span>')
  21. .replace(/\[(left|center|right)]/ig, '<div style="text-align:$1">').replace(/\[\/(left|center|right)]/ig, '</div>')
  22. .replace(/(?:<br>|\s)?\[list\](.*?)(<br>|\s)*\[\/list\]/ig, function(a,c){ return '<ul>'+c.replace(/\<br\>(\s|&nbsp;)*\[\*\]/g, '<li>')+'</ul>';})
  23. .replace(/(?:<br>|\s)?\[numlist\](.*?)(<br>|\s)*\[\/numlist\]/ig, function(a,c){ return '<ol>'+c.replace(/\<br\>(\s|&nbsp;)*\[\*\]/g, '<li>')+'</ol>';})
  24. .replace(/\[\:(\d+)]/g, '<img src="'+tqeUrl+'face/$1.gif" emot="$1" align="absMiddle" >') //表情
  25. .replace(/\[(\/?(?:b|u|i|s|sup|sub|h[1-6]))\]/ig, '<$1>')
  26. .replace(/\[url\]\s*(((?!")[\s\S])*?)(?:"[\s\S]*?)?\s*\[\/url\]/ig,'<a href="$1">$1</a>')
  27. .replace(/\[url\s*=\s*([^\]"]+?)(?:"[^\]]*?)?\s*\]\s*([\s\S]*?)\s*\[\/url\]/ig,'<a href="$1">$2</a>')
  28. .replace(/\[email\]\s*(((?!")[\s\S])+?)(?:"[\s\S]*?)?\s*\[\/email\]/ig,'<a href="mailto:$1">$1</a>')
  29. .replace(/\[email\s*=\s*([^\]"]+?)(?:"[^\]]*?)?\s*\]\s*([\s\S]+?)\s*\[\/email\]/ig,'<a href="mailto:$1">$2</a>')
  30. .replace(/\[qq\]\s*(\d+)\s*\[\/qq\]/ig,'<a href="tencent://message/?uin=$1">$1</a>')
  31. .replace(/\[qq\s*=\s*(\d+)\s*\]\s*([\s\S]+?)\s*\[\/qq\]/ig,'<a href="tencent://message/?uin=$1">$2</a>')
  32. .replace(/\[quote\]([\s\S]*?)\[\/quote\]/ig,'<blockquote>$1</blockquote>');
  33. while(/\[table\](((?!\[table)[\s\S])+?)\[\/table\]/i.test(s)){
  34. s=s.replace(/\[table\](((?!\[table)[\s\S])+?)\[\/table\]/ig, function(a,c){
  35. return '<table style="border-collapse: collapse;" width=98% border="1" cellPadding="3">'+c.replace(/\[(\/?(?:tr|td|th))\]/ig, '<$1>')+'</table>';
  36. });
  37. }
  38. i=-1;
  39. s= s.replace(new RegExp(split_str+'\\d+_','g'), function(c){return codes[++i];});
  40. return s;
  41. }
  42. function html2ubb(str)
  43. {
  44. var i=0 ,codes=[], s=''+str, split_str='';
  45. do{split_str= '__CODE__'+Math.random()+'_';}while(s.indexOf(split_str)>=0);
  46. s = s.replace(/[\r\n]/g,'').replace(/<br[^>]*>/ig,"\n");
  47. s = s.replace(/\[code[=\]].*?\[\/code\]/ig, function(cs){codes.push(cs); return split_str+(i++)+'_'})
  48. .replace(/<embed ([^>]*)>/ig, function(all,attr){
  49. var a,url,w='',h='',as='',attrStr=attr.toLowerCase();
  50. a=/width\s*=\s*\"?([^ \"]+)/i.exec(attrStr);
  51. if(a){
  52. w='='+a[1];
  53. }
  54. if(w!=''){
  55. a=/height\s*=\s*\"?([^ \"]+)/i.exec(attrStr);
  56. if(a){
  57. h=','+a[1];
  58. }
  59. }
  60. //flv
  61. if(attrStr.indexOf('vcastr_file')){
  62. a= /vcastr_file=([^\"&]+)/.exec(attr);
  63. url=a[1];
  64. if(''!=w){
  65. a=/IsAutoPlay=(0|1)/.exec(attr);
  66. if(a){
  67. as=','+a[1];
  68. }
  69. }
  70. return '[flv'+w+h+as+']'+url+'[/flv]';
  71. }
  72. //flash
  73. if(attrStr.indexOf('shockwave-flash')){
  74. a=/src\s*=\s*\"?([^ \"]+)/i.exec(attrStr);
  75. url=a[1];
  76. return '[flash'+w+h+']'+url+'[/flash]';
  77. }
  78. //rm
  79. if(attrStr.indexOf('realaudio-plugin')){
  80. a=/src\s*=\s*\"?([^ \"]+)/i.exec(attrStr);
  81. url=a[1];
  82. if(''!=w){
  83. a=/autostart\s*=\s*\"?(0|1)/.exec(attrStr);
  84. if(a){
  85. as=','+a[1];
  86. }
  87. }
  88. return '[rm'+w+h+']'+url+'[/rm]';
  89. }
  90. return '';
  91. })
  92. .replace(/<object (.*?)<\/object>/ig, function(all,attr){
  93. var a,url,w='',h='',as='',attrStr=attr.toLowerCase();
  94. a=/width\s*=\s*\"?([^ \"]+)/i.exec(attrStr);
  95. if(a){
  96. w='='+a[1];
  97. }
  98. if(w!=''){
  99. a=/height\s*=\s*\"?([^ \"]+)/i.exec(attrStr);
  100. if(a){
  101. h=','+a[1];
  102. }
  103. }
  104. a=/<PARAM\s+NAME\s*=\s*"?URL"?\s+VALUE\s*=\s*"?([^\"> ]+)"?/i.exec(attr);
  105. url=a[1];
  106. //mp3
  107. if(attrStr.indexOf('mp3player')){
  108. return '[mp3]'+url+'[/mp3]';
  109. }
  110. return all;
  111. })
  112. .replace(/<img ([^>]+)>/ig, function(all,attr){
  113. var a,url,w='',h='',as='',attrStr=attr.toLowerCase();
  114. a=/width\s*=\s*\"?([^ \"]+)/i.exec(attrStr);
  115. if(a){
  116. w='='+a[1];
  117. }
  118. if(w!=''){
  119. a=/height\s*=\s*\"?([^ \"]+)/i.exec(attrStr);
  120. if(a){
  121. h=','+a[1];
  122. }
  123. }
  124. //emot
  125. a= /emot\s*=\s*"?(\d+)"?/i.exec(attr);
  126. if(a){
  127. return '[:'+a[1]+']';
  128. }
  129. //img
  130. a=/src\s*=\s*"?([^\"> ]+)"?/i.exec(attr);
  131. url=a[1];
  132. return '[img'+w+h+']'+url+'[/img]';
  133. })
  134. //list
  135. .replace(/<ul[^>]*>/ig, '\n[list]')
  136. .replace(/\s*<\/ul[^>]*>/ig, '\n[/list]')
  137. .replace(/<ol[^>]*>/ig, '\n[numlist]')
  138. .replace(/\s*<\/ol[^>]*>/ig, '\n[/numlist]')
  139. .replace(/\s*<li[^>]*>/ig, '\n[*]')
  140. .replace(/<\/li[^>]*>/ig, '')
  141. .replace(/<(\/?(?:b|u|i|s|sup|sub|table|tr|td|th|h[1-6]))(?![a-z])[^>]*>/ig, '[$1]')
  142. .replace(/<(\/)?(strong|em|strike|del)(?![a-z])[^>]*>/ig, function(a,b,c){
  143. var t={'strong':'b', 'em':'i', 'strike':'s', 'del':'s'}[c.toLowerCase()];
  144. if(b!=='/')b='';
  145. return '['+b+t + ']';
  146. })
  147. .replace(/<blockquote(?:\s+[^>]*?)?>([\s\S]+?)<\/blockquote>/ig,'[quote]$1[/quote]');
  148. var reg,a,
  149. rgb2color=function(r,g,b){
  150. var color= (r*65536+g*256+b*1).toString(16),l=color.length;
  151. while(l++<6) color='0'+color;
  152. return '#'+color;
  153. },
  154. getFormat=function(aStr){
  155. var pre='', end='';
  156. aStr=aStr.toLowerCase();
  157. //left,center,right
  158. if( /align\s*[=:]\s*\"?(left|center|right)/.exec(aStr) ){
  159. pre+='['+RegExp.$1+']';
  160. end='[/'+RegExp.$1+']'+end;
  161. }
  162. //size
  163. if( /[^-]size\s*=\s*\"?(\d+\s*(?:px|pc|pt|em|ex|cm|mm)?)/.exec(aStr) ){
  164. pre+='[size='+RegExp.$1+']';
  165. end='[/size]'+end;
  166. }
  167. //color
  168. if( /[^-]color\s*[:=]\s*\"?rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/.exec(aStr) ){
  169. pre+='[color='+rgb2color(RegExp.$1,RegExp.$2,RegExp.$3)+']';
  170. end='[/color]'+end;
  171. }else if( /[^-]color\s*[:=]\s*\"?([a-z0-9#]+)/.exec(aStr) ){
  172. pre+='[color='+RegExp.$1+']';
  173. end='[/color]'+end;
  174. }
  175. //background-color
  176. if( /background(?:\-color)?\s*:\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/.exec(aStr) ){
  177. pre+='[bg='+rgb2color(RegExp.$1,RegExp.$2,RegExp.$3)+']';
  178. end ='[/bg]'+end;
  179. }else if( /background(?:\-color)?\s*:\s*([a-z0-9#]+)/.exec(aStr) ){
  180. pre+='[bg='+RegExp.$1+']';
  181. end ='[/bg]'+end;
  182. };
  183. return {'pre':pre, 'end':end};
  184. };
  185. while(/<div([^>]*)>(((?!<div)[\s\S])*?)<\/div>/i.test(s)){// /<div/i.test(s)
  186. s=s.replace(/<div([^>]*)>(((?!<div)[\s\S])*?)<\/div>/ig, function(all, attr, text){
  187. a=getFormat(attr);
  188. return "\n"+a.pre+text+a.end+"\n";
  189. });
  190. }
  191. while(/<p([^>]*)>(((?!<p)[\s\S])*?)<\/p>/i.test(s)){// /<div/i.test(s)
  192. s=s.replace(/<p([^>]*)>(((?!<p)[\s\S])*?)<\/p>/ig, function(all, attr, text){
  193. a=getFormat(attr);
  194. return "\n"+a.pre+text+a.end+"\n";
  195. });
  196. }
  197. while(/<span([^>]*)>(((?!<span)[\s\S])*?)<\/span>/i.test(s)){// /<div/i.test(s)
  198. s=s.replace(/<span([^>]*)>(((?!<span)[\s\S])*?)<\/span>/ig, function(all, attr, text){
  199. a=getFormat(attr);
  200. return a.pre+text+a.end;
  201. });
  202. }
  203. while(/<font([^>]*)>(((?!<font)[\s\S])*?)<\/font>/i.test(s)){// /<div/i.test(s)
  204. s=s.replace(/<font([^>]*)>(((?!<font)[\s\S])*?)<\/font>/ig, function(all, attr, text){
  205. a=getFormat(attr);
  206. return a.pre+text+a.end;
  207. });
  208. }
  209. i=-1;
  210. s= s.replace(/<a .*?href\s*=\s*["']?([^'" ]+)[^>]*>([\s\S]*?)<\/a>/ig,function(all,url,text){
  211. var tag='url';
  212. if('mailto:'==url.substr(0,7).toLowerCase()){
  213. tag='email';
  214. url=url.substr(7,url.length);
  215. }else if('tencent:'==url.substr(0,8)){
  216. tag='qq';
  217. var a= /uin=(\d+)/i.exec(url);
  218. url=a[1];
  219. }
  220. if(text==url) return '['+tag+']'+text+'[/'+tag+']';
  221. return '['+tag+'='+url+']'+text+'[/'+tag+']';
  222. })
  223. .replace(/<\/?[a-z][^>]*>/ig,'')//删除未处理的标签
  224. .replace(new RegExp(split_str+'\\d+_','g'), function(c){return codes[++i];}) //恢复code
  225. .replace(/(&nbsp;|&gt;|&lt;|&quot;)/g,function(c){return {'&nbsp;':' ','&gt;':'>','&lt;':'<','&quot;':'"'}[c];})
  226. .replace(/\n\s*\n/g,'\n\n');//最多两个空行
  227. return s;
  228. }