正在显示
9 个修改的文件
包含
0 行增加
和
4570 行删除
utils/qqmap-wx-jssdk.min.js
已删除
100644 → 0
1 | -var _createClass=function(){function a(e,c){for(var b=0;b<c.length;b++){var d=c[b];d.enumerable=d.enumerable||false;d.configurable=true;if("value" in d){d.writable=true}Object.defineProperty(e,d.key,d)}}return function(d,b,c){if(b){a(d.prototype,b)}if(c){a(d,c)}return d}}();function _classCallCheck(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function")}}var ERROR_CONF={KEY_ERR:311,KEY_ERR_MSG:"key格式错误",PARAM_ERR:310,PARAM_ERR_MSG:"请求参数信息有误",SYSTEM_ERR:600,SYSTEM_ERR_MSG:"系统错误",WX_ERR_CODE:1000,WX_OK_CODE:200};var BASE_URL="https://apis.map.qq.com/ws/";var URL_SEARCH=BASE_URL+"place/v1/search";var URL_SUGGESTION=BASE_URL+"place/v1/suggestion";var URL_GET_GEOCODER=BASE_URL+"geocoder/v1/";var URL_CITY_LIST=BASE_URL+"district/v1/list";var URL_AREA_LIST=BASE_URL+"district/v1/getchildren";var URL_DISTANCE=BASE_URL+"distance/v1/";var Utils={location2query:function location2query(c){if(typeof c=="string"){return c}var b="";for(var a=0;a<c.length;a++){var e=c[a];if(!!b){b+=";"}if(e.location){b=b+e.location.lat+","+e.location.lng}if(e.latitude&&e.longitude){b=b+e.latitude+","+e.longitude}}return b},getWXLocation:function getWXLocation(c,b,a){wx.getLocation({type:"gcj02",success:c,fail:b,complete:a})},getLocationParam:function getLocationParam(b){if(typeof b=="string"){var a=b.split(",");if(a.length===2){b={latitude:b.split(",")[0],longitude:b.split(",")[1]}}else{b={}}}return b},polyfillParam:function polyfillParam(a){a.success=a.success||function(){};a.fail=a.fail||function(){};a.complete=a.complete||function(){}},checkParamKeyEmpty:function checkParamKeyEmpty(c,b){if(!c[b]){var a=this.buildErrorConfig(ERROR_CONF.PARAM_ERR,ERROR_CONF.PARAM_ERR_MSG+b+"参数格式有误");c.fail(a);c.complete(a);return true}return false},checkKeyword:function checkKeyword(a){return !this.checkParamKeyEmpty(a,"keyword")},checkLocation:function checkLocation(c){var a=this.getLocationParam(c.location);if(!a||!a.latitude||!a.longitude){var b=this.buildErrorConfig(ERROR_CONF.PARAM_ERR,ERROR_CONF.PARAM_ERR_MSG+" location参数格式有误");c.fail(b);c.complete(b);return false}return true},buildErrorConfig:function buildErrorConfig(a,b){return{status:a,message:b}},buildWxRequestConfig:function buildWxRequestConfig(c,a){var b=this;a.header={"content-type":"application/json"};a.method="GET";a.success=function(d){var e=d.data;if(e.status===0){c.success(e)}else{c.fail(e)}};a.fail=function(d){d.statusCode=ERROR_CONF.WX_ERR_CODE;c.fail(b.buildErrorConfig(ERROR_CONF.WX_ERR_CODE,result.errMsg))};a.complete=function(d){var e=+d.statusCode;switch(e){case ERROR_CONF.WX_ERR_CODE:c.complete(b.buildErrorConfig(ERROR_CONF.WX_ERR_CODE,d.errMsg));break;case ERROR_CONF.WX_OK_CODE:var f=d.data;if(f.status===0){c.complete(f)}else{c.complete(b.buildErrorConfig(f.status,f.message))}break;default:c.complete(b.buildErrorConfig(ERROR_CONF.SYSTEM_ERR,ERROR_CONF.SYSTEM_ERR_MSG))}};return a},locationProcess:function locationProcess(f,e,c,a){var d=this;c=c||function(g){g.statusCode=ERROR_CONF.WX_ERR_CODE;f.fail(d.buildErrorConfig(ERROR_CONF.WX_ERR_CODE,g.errMsg))};a=a||function(g){if(g.statusCode==ERROR_CONF.WX_ERR_CODE){f.complete(d.buildErrorConfig(ERROR_CONF.WX_ERR_CODE,g.errMsg))}};if(!f.location){d.getWXLocation(e,c,a)}else{if(d.checkLocation(f)){var b=Utils.getLocationParam(f.location);e(b)}}}};var QQMapWX=function(){function b(i){_classCallCheck(this,b);if(!i.key){throw Error("key值不能为空")}this.key=i.key}_createClass(b,[{key:"search",value:function f(i){var l=this;i=i||{};Utils.polyfillParam(i);if(!Utils.checkKeyword(i)){return}var k={keyword:i.keyword,orderby:i.orderby||"_distance",page_size:i.page_size||10,page_index:i.page_index||1,output:"json",key:l.key};if(i.address_format){k.address_format=i.address_format}if(i.filter){k.filter=i.filter}var n=i.distance||"1000";var j=i.auto_extend||1;var m=function m(o){k.boundary="nearby("+o.latitude+","+o.longitude+","+n+","+j+")";wx.request(Utils.buildWxRequestConfig(i,{url:URL_SEARCH,data:k}))};Utils.locationProcess(i,m)}},{key:"getSuggestion",value:function h(i){var k=this;i=i||{};Utils.polyfillParam(i);if(!Utils.checkKeyword(i)){return}var j={keyword:i.keyword,region:i.region||"全国",region_fix:i.region_fix||0,policy:i.policy||0,output:"json",key:k.key};wx.request(Utils.buildWxRequestConfig(i,{url:URL_SUGGESTION,data:j}))}},{key:"reverseGeocoder",value:function a(i){var k=this;i=i||{};Utils.polyfillParam(i);var j={coord_type:i.coord_type||5,get_poi:i.get_poi||0,output:"json",key:k.key};if(i.poi_options){j.poi_options=i.poi_options}var l=function l(m){j.location=m.latitude+","+m.longitude;wx.request(Utils.buildWxRequestConfig(i,{url:URL_GET_GEOCODER,data:j}))};Utils.locationProcess(i,l)}},{key:"geocoder",value:function g(i){var k=this;i=i||{};Utils.polyfillParam(i);if(Utils.checkParamKeyEmpty(i,"address")){return}var j={address:i.address,output:"json",key:k.key};wx.request(Utils.buildWxRequestConfig(i,{url:URL_GET_GEOCODER,data:j}))}},{key:"getCityList",value:function c(i){var k=this;i=i||{};Utils.polyfillParam(i);var j={output:"json",key:k.key}; | ||
2 | -wx.request(Utils.buildWxRequestConfig(i,{url:URL_CITY_LIST,data:j}))}},{key:"getDistrictByCityId",value:function d(i){var k=this;i=i||{};Utils.polyfillParam(i);if(Utils.checkParamKeyEmpty(i,"id")){return}var j={id:i.id||"",output:"json",key:k.key};wx.request(Utils.buildWxRequestConfig(i,{url:URL_AREA_LIST,data:j}))}},{key:"calculateDistance",value:function e(i){var k=this;i=i||{};Utils.polyfillParam(i);if(Utils.checkParamKeyEmpty(i,"to")){return}var j={mode:i.mode||"walking",to:Utils.location2query(i.to),output:"json",key:k.key};var l=function l(m){j.from=m.latitude+","+m.longitude;wx.request(Utils.buildWxRequestConfig(i,{url:URL_DISTANCE,data:j}))};if(i.from){i.location=i.from}Utils.locationProcess(i,l)}}]);return b}();module.exports=QQMapWX; |
wxParse/html2json.js
已删除
100644 → 0
1 | -/** | ||
2 | - * html2Json 改造来自: https://github.com/Jxck/html2json | ||
3 | - * | ||
4 | - * | ||
5 | - * author: Di (微信小程序开发工程师) | ||
6 | - * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | ||
7 | - * 垂直微信小程序开发交流社区 | ||
8 | - * | ||
9 | - * github地址: https://github.com/icindy/wxParse | ||
10 | - * | ||
11 | - * for: 微信小程序富文本解析 | ||
12 | - * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | ||
13 | - */ | ||
14 | - | ||
15 | -var __placeImgeUrlHttps = "https"; | ||
16 | -var __emojisReg = ''; | ||
17 | -var __emojisBaseSrc = ''; | ||
18 | -var __emojis = {}; | ||
19 | -var wxDiscode = require('./wxDiscode.js'); | ||
20 | -var HTMLParser = require('./htmlparser.js'); | ||
21 | -// Empty Elements - HTML 5 | ||
22 | -var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr"); | ||
23 | -// Block Elements - HTML 5 | ||
24 | -var block = makeMap("br,a,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video"); | ||
25 | - | ||
26 | -// Inline Elements - HTML 5 | ||
27 | -var inline = makeMap("abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var"); | ||
28 | - | ||
29 | -// Elements that you can, intentionally, leave open | ||
30 | -// (and which close themselves) | ||
31 | -var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr"); | ||
32 | - | ||
33 | -// Attributes that have their values filled in disabled="disabled" | ||
34 | -var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"); | ||
35 | - | ||
36 | -// Special Elements (can contain anything) | ||
37 | -var special = makeMap("wxxxcode-style,script,style,view,scroll-view,block"); | ||
38 | -function makeMap(str) { | ||
39 | - var obj = {}, items = str.split(","); | ||
40 | - for (var i = 0; i < items.length; i++) | ||
41 | - obj[items[i]] = true; | ||
42 | - return obj; | ||
43 | -} | ||
44 | - | ||
45 | -function q(v) { | ||
46 | - return '"' + v + '"'; | ||
47 | -} | ||
48 | - | ||
49 | -function removeDOCTYPE(html) { | ||
50 | - return html | ||
51 | - .replace(/<\?xml.*\?>\n/, '') | ||
52 | - .replace(/<.*!doctype.*\>\n/, '') | ||
53 | - .replace(/<.*!DOCTYPE.*\>\n/, ''); | ||
54 | -} | ||
55 | - | ||
56 | -function trimHtml(html) { | ||
57 | - return html | ||
58 | - .replace(/\r?\n+/g, '') | ||
59 | - .replace(/<!--.*?-->/ig, '') | ||
60 | - .replace(/\/\*.*?\*\//ig, '') | ||
61 | - .replace(/[ ]+</ig, '<') | ||
62 | -} | ||
63 | - | ||
64 | - | ||
65 | -function html2json(html, bindName) { | ||
66 | - //处理字符串 | ||
67 | - html = removeDOCTYPE(html); | ||
68 | - html = trimHtml(html); | ||
69 | - html = wxDiscode.strDiscode(html); | ||
70 | - //生成node节点 | ||
71 | - var bufArray = []; | ||
72 | - var results = { | ||
73 | - node: bindName, | ||
74 | - nodes: [], | ||
75 | - images:[], | ||
76 | - imageUrls:[] | ||
77 | - }; | ||
78 | - var index = 0; | ||
79 | - HTMLParser(html, { | ||
80 | - start: function (tag, attrs, unary) { | ||
81 | - //debug(tag, attrs, unary); | ||
82 | - // node for this element | ||
83 | - var node = { | ||
84 | - node: 'element', | ||
85 | - tag: tag, | ||
86 | - }; | ||
87 | - | ||
88 | - if (bufArray.length === 0) { | ||
89 | - node.index = index.toString() | ||
90 | - index += 1 | ||
91 | - } else { | ||
92 | - var parent = bufArray[0]; | ||
93 | - if (parent.nodes === undefined) { | ||
94 | - parent.nodes = []; | ||
95 | - } | ||
96 | - node.index = parent.index + '.' + parent.nodes.length | ||
97 | - } | ||
98 | - | ||
99 | - if (block[tag]) { | ||
100 | - node.tagType = "block"; | ||
101 | - } else if (inline[tag]) { | ||
102 | - node.tagType = "inline"; | ||
103 | - } else if (closeSelf[tag]) { | ||
104 | - node.tagType = "closeSelf"; | ||
105 | - } | ||
106 | - | ||
107 | - if (attrs.length !== 0) { | ||
108 | - node.attr = attrs.reduce(function (pre, attr) { | ||
109 | - var name = attr.name; | ||
110 | - var value = attr.value; | ||
111 | - if (name == 'class') { | ||
112 | - // console.dir(value); | ||
113 | - // value = value.join("") | ||
114 | - node.classStr = value; | ||
115 | - } | ||
116 | - // has multi attibutes | ||
117 | - // make it array of attribute | ||
118 | - if (name == 'style') { | ||
119 | - console.dir(value); | ||
120 | - // value = value.join("") | ||
121 | - node.styleStr = value; | ||
122 | - } | ||
123 | - if (value.match(/ /)) { | ||
124 | - value = value.split(' '); | ||
125 | - } | ||
126 | - | ||
127 | - | ||
128 | - // if attr already exists | ||
129 | - // merge it | ||
130 | - if (pre[name]) { | ||
131 | - if (Array.isArray(pre[name])) { | ||
132 | - // already array, push to last | ||
133 | - pre[name].push(value); | ||
134 | - } else { | ||
135 | - // single value, make it array | ||
136 | - pre[name] = [pre[name], value]; | ||
137 | - } | ||
138 | - } else { | ||
139 | - // not exist, put it | ||
140 | - pre[name] = value; | ||
141 | - } | ||
142 | - | ||
143 | - return pre; | ||
144 | - }, {}); | ||
145 | - } | ||
146 | - | ||
147 | - //对img添加额外数据 | ||
148 | - if (node.tag === 'img') { | ||
149 | - node.imgIndex = results.images.length; | ||
150 | - var imgUrl = node.attr.src; | ||
151 | - if (imgUrl[0] == '') { | ||
152 | - imgUrl.splice(0, 1); | ||
153 | - } | ||
154 | - imgUrl = wxDiscode.urlToHttpUrl(imgUrl, __placeImgeUrlHttps); | ||
155 | - node.attr.src = imgUrl; | ||
156 | - node.from = bindName; | ||
157 | - results.images.push(node); | ||
158 | - results.imageUrls.push(imgUrl); | ||
159 | - } | ||
160 | - | ||
161 | - // 处理font标签样式属性 | ||
162 | - if (node.tag === 'font') { | ||
163 | - var fontSize = ['x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', '-webkit-xxx-large']; | ||
164 | - var styleAttrs = { | ||
165 | - 'color': 'color', | ||
166 | - 'face': 'font-family', | ||
167 | - 'size': 'font-size' | ||
168 | - }; | ||
169 | - if (!node.attr.style) node.attr.style = []; | ||
170 | - if (!node.styleStr) node.styleStr = ''; | ||
171 | - for (var key in styleAttrs) { | ||
172 | - if (node.attr[key]) { | ||
173 | - var value = key === 'size' ? fontSize[node.attr[key]-1] : node.attr[key]; | ||
174 | - node.attr.style.push(styleAttrs[key]); | ||
175 | - node.attr.style.push(value); | ||
176 | - node.styleStr += styleAttrs[key] + ': ' + value + ';'; | ||
177 | - } | ||
178 | - } | ||
179 | - } | ||
180 | - | ||
181 | - //临时记录source资源 | ||
182 | - if(node.tag === 'source'){ | ||
183 | - results.source = node.attr.src; | ||
184 | - } | ||
185 | - | ||
186 | - if (unary) { | ||
187 | - // if this tag doesn't have end tag | ||
188 | - // like <img src="hoge.png"/> | ||
189 | - // add to parents | ||
190 | - var parent = bufArray[0] || results; | ||
191 | - if (parent.nodes === undefined) { | ||
192 | - parent.nodes = []; | ||
193 | - } | ||
194 | - parent.nodes.push(node); | ||
195 | - } else { | ||
196 | - bufArray.unshift(node); | ||
197 | - } | ||
198 | - }, | ||
199 | - end: function (tag) { | ||
200 | - //debug(tag); | ||
201 | - // merge into parent tag | ||
202 | - var node = bufArray.shift(); | ||
203 | - if (node.tag !== tag) console.error('invalid state: mismatch end tag'); | ||
204 | - | ||
205 | - //当有缓存source资源时于于video补上src资源 | ||
206 | - if(node.tag === 'video' && results.source){ | ||
207 | - node.attr.src = results.source; | ||
208 | - delete results.source; | ||
209 | - } | ||
210 | - | ||
211 | - if (bufArray.length === 0) { | ||
212 | - results.nodes.push(node); | ||
213 | - } else { | ||
214 | - var parent = bufArray[0]; | ||
215 | - if (parent.nodes === undefined) { | ||
216 | - parent.nodes = []; | ||
217 | - } | ||
218 | - parent.nodes.push(node); | ||
219 | - } | ||
220 | - }, | ||
221 | - chars: function (text) { | ||
222 | - //debug(text); | ||
223 | - var node = { | ||
224 | - node: 'text', | ||
225 | - text: text, | ||
226 | - textArray:transEmojiStr(text) | ||
227 | - }; | ||
228 | - | ||
229 | - if (bufArray.length === 0) { | ||
230 | - node.index = index.toString() | ||
231 | - index += 1 | ||
232 | - results.nodes.push(node); | ||
233 | - } else { | ||
234 | - var parent = bufArray[0]; | ||
235 | - if (parent.nodes === undefined) { | ||
236 | - parent.nodes = []; | ||
237 | - } | ||
238 | - node.index = parent.index + '.' + parent.nodes.length | ||
239 | - parent.nodes.push(node); | ||
240 | - } | ||
241 | - }, | ||
242 | - comment: function (text) { | ||
243 | - //debug(text); | ||
244 | - // var node = { | ||
245 | - // node: 'comment', | ||
246 | - // text: text, | ||
247 | - // }; | ||
248 | - // var parent = bufArray[0]; | ||
249 | - // if (parent.nodes === undefined) { | ||
250 | - // parent.nodes = []; | ||
251 | - // } | ||
252 | - // parent.nodes.push(node); | ||
253 | - }, | ||
254 | - }); | ||
255 | - return results; | ||
256 | -}; | ||
257 | - | ||
258 | -function transEmojiStr(str){ | ||
259 | - // var eReg = new RegExp("["+__reg+' '+"]"); | ||
260 | -// str = str.replace(/\[([^\[\]]+)\]/g,':$1:') | ||
261 | - | ||
262 | - var emojiObjs = []; | ||
263 | - //如果正则表达式为空 | ||
264 | - if(__emojisReg.length == 0 || !__emojis){ | ||
265 | - var emojiObj = {} | ||
266 | - emojiObj.node = "text"; | ||
267 | - emojiObj.text = str; | ||
268 | - array = [emojiObj]; | ||
269 | - return array; | ||
270 | - } | ||
271 | - //这个地方需要调整 | ||
272 | - str = str.replace(/\[([^\[\]]+)\]/g,':$1:') | ||
273 | - var eReg = new RegExp("[:]"); | ||
274 | - var array = str.split(eReg); | ||
275 | - for(var i = 0; i < array.length; i++){ | ||
276 | - var ele = array[i]; | ||
277 | - var emojiObj = {}; | ||
278 | - if(__emojis[ele]){ | ||
279 | - emojiObj.node = "element"; | ||
280 | - emojiObj.tag = "emoji"; | ||
281 | - emojiObj.text = __emojis[ele]; | ||
282 | - emojiObj.baseSrc= __emojisBaseSrc; | ||
283 | - }else{ | ||
284 | - emojiObj.node = "text"; | ||
285 | - emojiObj.text = ele; | ||
286 | - } | ||
287 | - emojiObjs.push(emojiObj); | ||
288 | - } | ||
289 | - | ||
290 | - return emojiObjs; | ||
291 | -} | ||
292 | - | ||
293 | -function emojisInit(reg='',baseSrc="/wxParse/emojis/",emojis){ | ||
294 | - __emojisReg = reg; | ||
295 | - __emojisBaseSrc=baseSrc; | ||
296 | - __emojis=emojis; | ||
297 | -} | ||
298 | - | ||
299 | -module.exports = { | ||
300 | - html2json: html2json, | ||
301 | - emojisInit:emojisInit | ||
302 | -}; | ||
303 | - |
wxParse/htmlparser.js
已删除
100644 → 0
1 | -/** | ||
2 | - * | ||
3 | - * htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser | ||
4 | - * | ||
5 | - * author: Di (微信小程序开发工程师) | ||
6 | - * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | ||
7 | - * 垂直微信小程序开发交流社区 | ||
8 | - * | ||
9 | - * github地址: https://github.com/icindy/wxParse | ||
10 | - * | ||
11 | - * for: 微信小程序富文本解析 | ||
12 | - * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | ||
13 | - */ | ||
14 | -// Regular Expressions for parsing tags and attributes | ||
15 | -var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/, | ||
16 | - endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/, | ||
17 | - attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; | ||
18 | - | ||
19 | -// Empty Elements - HTML 5 | ||
20 | -var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr"); | ||
21 | - | ||
22 | -// Block Elements - HTML 5 | ||
23 | -var block = makeMap("a,address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video"); | ||
24 | - | ||
25 | -// Inline Elements - HTML 5 | ||
26 | -var inline = makeMap("abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var"); | ||
27 | - | ||
28 | -// Elements that you can, intentionally, leave open | ||
29 | -// (and which close themselves) | ||
30 | -var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr"); | ||
31 | - | ||
32 | -// Attributes that have their values filled in disabled="disabled" | ||
33 | -var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"); | ||
34 | - | ||
35 | -// Special Elements (can contain anything) | ||
36 | -var special = makeMap("wxxxcode-style,script,style,view,scroll-view,block"); | ||
37 | - | ||
38 | -function HTMLParser(html, handler) { | ||
39 | - var index, chars, match, stack = [], last = html; | ||
40 | - stack.last = function () { | ||
41 | - return this[this.length - 1]; | ||
42 | - }; | ||
43 | - | ||
44 | - while (html) { | ||
45 | - chars = true; | ||
46 | - | ||
47 | - // Make sure we're not in a script or style element | ||
48 | - if (!stack.last() || !special[stack.last()]) { | ||
49 | - | ||
50 | - // Comment | ||
51 | - if (html.indexOf("<!--") == 0) { | ||
52 | - index = html.indexOf("-->"); | ||
53 | - | ||
54 | - if (index >= 0) { | ||
55 | - if (handler.comment) | ||
56 | - handler.comment(html.substring(4, index)); | ||
57 | - html = html.substring(index + 3); | ||
58 | - chars = false; | ||
59 | - } | ||
60 | - | ||
61 | - // end tag | ||
62 | - } else if (html.indexOf("</") == 0) { | ||
63 | - match = html.match(endTag); | ||
64 | - | ||
65 | - if (match) { | ||
66 | - html = html.substring(match[0].length); | ||
67 | - match[0].replace(endTag, parseEndTag); | ||
68 | - chars = false; | ||
69 | - } | ||
70 | - | ||
71 | - // start tag | ||
72 | - } else if (html.indexOf("<") == 0) { | ||
73 | - match = html.match(startTag); | ||
74 | - | ||
75 | - if (match) { | ||
76 | - html = html.substring(match[0].length); | ||
77 | - match[0].replace(startTag, parseStartTag); | ||
78 | - chars = false; | ||
79 | - } | ||
80 | - } | ||
81 | - | ||
82 | - if (chars) { | ||
83 | - index = html.indexOf("<"); | ||
84 | - var text = '' | ||
85 | - while (index === 0) { | ||
86 | - text += "<"; | ||
87 | - html = html.substring(1); | ||
88 | - index = html.indexOf("<"); | ||
89 | - } | ||
90 | - text += index < 0 ? html : html.substring(0, index); | ||
91 | - html = index < 0 ? "" : html.substring(index); | ||
92 | - | ||
93 | - if (handler.chars) | ||
94 | - handler.chars(text); | ||
95 | - } | ||
96 | - | ||
97 | - } else { | ||
98 | - | ||
99 | - html = html.replace(new RegExp("([\\s\\S]*?)<\/" + stack.last() + "[^>]*>"), function (all, text) { | ||
100 | - text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, "$1$2"); | ||
101 | - if (handler.chars) | ||
102 | - handler.chars(text); | ||
103 | - | ||
104 | - return ""; | ||
105 | - }); | ||
106 | - | ||
107 | - | ||
108 | - parseEndTag("", stack.last()); | ||
109 | - } | ||
110 | - | ||
111 | - if (html == last) | ||
112 | - throw "Parse Error: " + html; | ||
113 | - last = html; | ||
114 | - } | ||
115 | - | ||
116 | - // Clean up any remaining tags | ||
117 | - parseEndTag(); | ||
118 | - | ||
119 | - function parseStartTag(tag, tagName, rest, unary) { | ||
120 | - tagName = tagName.toLowerCase(); | ||
121 | - | ||
122 | - if (block[tagName]) { | ||
123 | - while (stack.last() && inline[stack.last()]) { | ||
124 | - parseEndTag("", stack.last()); | ||
125 | - } | ||
126 | - } | ||
127 | - | ||
128 | - if (closeSelf[tagName] && stack.last() == tagName) { | ||
129 | - parseEndTag("", tagName); | ||
130 | - } | ||
131 | - | ||
132 | - unary = empty[tagName] || !!unary; | ||
133 | - | ||
134 | - if (!unary) | ||
135 | - stack.push(tagName); | ||
136 | - | ||
137 | - if (handler.start) { | ||
138 | - var attrs = []; | ||
139 | - | ||
140 | - rest.replace(attr, function (match, name) { | ||
141 | - var value = arguments[2] ? arguments[2] : | ||
142 | - arguments[3] ? arguments[3] : | ||
143 | - arguments[4] ? arguments[4] : | ||
144 | - fillAttrs[name] ? name : ""; | ||
145 | - | ||
146 | - attrs.push({ | ||
147 | - name: name, | ||
148 | - value: value, | ||
149 | - escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') //" | ||
150 | - }); | ||
151 | - }); | ||
152 | - | ||
153 | - if (handler.start) { | ||
154 | - handler.start(tagName, attrs, unary); | ||
155 | - } | ||
156 | - | ||
157 | - } | ||
158 | - } | ||
159 | - | ||
160 | - function parseEndTag(tag, tagName) { | ||
161 | - // If no tag name is provided, clean shop | ||
162 | - if (!tagName) | ||
163 | - var pos = 0; | ||
164 | - | ||
165 | - // Find the closest opened tag of the same type | ||
166 | - else { | ||
167 | - tagName = tagName.toLowerCase(); | ||
168 | - for (var pos = stack.length - 1; pos >= 0; pos--) | ||
169 | - if (stack[pos] == tagName) | ||
170 | - break; | ||
171 | - } | ||
172 | - if (pos >= 0) { | ||
173 | - // Close all the open elements, up the stack | ||
174 | - for (var i = stack.length - 1; i >= pos; i--) | ||
175 | - if (handler.end) | ||
176 | - handler.end(stack[i]); | ||
177 | - | ||
178 | - // Remove the open elements from the stack | ||
179 | - stack.length = pos; | ||
180 | - } | ||
181 | - } | ||
182 | -}; | ||
183 | - | ||
184 | - | ||
185 | -function makeMap(str) { | ||
186 | - var obj = {}, items = str.split(","); | ||
187 | - for (var i = 0; i < items.length; i++) | ||
188 | - obj[items[i]] = true; | ||
189 | - return obj; | ||
190 | -} | ||
191 | - | ||
192 | -module.exports = HTMLParser; |
wxParse/showdown.js
已删除
100644 → 0
1 | -/** | ||
2 | - * | ||
3 | - * showdown: https://github.com/showdownjs/showdown | ||
4 | - * | ||
5 | - * author: Di (微信小程序开发工程师) | ||
6 | - * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | ||
7 | - * 垂直微信小程序开发交流社区 | ||
8 | - * | ||
9 | - * github地址: https://github.com/icindy/wxParse | ||
10 | - * | ||
11 | - * for: 微信小程序富文本解析 | ||
12 | - * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | ||
13 | - */ | ||
14 | - | ||
15 | -function getDefaultOpts(simple) { | ||
16 | - 'use strict'; | ||
17 | - | ||
18 | - var defaultOptions = { | ||
19 | - omitExtraWLInCodeBlocks: { | ||
20 | - defaultValue: false, | ||
21 | - describe: 'Omit the default extra whiteline added to code blocks', | ||
22 | - type: 'boolean' | ||
23 | - }, | ||
24 | - noHeaderId: { | ||
25 | - defaultValue: false, | ||
26 | - describe: 'Turn on/off generated header id', | ||
27 | - type: 'boolean' | ||
28 | - }, | ||
29 | - prefixHeaderId: { | ||
30 | - defaultValue: false, | ||
31 | - describe: 'Specify a prefix to generated header ids', | ||
32 | - type: 'string' | ||
33 | - }, | ||
34 | - headerLevelStart: { | ||
35 | - defaultValue: false, | ||
36 | - describe: 'The header blocks level start', | ||
37 | - type: 'integer' | ||
38 | - }, | ||
39 | - parseImgDimensions: { | ||
40 | - defaultValue: false, | ||
41 | - describe: 'Turn on/off image dimension parsing', | ||
42 | - type: 'boolean' | ||
43 | - }, | ||
44 | - simplifiedAutoLink: { | ||
45 | - defaultValue: false, | ||
46 | - describe: 'Turn on/off GFM autolink style', | ||
47 | - type: 'boolean' | ||
48 | - }, | ||
49 | - literalMidWordUnderscores: { | ||
50 | - defaultValue: false, | ||
51 | - describe: 'Parse midword underscores as literal underscores', | ||
52 | - type: 'boolean' | ||
53 | - }, | ||
54 | - strikethrough: { | ||
55 | - defaultValue: false, | ||
56 | - describe: 'Turn on/off strikethrough support', | ||
57 | - type: 'boolean' | ||
58 | - }, | ||
59 | - tables: { | ||
60 | - defaultValue: false, | ||
61 | - describe: 'Turn on/off tables support', | ||
62 | - type: 'boolean' | ||
63 | - }, | ||
64 | - tablesHeaderId: { | ||
65 | - defaultValue: false, | ||
66 | - describe: 'Add an id to table headers', | ||
67 | - type: 'boolean' | ||
68 | - }, | ||
69 | - ghCodeBlocks: { | ||
70 | - defaultValue: true, | ||
71 | - describe: 'Turn on/off GFM fenced code blocks support', | ||
72 | - type: 'boolean' | ||
73 | - }, | ||
74 | - tasklists: { | ||
75 | - defaultValue: false, | ||
76 | - describe: 'Turn on/off GFM tasklist support', | ||
77 | - type: 'boolean' | ||
78 | - }, | ||
79 | - smoothLivePreview: { | ||
80 | - defaultValue: false, | ||
81 | - describe: 'Prevents weird effects in live previews due to incomplete input', | ||
82 | - type: 'boolean' | ||
83 | - }, | ||
84 | - smartIndentationFix: { | ||
85 | - defaultValue: false, | ||
86 | - description: 'Tries to smartly fix identation in es6 strings', | ||
87 | - type: 'boolean' | ||
88 | - } | ||
89 | - }; | ||
90 | - if (simple === false) { | ||
91 | - return JSON.parse(JSON.stringify(defaultOptions)); | ||
92 | - } | ||
93 | - var ret = {}; | ||
94 | - for (var opt in defaultOptions) { | ||
95 | - if (defaultOptions.hasOwnProperty(opt)) { | ||
96 | - ret[opt] = defaultOptions[opt].defaultValue; | ||
97 | - } | ||
98 | - } | ||
99 | - return ret; | ||
100 | -} | ||
101 | - | ||
102 | -/** | ||
103 | - * Created by Tivie on 06-01-2015. | ||
104 | - */ | ||
105 | - | ||
106 | -// Private properties | ||
107 | -var showdown = {}, | ||
108 | - parsers = {}, | ||
109 | - extensions = {}, | ||
110 | - globalOptions = getDefaultOpts(true), | ||
111 | - flavor = { | ||
112 | - github: { | ||
113 | - omitExtraWLInCodeBlocks: true, | ||
114 | - prefixHeaderId: 'user-content-', | ||
115 | - simplifiedAutoLink: true, | ||
116 | - literalMidWordUnderscores: true, | ||
117 | - strikethrough: true, | ||
118 | - tables: true, | ||
119 | - tablesHeaderId: true, | ||
120 | - ghCodeBlocks: true, | ||
121 | - tasklists: true | ||
122 | - }, | ||
123 | - vanilla: getDefaultOpts(true) | ||
124 | - }; | ||
125 | - | ||
126 | -/** | ||
127 | - * helper namespace | ||
128 | - * @type {{}} | ||
129 | - */ | ||
130 | -showdown.helper = {}; | ||
131 | - | ||
132 | -/** | ||
133 | - * TODO LEGACY SUPPORT CODE | ||
134 | - * @type {{}} | ||
135 | - */ | ||
136 | -showdown.extensions = {}; | ||
137 | - | ||
138 | -/** | ||
139 | - * Set a global option | ||
140 | - * @static | ||
141 | - * @param {string} key | ||
142 | - * @param {*} value | ||
143 | - * @returns {showdown} | ||
144 | - */ | ||
145 | -showdown.setOption = function (key, value) { | ||
146 | - 'use strict'; | ||
147 | - globalOptions[key] = value; | ||
148 | - return this; | ||
149 | -}; | ||
150 | - | ||
151 | -/** | ||
152 | - * Get a global option | ||
153 | - * @static | ||
154 | - * @param {string} key | ||
155 | - * @returns {*} | ||
156 | - */ | ||
157 | -showdown.getOption = function (key) { | ||
158 | - 'use strict'; | ||
159 | - return globalOptions[key]; | ||
160 | -}; | ||
161 | - | ||
162 | -/** | ||
163 | - * Get the global options | ||
164 | - * @static | ||
165 | - * @returns {{}} | ||
166 | - */ | ||
167 | -showdown.getOptions = function () { | ||
168 | - 'use strict'; | ||
169 | - return globalOptions; | ||
170 | -}; | ||
171 | - | ||
172 | -/** | ||
173 | - * Reset global options to the default values | ||
174 | - * @static | ||
175 | - */ | ||
176 | -showdown.resetOptions = function () { | ||
177 | - 'use strict'; | ||
178 | - globalOptions = getDefaultOpts(true); | ||
179 | -}; | ||
180 | - | ||
181 | -/** | ||
182 | - * Set the flavor showdown should use as default | ||
183 | - * @param {string} name | ||
184 | - */ | ||
185 | -showdown.setFlavor = function (name) { | ||
186 | - 'use strict'; | ||
187 | - if (flavor.hasOwnProperty(name)) { | ||
188 | - var preset = flavor[name]; | ||
189 | - for (var option in preset) { | ||
190 | - if (preset.hasOwnProperty(option)) { | ||
191 | - globalOptions[option] = preset[option]; | ||
192 | - } | ||
193 | - } | ||
194 | - } | ||
195 | -}; | ||
196 | - | ||
197 | -/** | ||
198 | - * Get the default options | ||
199 | - * @static | ||
200 | - * @param {boolean} [simple=true] | ||
201 | - * @returns {{}} | ||
202 | - */ | ||
203 | -showdown.getDefaultOptions = function (simple) { | ||
204 | - 'use strict'; | ||
205 | - return getDefaultOpts(simple); | ||
206 | -}; | ||
207 | - | ||
208 | -/** | ||
209 | - * Get or set a subParser | ||
210 | - * | ||
211 | - * subParser(name) - Get a registered subParser | ||
212 | - * subParser(name, func) - Register a subParser | ||
213 | - * @static | ||
214 | - * @param {string} name | ||
215 | - * @param {function} [func] | ||
216 | - * @returns {*} | ||
217 | - */ | ||
218 | -showdown.subParser = function (name, func) { | ||
219 | - 'use strict'; | ||
220 | - if (showdown.helper.isString(name)) { | ||
221 | - if (typeof func !== 'undefined') { | ||
222 | - parsers[name] = func; | ||
223 | - } else { | ||
224 | - if (parsers.hasOwnProperty(name)) { | ||
225 | - return parsers[name]; | ||
226 | - } else { | ||
227 | - throw Error('SubParser named ' + name + ' not registered!'); | ||
228 | - } | ||
229 | - } | ||
230 | - } | ||
231 | -}; | ||
232 | - | ||
233 | -/** | ||
234 | - * Gets or registers an extension | ||
235 | - * @static | ||
236 | - * @param {string} name | ||
237 | - * @param {object|function=} ext | ||
238 | - * @returns {*} | ||
239 | - */ | ||
240 | -showdown.extension = function (name, ext) { | ||
241 | - 'use strict'; | ||
242 | - | ||
243 | - if (!showdown.helper.isString(name)) { | ||
244 | - throw Error('Extension \'name\' must be a string'); | ||
245 | - } | ||
246 | - | ||
247 | - name = showdown.helper.stdExtName(name); | ||
248 | - | ||
249 | - // Getter | ||
250 | - if (showdown.helper.isUndefined(ext)) { | ||
251 | - if (!extensions.hasOwnProperty(name)) { | ||
252 | - throw Error('Extension named ' + name + ' is not registered!'); | ||
253 | - } | ||
254 | - return extensions[name]; | ||
255 | - | ||
256 | - // Setter | ||
257 | - } else { | ||
258 | - // Expand extension if it's wrapped in a function | ||
259 | - if (typeof ext === 'function') { | ||
260 | - ext = ext(); | ||
261 | - } | ||
262 | - | ||
263 | - // Ensure extension is an array | ||
264 | - if (!showdown.helper.isArray(ext)) { | ||
265 | - ext = [ext]; | ||
266 | - } | ||
267 | - | ||
268 | - var validExtension = validate(ext, name); | ||
269 | - | ||
270 | - if (validExtension.valid) { | ||
271 | - extensions[name] = ext; | ||
272 | - } else { | ||
273 | - throw Error(validExtension.error); | ||
274 | - } | ||
275 | - } | ||
276 | -}; | ||
277 | - | ||
278 | -/** | ||
279 | - * Gets all extensions registered | ||
280 | - * @returns {{}} | ||
281 | - */ | ||
282 | -showdown.getAllExtensions = function () { | ||
283 | - 'use strict'; | ||
284 | - return extensions; | ||
285 | -}; | ||
286 | - | ||
287 | -/** | ||
288 | - * Remove an extension | ||
289 | - * @param {string} name | ||
290 | - */ | ||
291 | -showdown.removeExtension = function (name) { | ||
292 | - 'use strict'; | ||
293 | - delete extensions[name]; | ||
294 | -}; | ||
295 | - | ||
296 | -/** | ||
297 | - * Removes all extensions | ||
298 | - */ | ||
299 | -showdown.resetExtensions = function () { | ||
300 | - 'use strict'; | ||
301 | - extensions = {}; | ||
302 | -}; | ||
303 | - | ||
304 | -/** | ||
305 | - * Validate extension | ||
306 | - * @param {array} extension | ||
307 | - * @param {string} name | ||
308 | - * @returns {{valid: boolean, error: string}} | ||
309 | - */ | ||
310 | -function validate(extension, name) { | ||
311 | - 'use strict'; | ||
312 | - | ||
313 | - var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension', | ||
314 | - ret = { | ||
315 | - valid: true, | ||
316 | - error: '' | ||
317 | - }; | ||
318 | - | ||
319 | - if (!showdown.helper.isArray(extension)) { | ||
320 | - extension = [extension]; | ||
321 | - } | ||
322 | - | ||
323 | - for (var i = 0; i < extension.length; ++i) { | ||
324 | - var baseMsg = errMsg + ' sub-extension ' + i + ': ', | ||
325 | - ext = extension[i]; | ||
326 | - if (typeof ext !== 'object') { | ||
327 | - ret.valid = false; | ||
328 | - ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given'; | ||
329 | - return ret; | ||
330 | - } | ||
331 | - | ||
332 | - if (!showdown.helper.isString(ext.type)) { | ||
333 | - ret.valid = false; | ||
334 | - ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given'; | ||
335 | - return ret; | ||
336 | - } | ||
337 | - | ||
338 | - var type = ext.type = ext.type.toLowerCase(); | ||
339 | - | ||
340 | - // normalize extension type | ||
341 | - if (type === 'language') { | ||
342 | - type = ext.type = 'lang'; | ||
343 | - } | ||
344 | - | ||
345 | - if (type === 'html') { | ||
346 | - type = ext.type = 'output'; | ||
347 | - } | ||
348 | - | ||
349 | - if (type !== 'lang' && type !== 'output' && type !== 'listener') { | ||
350 | - ret.valid = false; | ||
351 | - ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"'; | ||
352 | - return ret; | ||
353 | - } | ||
354 | - | ||
355 | - if (type === 'listener') { | ||
356 | - if (showdown.helper.isUndefined(ext.listeners)) { | ||
357 | - ret.valid = false; | ||
358 | - ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"'; | ||
359 | - return ret; | ||
360 | - } | ||
361 | - } else { | ||
362 | - if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) { | ||
363 | - ret.valid = false; | ||
364 | - ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method'; | ||
365 | - return ret; | ||
366 | - } | ||
367 | - } | ||
368 | - | ||
369 | - if (ext.listeners) { | ||
370 | - if (typeof ext.listeners !== 'object') { | ||
371 | - ret.valid = false; | ||
372 | - ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given'; | ||
373 | - return ret; | ||
374 | - } | ||
375 | - for (var ln in ext.listeners) { | ||
376 | - if (ext.listeners.hasOwnProperty(ln)) { | ||
377 | - if (typeof ext.listeners[ln] !== 'function') { | ||
378 | - ret.valid = false; | ||
379 | - ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln + | ||
380 | - ' must be a function but ' + typeof ext.listeners[ln] + ' given'; | ||
381 | - return ret; | ||
382 | - } | ||
383 | - } | ||
384 | - } | ||
385 | - } | ||
386 | - | ||
387 | - if (ext.filter) { | ||
388 | - if (typeof ext.filter !== 'function') { | ||
389 | - ret.valid = false; | ||
390 | - ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given'; | ||
391 | - return ret; | ||
392 | - } | ||
393 | - } else if (ext.regex) { | ||
394 | - if (showdown.helper.isString(ext.regex)) { | ||
395 | - ext.regex = new RegExp(ext.regex, 'g'); | ||
396 | - } | ||
397 | - if (!ext.regex instanceof RegExp) { | ||
398 | - ret.valid = false; | ||
399 | - ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given'; | ||
400 | - return ret; | ||
401 | - } | ||
402 | - if (showdown.helper.isUndefined(ext.replace)) { | ||
403 | - ret.valid = false; | ||
404 | - ret.error = baseMsg + '"regex" extensions must implement a replace string or function'; | ||
405 | - return ret; | ||
406 | - } | ||
407 | - } | ||
408 | - } | ||
409 | - return ret; | ||
410 | -} | ||
411 | - | ||
412 | -/** | ||
413 | - * Validate extension | ||
414 | - * @param {object} ext | ||
415 | - * @returns {boolean} | ||
416 | - */ | ||
417 | -showdown.validateExtension = function (ext) { | ||
418 | - 'use strict'; | ||
419 | - | ||
420 | - var validateExtension = validate(ext, null); | ||
421 | - if (!validateExtension.valid) { | ||
422 | - console.warn(validateExtension.error); | ||
423 | - return false; | ||
424 | - } | ||
425 | - return true; | ||
426 | -}; | ||
427 | - | ||
428 | -/** | ||
429 | - * showdownjs helper functions | ||
430 | - */ | ||
431 | - | ||
432 | -if (!showdown.hasOwnProperty('helper')) { | ||
433 | - showdown.helper = {}; | ||
434 | -} | ||
435 | - | ||
436 | -/** | ||
437 | - * Check if var is string | ||
438 | - * @static | ||
439 | - * @param {string} a | ||
440 | - * @returns {boolean} | ||
441 | - */ | ||
442 | -showdown.helper.isString = function isString(a) { | ||
443 | - 'use strict'; | ||
444 | - return (typeof a === 'string' || a instanceof String); | ||
445 | -}; | ||
446 | - | ||
447 | -/** | ||
448 | - * Check if var is a function | ||
449 | - * @static | ||
450 | - * @param {string} a | ||
451 | - * @returns {boolean} | ||
452 | - */ | ||
453 | -showdown.helper.isFunction = function isFunction(a) { | ||
454 | - 'use strict'; | ||
455 | - var getType = {}; | ||
456 | - return a && getType.toString.call(a) === '[object Function]'; | ||
457 | -}; | ||
458 | - | ||
459 | -/** | ||
460 | - * ForEach helper function | ||
461 | - * @static | ||
462 | - * @param {*} obj | ||
463 | - * @param {function} callback | ||
464 | - */ | ||
465 | -showdown.helper.forEach = function forEach(obj, callback) { | ||
466 | - 'use strict'; | ||
467 | - if (typeof obj.forEach === 'function') { | ||
468 | - obj.forEach(callback); | ||
469 | - } else { | ||
470 | - for (var i = 0; i < obj.length; i++) { | ||
471 | - callback(obj[i], i, obj); | ||
472 | - } | ||
473 | - } | ||
474 | -}; | ||
475 | - | ||
476 | -/** | ||
477 | - * isArray helper function | ||
478 | - * @static | ||
479 | - * @param {*} a | ||
480 | - * @returns {boolean} | ||
481 | - */ | ||
482 | -showdown.helper.isArray = function isArray(a) { | ||
483 | - 'use strict'; | ||
484 | - return a.constructor === Array; | ||
485 | -}; | ||
486 | - | ||
487 | -/** | ||
488 | - * Check if value is undefined | ||
489 | - * @static | ||
490 | - * @param {*} value The value to check. | ||
491 | - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. | ||
492 | - */ | ||
493 | -showdown.helper.isUndefined = function isUndefined(value) { | ||
494 | - 'use strict'; | ||
495 | - return typeof value === 'undefined'; | ||
496 | -}; | ||
497 | - | ||
498 | -/** | ||
499 | - * Standardidize extension name | ||
500 | - * @static | ||
501 | - * @param {string} s extension name | ||
502 | - * @returns {string} | ||
503 | - */ | ||
504 | -showdown.helper.stdExtName = function (s) { | ||
505 | - 'use strict'; | ||
506 | - return s.replace(/[_-]||\s/g, '').toLowerCase(); | ||
507 | -}; | ||
508 | - | ||
509 | -function escapeCharactersCallback(wholeMatch, m1) { | ||
510 | - 'use strict'; | ||
511 | - var charCodeToEscape = m1.charCodeAt(0); | ||
512 | - return '~E' + charCodeToEscape + 'E'; | ||
513 | -} | ||
514 | - | ||
515 | -/** | ||
516 | - * Callback used to escape characters when passing through String.replace | ||
517 | - * @static | ||
518 | - * @param {string} wholeMatch | ||
519 | - * @param {string} m1 | ||
520 | - * @returns {string} | ||
521 | - */ | ||
522 | -showdown.helper.escapeCharactersCallback = escapeCharactersCallback; | ||
523 | - | ||
524 | -/** | ||
525 | - * Escape characters in a string | ||
526 | - * @static | ||
527 | - * @param {string} text | ||
528 | - * @param {string} charsToEscape | ||
529 | - * @param {boolean} afterBackslash | ||
530 | - * @returns {XML|string|void|*} | ||
531 | - */ | ||
532 | -showdown.helper.escapeCharacters = function escapeCharacters(text, charsToEscape, afterBackslash) { | ||
533 | - 'use strict'; | ||
534 | - // First we have to escape the escape characters so that | ||
535 | - // we can build a character class out of them | ||
536 | - var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])'; | ||
537 | - | ||
538 | - if (afterBackslash) { | ||
539 | - regexString = '\\\\' + regexString; | ||
540 | - } | ||
541 | - | ||
542 | - var regex = new RegExp(regexString, 'g'); | ||
543 | - text = text.replace(regex, escapeCharactersCallback); | ||
544 | - | ||
545 | - return text; | ||
546 | -}; | ||
547 | - | ||
548 | -var rgxFindMatchPos = function (str, left, right, flags) { | ||
549 | - 'use strict'; | ||
550 | - var f = flags || '', | ||
551 | - g = f.indexOf('g') > -1, | ||
552 | - x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')), | ||
553 | - l = new RegExp(left, f.replace(/g/g, '')), | ||
554 | - pos = [], | ||
555 | - t, s, m, start, end; | ||
556 | - | ||
557 | - do { | ||
558 | - t = 0; | ||
559 | - while ((m = x.exec(str))) { | ||
560 | - if (l.test(m[0])) { | ||
561 | - if (!(t++)) { | ||
562 | - s = x.lastIndex; | ||
563 | - start = s - m[0].length; | ||
564 | - } | ||
565 | - } else if (t) { | ||
566 | - if (!--t) { | ||
567 | - end = m.index + m[0].length; | ||
568 | - var obj = { | ||
569 | - left: {start: start, end: s}, | ||
570 | - match: {start: s, end: m.index}, | ||
571 | - right: {start: m.index, end: end}, | ||
572 | - wholeMatch: {start: start, end: end} | ||
573 | - }; | ||
574 | - pos.push(obj); | ||
575 | - if (!g) { | ||
576 | - return pos; | ||
577 | - } | ||
578 | - } | ||
579 | - } | ||
580 | - } | ||
581 | - } while (t && (x.lastIndex = s)); | ||
582 | - | ||
583 | - return pos; | ||
584 | -}; | ||
585 | - | ||
586 | -/** | ||
587 | - * matchRecursiveRegExp | ||
588 | - * | ||
589 | - * (c) 2007 Steven Levithan <stevenlevithan.com> | ||
590 | - * MIT License | ||
591 | - * | ||
592 | - * Accepts a string to search, a left and right format delimiter | ||
593 | - * as regex patterns, and optional regex flags. Returns an array | ||
594 | - * of matches, allowing nested instances of left/right delimiters. | ||
595 | - * Use the "g" flag to return all matches, otherwise only the | ||
596 | - * first is returned. Be careful to ensure that the left and | ||
597 | - * right format delimiters produce mutually exclusive matches. | ||
598 | - * Backreferences are not supported within the right delimiter | ||
599 | - * due to how it is internally combined with the left delimiter. | ||
600 | - * When matching strings whose format delimiters are unbalanced | ||
601 | - * to the left or right, the output is intentionally as a | ||
602 | - * conventional regex library with recursion support would | ||
603 | - * produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using | ||
604 | - * "<" and ">" as the delimiters (both strings contain a single, | ||
605 | - * balanced instance of "<x>"). | ||
606 | - * | ||
607 | - * examples: | ||
608 | - * matchRecursiveRegExp("test", "\\(", "\\)") | ||
609 | - * returns: [] | ||
610 | - * matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g") | ||
611 | - * returns: ["t<<e>><s>", ""] | ||
612 | - * matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi") | ||
613 | - * returns: ["test"] | ||
614 | - */ | ||
615 | -showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) { | ||
616 | - 'use strict'; | ||
617 | - | ||
618 | - var matchPos = rgxFindMatchPos (str, left, right, flags), | ||
619 | - results = []; | ||
620 | - | ||
621 | - for (var i = 0; i < matchPos.length; ++i) { | ||
622 | - results.push([ | ||
623 | - str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), | ||
624 | - str.slice(matchPos[i].match.start, matchPos[i].match.end), | ||
625 | - str.slice(matchPos[i].left.start, matchPos[i].left.end), | ||
626 | - str.slice(matchPos[i].right.start, matchPos[i].right.end) | ||
627 | - ]); | ||
628 | - } | ||
629 | - return results; | ||
630 | -}; | ||
631 | - | ||
632 | -/** | ||
633 | - * | ||
634 | - * @param {string} str | ||
635 | - * @param {string|function} replacement | ||
636 | - * @param {string} left | ||
637 | - * @param {string} right | ||
638 | - * @param {string} flags | ||
639 | - * @returns {string} | ||
640 | - */ | ||
641 | -showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) { | ||
642 | - 'use strict'; | ||
643 | - | ||
644 | - if (!showdown.helper.isFunction(replacement)) { | ||
645 | - var repStr = replacement; | ||
646 | - replacement = function () { | ||
647 | - return repStr; | ||
648 | - }; | ||
649 | - } | ||
650 | - | ||
651 | - var matchPos = rgxFindMatchPos(str, left, right, flags), | ||
652 | - finalStr = str, | ||
653 | - lng = matchPos.length; | ||
654 | - | ||
655 | - if (lng > 0) { | ||
656 | - var bits = []; | ||
657 | - if (matchPos[0].wholeMatch.start !== 0) { | ||
658 | - bits.push(str.slice(0, matchPos[0].wholeMatch.start)); | ||
659 | - } | ||
660 | - for (var i = 0; i < lng; ++i) { | ||
661 | - bits.push( | ||
662 | - replacement( | ||
663 | - str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), | ||
664 | - str.slice(matchPos[i].match.start, matchPos[i].match.end), | ||
665 | - str.slice(matchPos[i].left.start, matchPos[i].left.end), | ||
666 | - str.slice(matchPos[i].right.start, matchPos[i].right.end) | ||
667 | - ) | ||
668 | - ); | ||
669 | - if (i < lng - 1) { | ||
670 | - bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start)); | ||
671 | - } | ||
672 | - } | ||
673 | - if (matchPos[lng - 1].wholeMatch.end < str.length) { | ||
674 | - bits.push(str.slice(matchPos[lng - 1].wholeMatch.end)); | ||
675 | - } | ||
676 | - finalStr = bits.join(''); | ||
677 | - } | ||
678 | - return finalStr; | ||
679 | -}; | ||
680 | - | ||
681 | -/** | ||
682 | - * POLYFILLS | ||
683 | - */ | ||
684 | -if (showdown.helper.isUndefined(console)) { | ||
685 | - console = { | ||
686 | - warn: function (msg) { | ||
687 | - 'use strict'; | ||
688 | - alert(msg); | ||
689 | - }, | ||
690 | - log: function (msg) { | ||
691 | - 'use strict'; | ||
692 | - alert(msg); | ||
693 | - }, | ||
694 | - error: function (msg) { | ||
695 | - 'use strict'; | ||
696 | - throw msg; | ||
697 | - } | ||
698 | - }; | ||
699 | -} | ||
700 | - | ||
701 | -/** | ||
702 | - * Created by Estevao on 31-05-2015. | ||
703 | - */ | ||
704 | - | ||
705 | -/** | ||
706 | - * Showdown Converter class | ||
707 | - * @class | ||
708 | - * @param {object} [converterOptions] | ||
709 | - * @returns {Converter} | ||
710 | - */ | ||
711 | -showdown.Converter = function (converterOptions) { | ||
712 | - 'use strict'; | ||
713 | - | ||
714 | - var | ||
715 | - /** | ||
716 | - * Options used by this converter | ||
717 | - * @private | ||
718 | - * @type {{}} | ||
719 | - */ | ||
720 | - options = {}, | ||
721 | - | ||
722 | - /** | ||
723 | - * Language extensions used by this converter | ||
724 | - * @private | ||
725 | - * @type {Array} | ||
726 | - */ | ||
727 | - langExtensions = [], | ||
728 | - | ||
729 | - /** | ||
730 | - * Output modifiers extensions used by this converter | ||
731 | - * @private | ||
732 | - * @type {Array} | ||
733 | - */ | ||
734 | - outputModifiers = [], | ||
735 | - | ||
736 | - /** | ||
737 | - * Event listeners | ||
738 | - * @private | ||
739 | - * @type {{}} | ||
740 | - */ | ||
741 | - listeners = {}; | ||
742 | - | ||
743 | - _constructor(); | ||
744 | - | ||
745 | - /** | ||
746 | - * Converter constructor | ||
747 | - * @private | ||
748 | - */ | ||
749 | - function _constructor() { | ||
750 | - converterOptions = converterOptions || {}; | ||
751 | - | ||
752 | - for (var gOpt in globalOptions) { | ||
753 | - if (globalOptions.hasOwnProperty(gOpt)) { | ||
754 | - options[gOpt] = globalOptions[gOpt]; | ||
755 | - } | ||
756 | - } | ||
757 | - | ||
758 | - // Merge options | ||
759 | - if (typeof converterOptions === 'object') { | ||
760 | - for (var opt in converterOptions) { | ||
761 | - if (converterOptions.hasOwnProperty(opt)) { | ||
762 | - options[opt] = converterOptions[opt]; | ||
763 | - } | ||
764 | - } | ||
765 | - } else { | ||
766 | - throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions + | ||
767 | - ' was passed instead.'); | ||
768 | - } | ||
769 | - | ||
770 | - if (options.extensions) { | ||
771 | - showdown.helper.forEach(options.extensions, _parseExtension); | ||
772 | - } | ||
773 | - } | ||
774 | - | ||
775 | - /** | ||
776 | - * Parse extension | ||
777 | - * @param {*} ext | ||
778 | - * @param {string} [name=''] | ||
779 | - * @private | ||
780 | - */ | ||
781 | - function _parseExtension(ext, name) { | ||
782 | - | ||
783 | - name = name || null; | ||
784 | - // If it's a string, the extension was previously loaded | ||
785 | - if (showdown.helper.isString(ext)) { | ||
786 | - ext = showdown.helper.stdExtName(ext); | ||
787 | - name = ext; | ||
788 | - | ||
789 | - // LEGACY_SUPPORT CODE | ||
790 | - if (showdown.extensions[ext]) { | ||
791 | - console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' + | ||
792 | - 'Please inform the developer that the extension should be updated!'); | ||
793 | - legacyExtensionLoading(showdown.extensions[ext], ext); | ||
794 | - return; | ||
795 | - // END LEGACY SUPPORT CODE | ||
796 | - | ||
797 | - } else if (!showdown.helper.isUndefined(extensions[ext])) { | ||
798 | - ext = extensions[ext]; | ||
799 | - | ||
800 | - } else { | ||
801 | - throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.'); | ||
802 | - } | ||
803 | - } | ||
804 | - | ||
805 | - if (typeof ext === 'function') { | ||
806 | - ext = ext(); | ||
807 | - } | ||
808 | - | ||
809 | - if (!showdown.helper.isArray(ext)) { | ||
810 | - ext = [ext]; | ||
811 | - } | ||
812 | - | ||
813 | - var validExt = validate(ext, name); | ||
814 | - if (!validExt.valid) { | ||
815 | - throw Error(validExt.error); | ||
816 | - } | ||
817 | - | ||
818 | - for (var i = 0; i < ext.length; ++i) { | ||
819 | - switch (ext[i].type) { | ||
820 | - | ||
821 | - case 'lang': | ||
822 | - langExtensions.push(ext[i]); | ||
823 | - break; | ||
824 | - | ||
825 | - case 'output': | ||
826 | - outputModifiers.push(ext[i]); | ||
827 | - break; | ||
828 | - } | ||
829 | - if (ext[i].hasOwnProperty(listeners)) { | ||
830 | - for (var ln in ext[i].listeners) { | ||
831 | - if (ext[i].listeners.hasOwnProperty(ln)) { | ||
832 | - listen(ln, ext[i].listeners[ln]); | ||
833 | - } | ||
834 | - } | ||
835 | - } | ||
836 | - } | ||
837 | - | ||
838 | - } | ||
839 | - | ||
840 | - /** | ||
841 | - * LEGACY_SUPPORT | ||
842 | - * @param {*} ext | ||
843 | - * @param {string} name | ||
844 | - */ | ||
845 | - function legacyExtensionLoading(ext, name) { | ||
846 | - if (typeof ext === 'function') { | ||
847 | - ext = ext(new showdown.Converter()); | ||
848 | - } | ||
849 | - if (!showdown.helper.isArray(ext)) { | ||
850 | - ext = [ext]; | ||
851 | - } | ||
852 | - var valid = validate(ext, name); | ||
853 | - | ||
854 | - if (!valid.valid) { | ||
855 | - throw Error(valid.error); | ||
856 | - } | ||
857 | - | ||
858 | - for (var i = 0; i < ext.length; ++i) { | ||
859 | - switch (ext[i].type) { | ||
860 | - case 'lang': | ||
861 | - langExtensions.push(ext[i]); | ||
862 | - break; | ||
863 | - case 'output': | ||
864 | - outputModifiers.push(ext[i]); | ||
865 | - break; | ||
866 | - default:// should never reach here | ||
867 | - throw Error('Extension loader error: Type unrecognized!!!'); | ||
868 | - } | ||
869 | - } | ||
870 | - } | ||
871 | - | ||
872 | - /** | ||
873 | - * Listen to an event | ||
874 | - * @param {string} name | ||
875 | - * @param {function} callback | ||
876 | - */ | ||
877 | - function listen(name, callback) { | ||
878 | - if (!showdown.helper.isString(name)) { | ||
879 | - throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given'); | ||
880 | - } | ||
881 | - | ||
882 | - if (typeof callback !== 'function') { | ||
883 | - throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given'); | ||
884 | - } | ||
885 | - | ||
886 | - if (!listeners.hasOwnProperty(name)) { | ||
887 | - listeners[name] = []; | ||
888 | - } | ||
889 | - listeners[name].push(callback); | ||
890 | - } | ||
891 | - | ||
892 | - function rTrimInputText(text) { | ||
893 | - var rsp = text.match(/^\s*/)[0].length, | ||
894 | - rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm'); | ||
895 | - return text.replace(rgx, ''); | ||
896 | - } | ||
897 | - | ||
898 | - /** | ||
899 | - * Dispatch an event | ||
900 | - * @private | ||
901 | - * @param {string} evtName Event name | ||
902 | - * @param {string} text Text | ||
903 | - * @param {{}} options Converter Options | ||
904 | - * @param {{}} globals | ||
905 | - * @returns {string} | ||
906 | - */ | ||
907 | - this._dispatch = function dispatch (evtName, text, options, globals) { | ||
908 | - if (listeners.hasOwnProperty(evtName)) { | ||
909 | - for (var ei = 0; ei < listeners[evtName].length; ++ei) { | ||
910 | - var nText = listeners[evtName][ei](evtName, text, this, options, globals); | ||
911 | - if (nText && typeof nText !== 'undefined') { | ||
912 | - text = nText; | ||
913 | - } | ||
914 | - } | ||
915 | - } | ||
916 | - return text; | ||
917 | - }; | ||
918 | - | ||
919 | - /** | ||
920 | - * Listen to an event | ||
921 | - * @param {string} name | ||
922 | - * @param {function} callback | ||
923 | - * @returns {showdown.Converter} | ||
924 | - */ | ||
925 | - this.listen = function (name, callback) { | ||
926 | - listen(name, callback); | ||
927 | - return this; | ||
928 | - }; | ||
929 | - | ||
930 | - /** | ||
931 | - * Converts a markdown string into HTML | ||
932 | - * @param {string} text | ||
933 | - * @returns {*} | ||
934 | - */ | ||
935 | - this.makeHtml = function (text) { | ||
936 | - //check if text is not falsy | ||
937 | - if (!text) { | ||
938 | - return text; | ||
939 | - } | ||
940 | - | ||
941 | - var globals = { | ||
942 | - gHtmlBlocks: [], | ||
943 | - gHtmlMdBlocks: [], | ||
944 | - gHtmlSpans: [], | ||
945 | - gUrls: {}, | ||
946 | - gTitles: {}, | ||
947 | - gDimensions: {}, | ||
948 | - gListLevel: 0, | ||
949 | - hashLinkCounts: {}, | ||
950 | - langExtensions: langExtensions, | ||
951 | - outputModifiers: outputModifiers, | ||
952 | - converter: this, | ||
953 | - ghCodeBlocks: [] | ||
954 | - }; | ||
955 | - | ||
956 | - // attacklab: Replace ~ with ~T | ||
957 | - // This lets us use tilde as an escape char to avoid md5 hashes | ||
958 | - // The choice of character is arbitrary; anything that isn't | ||
959 | - // magic in Markdown will work. | ||
960 | - text = text.replace(/~/g, '~T'); | ||
961 | - | ||
962 | - // attacklab: Replace $ with ~D | ||
963 | - // RegExp interprets $ as a special character | ||
964 | - // when it's in a replacement string | ||
965 | - text = text.replace(/\$/g, '~D'); | ||
966 | - | ||
967 | - // Standardize line endings | ||
968 | - text = text.replace(/\r\n/g, '\n'); // DOS to Unix | ||
969 | - text = text.replace(/\r/g, '\n'); // Mac to Unix | ||
970 | - | ||
971 | - if (options.smartIndentationFix) { | ||
972 | - text = rTrimInputText(text); | ||
973 | - } | ||
974 | - | ||
975 | - // Make sure text begins and ends with a couple of newlines: | ||
976 | - //text = '\n\n' + text + '\n\n'; | ||
977 | - text = text; | ||
978 | - // detab | ||
979 | - text = showdown.subParser('detab')(text, options, globals); | ||
980 | - | ||
981 | - // stripBlankLines | ||
982 | - text = showdown.subParser('stripBlankLines')(text, options, globals); | ||
983 | - | ||
984 | - //run languageExtensions | ||
985 | - showdown.helper.forEach(langExtensions, function (ext) { | ||
986 | - text = showdown.subParser('runExtension')(ext, text, options, globals); | ||
987 | - }); | ||
988 | - | ||
989 | - // run the sub parsers | ||
990 | - text = showdown.subParser('hashPreCodeTags')(text, options, globals); | ||
991 | - text = showdown.subParser('githubCodeBlocks')(text, options, globals); | ||
992 | - text = showdown.subParser('hashHTMLBlocks')(text, options, globals); | ||
993 | - text = showdown.subParser('hashHTMLSpans')(text, options, globals); | ||
994 | - text = showdown.subParser('stripLinkDefinitions')(text, options, globals); | ||
995 | - text = showdown.subParser('blockGamut')(text, options, globals); | ||
996 | - text = showdown.subParser('unhashHTMLSpans')(text, options, globals); | ||
997 | - text = showdown.subParser('unescapeSpecialChars')(text, options, globals); | ||
998 | - | ||
999 | - // attacklab: Restore dollar signs | ||
1000 | - text = text.replace(/~D/g, '$$'); | ||
1001 | - | ||
1002 | - // attacklab: Restore tildes | ||
1003 | - text = text.replace(/~T/g, '~'); | ||
1004 | - | ||
1005 | - // Run output modifiers | ||
1006 | - showdown.helper.forEach(outputModifiers, function (ext) { | ||
1007 | - text = showdown.subParser('runExtension')(ext, text, options, globals); | ||
1008 | - }); | ||
1009 | - return text; | ||
1010 | - }; | ||
1011 | - | ||
1012 | - /** | ||
1013 | - * Set an option of this Converter instance | ||
1014 | - * @param {string} key | ||
1015 | - * @param {*} value | ||
1016 | - */ | ||
1017 | - this.setOption = function (key, value) { | ||
1018 | - options[key] = value; | ||
1019 | - }; | ||
1020 | - | ||
1021 | - /** | ||
1022 | - * Get the option of this Converter instance | ||
1023 | - * @param {string} key | ||
1024 | - * @returns {*} | ||
1025 | - */ | ||
1026 | - this.getOption = function (key) { | ||
1027 | - return options[key]; | ||
1028 | - }; | ||
1029 | - | ||
1030 | - /** | ||
1031 | - * Get the options of this Converter instance | ||
1032 | - * @returns {{}} | ||
1033 | - */ | ||
1034 | - this.getOptions = function () { | ||
1035 | - return options; | ||
1036 | - }; | ||
1037 | - | ||
1038 | - /** | ||
1039 | - * Add extension to THIS converter | ||
1040 | - * @param {{}} extension | ||
1041 | - * @param {string} [name=null] | ||
1042 | - */ | ||
1043 | - this.addExtension = function (extension, name) { | ||
1044 | - name = name || null; | ||
1045 | - _parseExtension(extension, name); | ||
1046 | - }; | ||
1047 | - | ||
1048 | - /** | ||
1049 | - * Use a global registered extension with THIS converter | ||
1050 | - * @param {string} extensionName Name of the previously registered extension | ||
1051 | - */ | ||
1052 | - this.useExtension = function (extensionName) { | ||
1053 | - _parseExtension(extensionName); | ||
1054 | - }; | ||
1055 | - | ||
1056 | - /** | ||
1057 | - * Set the flavor THIS converter should use | ||
1058 | - * @param {string} name | ||
1059 | - */ | ||
1060 | - this.setFlavor = function (name) { | ||
1061 | - if (flavor.hasOwnProperty(name)) { | ||
1062 | - var preset = flavor[name]; | ||
1063 | - for (var option in preset) { | ||
1064 | - if (preset.hasOwnProperty(option)) { | ||
1065 | - options[option] = preset[option]; | ||
1066 | - } | ||
1067 | - } | ||
1068 | - } | ||
1069 | - }; | ||
1070 | - | ||
1071 | - /** | ||
1072 | - * Remove an extension from THIS converter. | ||
1073 | - * Note: This is a costly operation. It's better to initialize a new converter | ||
1074 | - * and specify the extensions you wish to use | ||
1075 | - * @param {Array} extension | ||
1076 | - */ | ||
1077 | - this.removeExtension = function (extension) { | ||
1078 | - if (!showdown.helper.isArray(extension)) { | ||
1079 | - extension = [extension]; | ||
1080 | - } | ||
1081 | - for (var a = 0; a < extension.length; ++a) { | ||
1082 | - var ext = extension[a]; | ||
1083 | - for (var i = 0; i < langExtensions.length; ++i) { | ||
1084 | - if (langExtensions[i] === ext) { | ||
1085 | - langExtensions[i].splice(i, 1); | ||
1086 | - } | ||
1087 | - } | ||
1088 | - for (var ii = 0; ii < outputModifiers.length; ++i) { | ||
1089 | - if (outputModifiers[ii] === ext) { | ||
1090 | - outputModifiers[ii].splice(i, 1); | ||
1091 | - } | ||
1092 | - } | ||
1093 | - } | ||
1094 | - }; | ||
1095 | - | ||
1096 | - /** | ||
1097 | - * Get all extension of THIS converter | ||
1098 | - * @returns {{language: Array, output: Array}} | ||
1099 | - */ | ||
1100 | - this.getAllExtensions = function () { | ||
1101 | - return { | ||
1102 | - language: langExtensions, | ||
1103 | - output: outputModifiers | ||
1104 | - }; | ||
1105 | - }; | ||
1106 | -}; | ||
1107 | - | ||
1108 | -/** | ||
1109 | - * Turn Markdown link shortcuts into XHTML <a> tags. | ||
1110 | - */ | ||
1111 | -showdown.subParser('anchors', function (text, options, globals) { | ||
1112 | - 'use strict'; | ||
1113 | - | ||
1114 | - text = globals.converter._dispatch('anchors.before', text, options, globals); | ||
1115 | - | ||
1116 | - var writeAnchorTag = function (wholeMatch, m1, m2, m3, m4, m5, m6, m7) { | ||
1117 | - if (showdown.helper.isUndefined(m7)) { | ||
1118 | - m7 = ''; | ||
1119 | - } | ||
1120 | - wholeMatch = m1; | ||
1121 | - var linkText = m2, | ||
1122 | - linkId = m3.toLowerCase(), | ||
1123 | - url = m4, | ||
1124 | - title = m7; | ||
1125 | - | ||
1126 | - if (!url) { | ||
1127 | - if (!linkId) { | ||
1128 | - // lower-case and turn embedded newlines into spaces | ||
1129 | - linkId = linkText.toLowerCase().replace(/ ?\n/g, ' '); | ||
1130 | - } | ||
1131 | - url = '#' + linkId; | ||
1132 | - | ||
1133 | - if (!showdown.helper.isUndefined(globals.gUrls[linkId])) { | ||
1134 | - url = globals.gUrls[linkId]; | ||
1135 | - if (!showdown.helper.isUndefined(globals.gTitles[linkId])) { | ||
1136 | - title = globals.gTitles[linkId]; | ||
1137 | - } | ||
1138 | - } else { | ||
1139 | - if (wholeMatch.search(/\(\s*\)$/m) > -1) { | ||
1140 | - // Special case for explicit empty url | ||
1141 | - url = ''; | ||
1142 | - } else { | ||
1143 | - return wholeMatch; | ||
1144 | - } | ||
1145 | - } | ||
1146 | - } | ||
1147 | - | ||
1148 | - url = showdown.helper.escapeCharacters(url, '*_', false); | ||
1149 | - var result = '<a href="' + url + '"'; | ||
1150 | - | ||
1151 | - if (title !== '' && title !== null) { | ||
1152 | - title = title.replace(/"/g, '"'); | ||
1153 | - title = showdown.helper.escapeCharacters(title, '*_', false); | ||
1154 | - result += ' title="' + title + '"'; | ||
1155 | - } | ||
1156 | - | ||
1157 | - result += '>' + linkText + '</a>'; | ||
1158 | - | ||
1159 | - return result; | ||
1160 | - }; | ||
1161 | - | ||
1162 | - // First, handle reference-style links: [link text] [id] | ||
1163 | - /* | ||
1164 | - text = text.replace(/ | ||
1165 | - ( // wrap whole match in $1 | ||
1166 | - \[ | ||
1167 | - ( | ||
1168 | - (?: | ||
1169 | - \[[^\]]*\] // allow brackets nested one level | ||
1170 | - | | ||
1171 | - [^\[] // or anything else | ||
1172 | - )* | ||
1173 | - ) | ||
1174 | - \] | ||
1175 | - | ||
1176 | - [ ]? // one optional space | ||
1177 | - (?:\n[ ]*)? // one optional newline followed by spaces | ||
1178 | - | ||
1179 | - \[ | ||
1180 | - (.*?) // id = $3 | ||
1181 | - \] | ||
1182 | - )()()()() // pad remaining backreferences | ||
1183 | - /g,_DoAnchors_callback); | ||
1184 | - */ | ||
1185 | - text = text.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)][ ]?(?:\n[ ]*)?\[(.*?)])()()()()/g, writeAnchorTag); | ||
1186 | - | ||
1187 | - // | ||
1188 | - // Next, inline-style links: [link text](url "optional title") | ||
1189 | - // | ||
1190 | - | ||
1191 | - /* | ||
1192 | - text = text.replace(/ | ||
1193 | - ( // wrap whole match in $1 | ||
1194 | - \[ | ||
1195 | - ( | ||
1196 | - (?: | ||
1197 | - \[[^\]]*\] // allow brackets nested one level | ||
1198 | - | | ||
1199 | - [^\[\]] // or anything else | ||
1200 | - ) | ||
1201 | - ) | ||
1202 | - \] | ||
1203 | - \( // literal paren | ||
1204 | - [ \t]* | ||
1205 | - () // no id, so leave $3 empty | ||
1206 | - <?(.*?)>? // href = $4 | ||
1207 | - [ \t]* | ||
1208 | - ( // $5 | ||
1209 | - (['"]) // quote char = $6 | ||
1210 | - (.*?) // Title = $7 | ||
1211 | - \6 // matching quote | ||
1212 | - [ \t]* // ignore any spaces/tabs between closing quote and ) | ||
1213 | - )? // title is optional | ||
1214 | - \) | ||
1215 | - ) | ||
1216 | - /g,writeAnchorTag); | ||
1217 | - */ | ||
1218 | - text = text.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)]\([ \t]*()<?(.*?(?:\(.*?\).*?)?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, | ||
1219 | - writeAnchorTag); | ||
1220 | - | ||
1221 | - // | ||
1222 | - // Last, handle reference-style shortcuts: [link text] | ||
1223 | - // These must come last in case you've also got [link test][1] | ||
1224 | - // or [link test](/foo) | ||
1225 | - // | ||
1226 | - | ||
1227 | - /* | ||
1228 | - text = text.replace(/ | ||
1229 | - ( // wrap whole match in $1 | ||
1230 | - \[ | ||
1231 | - ([^\[\]]+) // link text = $2; can't contain '[' or ']' | ||
1232 | - \] | ||
1233 | - )()()()()() // pad rest of backreferences | ||
1234 | - /g, writeAnchorTag); | ||
1235 | - */ | ||
1236 | - text = text.replace(/(\[([^\[\]]+)])()()()()()/g, writeAnchorTag); | ||
1237 | - | ||
1238 | - text = globals.converter._dispatch('anchors.after', text, options, globals); | ||
1239 | - return text; | ||
1240 | -}); | ||
1241 | - | ||
1242 | -showdown.subParser('autoLinks', function (text, options, globals) { | ||
1243 | - 'use strict'; | ||
1244 | - | ||
1245 | - text = globals.converter._dispatch('autoLinks.before', text, options, globals); | ||
1246 | - | ||
1247 | - var simpleURLRegex = /\b(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+)(?=\s|$)(?!["<>])/gi, | ||
1248 | - delimUrlRegex = /<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)>/gi, | ||
1249 | - simpleMailRegex = /(?:^|[ \n\t])([A-Za-z0-9!#$%&'*+-/=?^_`\{|}~\.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?:$|[ \n\t])/gi, | ||
1250 | - delimMailRegex = /<(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi; | ||
1251 | - | ||
1252 | - text = text.replace(delimUrlRegex, replaceLink); | ||
1253 | - text = text.replace(delimMailRegex, replaceMail); | ||
1254 | - // simpleURLRegex = /\b(((https?|ftp|dict):\/\/|www\.)[-.+~:?#@!$&'()*,;=[\]\w]+)\b/gi, | ||
1255 | - // Email addresses: <address@domain.foo> | ||
1256 | - | ||
1257 | - if (options.simplifiedAutoLink) { | ||
1258 | - text = text.replace(simpleURLRegex, replaceLink); | ||
1259 | - text = text.replace(simpleMailRegex, replaceMail); | ||
1260 | - } | ||
1261 | - | ||
1262 | - function replaceLink(wm, link) { | ||
1263 | - var lnkTxt = link; | ||
1264 | - if (/^www\./i.test(link)) { | ||
1265 | - link = link.replace(/^www\./i, 'http://www.'); | ||
1266 | - } | ||
1267 | - return '<a href="' + link + '">' + lnkTxt + '</a>'; | ||
1268 | - } | ||
1269 | - | ||
1270 | - function replaceMail(wholeMatch, m1) { | ||
1271 | - var unescapedStr = showdown.subParser('unescapeSpecialChars')(m1); | ||
1272 | - return showdown.subParser('encodeEmailAddress')(unescapedStr); | ||
1273 | - } | ||
1274 | - | ||
1275 | - text = globals.converter._dispatch('autoLinks.after', text, options, globals); | ||
1276 | - | ||
1277 | - return text; | ||
1278 | -}); | ||
1279 | - | ||
1280 | -/** | ||
1281 | - * These are all the transformations that form block-level | ||
1282 | - * tags like paragraphs, headers, and list items. | ||
1283 | - */ | ||
1284 | -showdown.subParser('blockGamut', function (text, options, globals) { | ||
1285 | - 'use strict'; | ||
1286 | - | ||
1287 | - text = globals.converter._dispatch('blockGamut.before', text, options, globals); | ||
1288 | - | ||
1289 | - // we parse blockquotes first so that we can have headings and hrs | ||
1290 | - // inside blockquotes | ||
1291 | - text = showdown.subParser('blockQuotes')(text, options, globals); | ||
1292 | - text = showdown.subParser('headers')(text, options, globals); | ||
1293 | - | ||
1294 | - // Do Horizontal Rules: | ||
1295 | - var key = showdown.subParser('hashBlock')('<hr />', options, globals); | ||
1296 | - text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm, key); | ||
1297 | - text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm, key); | ||
1298 | - text = text.replace(/^[ ]{0,2}([ ]?_[ ]?){3,}[ \t]*$/gm, key); | ||
1299 | - | ||
1300 | - text = showdown.subParser('lists')(text, options, globals); | ||
1301 | - text = showdown.subParser('codeBlocks')(text, options, globals); | ||
1302 | - text = showdown.subParser('tables')(text, options, globals); | ||
1303 | - | ||
1304 | - // We already ran _HashHTMLBlocks() before, in Markdown(), but that | ||
1305 | - // was to escape raw HTML in the original Markdown source. This time, | ||
1306 | - // we're escaping the markup we've just created, so that we don't wrap | ||
1307 | - // <p> tags around block-level tags. | ||
1308 | - text = showdown.subParser('hashHTMLBlocks')(text, options, globals); | ||
1309 | - text = showdown.subParser('paragraphs')(text, options, globals); | ||
1310 | - | ||
1311 | - text = globals.converter._dispatch('blockGamut.after', text, options, globals); | ||
1312 | - | ||
1313 | - return text; | ||
1314 | -}); | ||
1315 | - | ||
1316 | -showdown.subParser('blockQuotes', function (text, options, globals) { | ||
1317 | - 'use strict'; | ||
1318 | - | ||
1319 | - text = globals.converter._dispatch('blockQuotes.before', text, options, globals); | ||
1320 | - /* | ||
1321 | - text = text.replace(/ | ||
1322 | - ( // Wrap whole match in $1 | ||
1323 | - ( | ||
1324 | - ^[ \t]*>[ \t]? // '>' at the start of a line | ||
1325 | - .+\n // rest of the first line | ||
1326 | - (.+\n)* // subsequent consecutive lines | ||
1327 | - \n* // blanks | ||
1328 | - )+ | ||
1329 | - ) | ||
1330 | - /gm, function(){...}); | ||
1331 | - */ | ||
1332 | - | ||
1333 | - text = text.replace(/((^[ \t]{0,3}>[ \t]?.+\n(.+\n)*\n*)+)/gm, function (wholeMatch, m1) { | ||
1334 | - var bq = m1; | ||
1335 | - | ||
1336 | - // attacklab: hack around Konqueror 3.5.4 bug: | ||
1337 | - // "----------bug".replace(/^-/g,"") == "bug" | ||
1338 | - bq = bq.replace(/^[ \t]*>[ \t]?/gm, '~0'); // trim one level of quoting | ||
1339 | - | ||
1340 | - // attacklab: clean up hack | ||
1341 | - bq = bq.replace(/~0/g, ''); | ||
1342 | - | ||
1343 | - bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines | ||
1344 | - bq = showdown.subParser('githubCodeBlocks')(bq, options, globals); | ||
1345 | - bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse | ||
1346 | - | ||
1347 | - bq = bq.replace(/(^|\n)/g, '$1 '); | ||
1348 | - // These leading spaces screw with <pre> content, so we need to fix that: | ||
1349 | - bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) { | ||
1350 | - var pre = m1; | ||
1351 | - // attacklab: hack around Konqueror 3.5.4 bug: | ||
1352 | - pre = pre.replace(/^ /mg, '~0'); | ||
1353 | - pre = pre.replace(/~0/g, ''); | ||
1354 | - return pre; | ||
1355 | - }); | ||
1356 | - | ||
1357 | - return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals); | ||
1358 | - }); | ||
1359 | - | ||
1360 | - text = globals.converter._dispatch('blockQuotes.after', text, options, globals); | ||
1361 | - return text; | ||
1362 | -}); | ||
1363 | - | ||
1364 | -/** | ||
1365 | - * Process Markdown `<pre><code>` blocks. | ||
1366 | - */ | ||
1367 | -showdown.subParser('codeBlocks', function (text, options, globals) { | ||
1368 | - 'use strict'; | ||
1369 | - | ||
1370 | - text = globals.converter._dispatch('codeBlocks.before', text, options, globals); | ||
1371 | - /* | ||
1372 | - text = text.replace(text, | ||
1373 | - /(?:\n\n|^) | ||
1374 | - ( // $1 = the code block -- one or more lines, starting with a space/tab | ||
1375 | - (?: | ||
1376 | - (?:[ ]{4}|\t) // Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width | ||
1377 | - .*\n+ | ||
1378 | - )+ | ||
1379 | - ) | ||
1380 | - (\n*[ ]{0,3}[^ \t\n]|(?=~0)) // attacklab: g_tab_width | ||
1381 | - /g,function(){...}); | ||
1382 | - */ | ||
1383 | - | ||
1384 | - // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug | ||
1385 | - text += '~0'; | ||
1386 | - | ||
1387 | - var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g; | ||
1388 | - text = text.replace(pattern, function (wholeMatch, m1, m2) { | ||
1389 | - var codeblock = m1, | ||
1390 | - nextChar = m2, | ||
1391 | - end = '\n'; | ||
1392 | - | ||
1393 | - codeblock = showdown.subParser('outdent')(codeblock); | ||
1394 | - codeblock = showdown.subParser('encodeCode')(codeblock); | ||
1395 | - codeblock = showdown.subParser('detab')(codeblock); | ||
1396 | - codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines | ||
1397 | - codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines | ||
1398 | - | ||
1399 | - if (options.omitExtraWLInCodeBlocks) { | ||
1400 | - end = ''; | ||
1401 | - } | ||
1402 | - | ||
1403 | - codeblock = '<pre><code>' + codeblock + end + '</code></pre>'; | ||
1404 | - | ||
1405 | - return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar; | ||
1406 | - }); | ||
1407 | - | ||
1408 | - // attacklab: strip sentinel | ||
1409 | - text = text.replace(/~0/, ''); | ||
1410 | - | ||
1411 | - text = globals.converter._dispatch('codeBlocks.after', text, options, globals); | ||
1412 | - return text; | ||
1413 | -}); | ||
1414 | - | ||
1415 | -/** | ||
1416 | - * | ||
1417 | - * * Backtick quotes are used for <code></code> spans. | ||
1418 | - * | ||
1419 | - * * You can use multiple backticks as the delimiters if you want to | ||
1420 | - * include literal backticks in the code span. So, this input: | ||
1421 | - * | ||
1422 | - * Just type ``foo `bar` baz`` at the prompt. | ||
1423 | - * | ||
1424 | - * Will translate to: | ||
1425 | - * | ||
1426 | - * <p>Just type <code>foo `bar` baz</code> at the prompt.</p> | ||
1427 | - * | ||
1428 | - * There's no arbitrary limit to the number of backticks you | ||
1429 | - * can use as delimters. If you need three consecutive backticks | ||
1430 | - * in your code, use four for delimiters, etc. | ||
1431 | - * | ||
1432 | - * * You can use spaces to get literal backticks at the edges: | ||
1433 | - * | ||
1434 | - * ... type `` `bar` `` ... | ||
1435 | - * | ||
1436 | - * Turns to: | ||
1437 | - * | ||
1438 | - * ... type <code>`bar`</code> ... | ||
1439 | - */ | ||
1440 | -showdown.subParser('codeSpans', function (text, options, globals) { | ||
1441 | - 'use strict'; | ||
1442 | - | ||
1443 | - text = globals.converter._dispatch('codeSpans.before', text, options, globals); | ||
1444 | - | ||
1445 | - /* | ||
1446 | - text = text.replace(/ | ||
1447 | - (^|[^\\]) // Character before opening ` can't be a backslash | ||
1448 | - (`+) // $2 = Opening run of ` | ||
1449 | - ( // $3 = The code block | ||
1450 | - [^\r]*? | ||
1451 | - [^`] // attacklab: work around lack of lookbehind | ||
1452 | - ) | ||
1453 | - \2 // Matching closer | ||
1454 | - (?!`) | ||
1455 | - /gm, function(){...}); | ||
1456 | - */ | ||
1457 | - | ||
1458 | - if (typeof(text) === 'undefined') { | ||
1459 | - text = ''; | ||
1460 | - } | ||
1461 | - text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, | ||
1462 | - function (wholeMatch, m1, m2, m3) { | ||
1463 | - var c = m3; | ||
1464 | - c = c.replace(/^([ \t]*)/g, ''); // leading whitespace | ||
1465 | - c = c.replace(/[ \t]*$/g, ''); // trailing whitespace | ||
1466 | - c = showdown.subParser('encodeCode')(c); | ||
1467 | - return m1 + '<code>' + c + '</code>'; | ||
1468 | - } | ||
1469 | - ); | ||
1470 | - | ||
1471 | - text = globals.converter._dispatch('codeSpans.after', text, options, globals); | ||
1472 | - return text; | ||
1473 | -}); | ||
1474 | - | ||
1475 | -/** | ||
1476 | - * Convert all tabs to spaces | ||
1477 | - */ | ||
1478 | -showdown.subParser('detab', function (text) { | ||
1479 | - 'use strict'; | ||
1480 | - | ||
1481 | - // expand first n-1 tabs | ||
1482 | - text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width | ||
1483 | - | ||
1484 | - // replace the nth with two sentinels | ||
1485 | - text = text.replace(/\t/g, '~A~B'); | ||
1486 | - | ||
1487 | - // use the sentinel to anchor our regex so it doesn't explode | ||
1488 | - text = text.replace(/~B(.+?)~A/g, function (wholeMatch, m1) { | ||
1489 | - var leadingText = m1, | ||
1490 | - numSpaces = 4 - leadingText.length % 4; // g_tab_width | ||
1491 | - | ||
1492 | - // there *must* be a better way to do this: | ||
1493 | - for (var i = 0; i < numSpaces; i++) { | ||
1494 | - leadingText += ' '; | ||
1495 | - } | ||
1496 | - | ||
1497 | - return leadingText; | ||
1498 | - }); | ||
1499 | - | ||
1500 | - // clean up sentinels | ||
1501 | - text = text.replace(/~A/g, ' '); // g_tab_width | ||
1502 | - text = text.replace(/~B/g, ''); | ||
1503 | - | ||
1504 | - return text; | ||
1505 | - | ||
1506 | -}); | ||
1507 | - | ||
1508 | -/** | ||
1509 | - * Smart processing for ampersands and angle brackets that need to be encoded. | ||
1510 | - */ | ||
1511 | -showdown.subParser('encodeAmpsAndAngles', function (text) { | ||
1512 | - 'use strict'; | ||
1513 | - // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: | ||
1514 | - // http://bumppo.net/projects/amputator/ | ||
1515 | - text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&'); | ||
1516 | - | ||
1517 | - // Encode naked <'s | ||
1518 | - text = text.replace(/<(?![a-z\/?\$!])/gi, '<'); | ||
1519 | - | ||
1520 | - return text; | ||
1521 | -}); | ||
1522 | - | ||
1523 | -/** | ||
1524 | - * Returns the string, with after processing the following backslash escape sequences. | ||
1525 | - * | ||
1526 | - * attacklab: The polite way to do this is with the new escapeCharacters() function: | ||
1527 | - * | ||
1528 | - * text = escapeCharacters(text,"\\",true); | ||
1529 | - * text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); | ||
1530 | - * | ||
1531 | - * ...but we're sidestepping its use of the (slow) RegExp constructor | ||
1532 | - * as an optimization for Firefox. This function gets called a LOT. | ||
1533 | - */ | ||
1534 | -showdown.subParser('encodeBackslashEscapes', function (text) { | ||
1535 | - 'use strict'; | ||
1536 | - text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback); | ||
1537 | - text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g, showdown.helper.escapeCharactersCallback); | ||
1538 | - return text; | ||
1539 | -}); | ||
1540 | - | ||
1541 | -/** | ||
1542 | - * Encode/escape certain characters inside Markdown code runs. | ||
1543 | - * The point is that in code, these characters are literals, | ||
1544 | - * and lose their special Markdown meanings. | ||
1545 | - */ | ||
1546 | -showdown.subParser('encodeCode', function (text) { | ||
1547 | - 'use strict'; | ||
1548 | - | ||
1549 | - // Encode all ampersands; HTML entities are not | ||
1550 | - // entities within a Markdown code span. | ||
1551 | - text = text.replace(/&/g, '&'); | ||
1552 | - | ||
1553 | - // Do the angle bracket song and dance: | ||
1554 | - text = text.replace(/</g, '<'); | ||
1555 | - text = text.replace(/>/g, '>'); | ||
1556 | - | ||
1557 | - // Now, escape characters that are magic in Markdown: | ||
1558 | - text = showdown.helper.escapeCharacters(text, '*_{}[]\\', false); | ||
1559 | - | ||
1560 | - // jj the line above breaks this: | ||
1561 | - //--- | ||
1562 | - //* Item | ||
1563 | - // 1. Subitem | ||
1564 | - // special char: * | ||
1565 | - // --- | ||
1566 | - | ||
1567 | - return text; | ||
1568 | -}); | ||
1569 | - | ||
1570 | -/** | ||
1571 | - * Input: an email address, e.g. "foo@example.com" | ||
1572 | - * | ||
1573 | - * Output: the email address as a mailto link, with each character | ||
1574 | - * of the address encoded as either a decimal or hex entity, in | ||
1575 | - * the hopes of foiling most address harvesting spam bots. E.g.: | ||
1576 | - * | ||
1577 | - * <a href="mailto:foo@e | ||
1578 | - * xample.com">foo | ||
1579 | - * @example.com</a> | ||
1580 | - * | ||
1581 | - * Based on a filter by Matthew Wickline, posted to the BBEdit-Talk | ||
1582 | - * mailing list: <http://tinyurl.com/yu7ue> | ||
1583 | - * | ||
1584 | - */ | ||
1585 | -showdown.subParser('encodeEmailAddress', function (addr) { | ||
1586 | - 'use strict'; | ||
1587 | - | ||
1588 | - var encode = [ | ||
1589 | - function (ch) { | ||
1590 | - return '&#' + ch.charCodeAt(0) + ';'; | ||
1591 | - }, | ||
1592 | - function (ch) { | ||
1593 | - return '&#x' + ch.charCodeAt(0).toString(16) + ';'; | ||
1594 | - }, | ||
1595 | - function (ch) { | ||
1596 | - return ch; | ||
1597 | - } | ||
1598 | - ]; | ||
1599 | - | ||
1600 | - addr = 'mailto:' + addr; | ||
1601 | - | ||
1602 | - addr = addr.replace(/./g, function (ch) { | ||
1603 | - if (ch === '@') { | ||
1604 | - // this *must* be encoded. I insist. | ||
1605 | - ch = encode[Math.floor(Math.random() * 2)](ch); | ||
1606 | - } else if (ch !== ':') { | ||
1607 | - // leave ':' alone (to spot mailto: later) | ||
1608 | - var r = Math.random(); | ||
1609 | - // roughly 10% raw, 45% hex, 45% dec | ||
1610 | - ch = ( | ||
1611 | - r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch) | ||
1612 | - ); | ||
1613 | - } | ||
1614 | - return ch; | ||
1615 | - }); | ||
1616 | - | ||
1617 | - addr = '<a href="' + addr + '">' + addr + '</a>'; | ||
1618 | - addr = addr.replace(/">.+:/g, '">'); // strip the mailto: from the visible part | ||
1619 | - | ||
1620 | - return addr; | ||
1621 | -}); | ||
1622 | - | ||
1623 | -/** | ||
1624 | - * Within tags -- meaning between < and > -- encode [\ ` * _] so they | ||
1625 | - * don't conflict with their use in Markdown for code, italics and strong. | ||
1626 | - */ | ||
1627 | -showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text) { | ||
1628 | - 'use strict'; | ||
1629 | - | ||
1630 | - // Build a regex to find HTML tags and comments. See Friedl's | ||
1631 | - // "Mastering Regular Expressions", 2nd Ed., pp. 200-201. | ||
1632 | - var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi; | ||
1633 | - | ||
1634 | - text = text.replace(regex, function (wholeMatch) { | ||
1635 | - var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g, '$1`'); | ||
1636 | - tag = showdown.helper.escapeCharacters(tag, '\\`*_', false); | ||
1637 | - return tag; | ||
1638 | - }); | ||
1639 | - | ||
1640 | - return text; | ||
1641 | -}); | ||
1642 | - | ||
1643 | -/** | ||
1644 | - * Handle github codeblocks prior to running HashHTML so that | ||
1645 | - * HTML contained within the codeblock gets escaped properly | ||
1646 | - * Example: | ||
1647 | - * ```ruby | ||
1648 | - * def hello_world(x) | ||
1649 | - * puts "Hello, #{x}" | ||
1650 | - * end | ||
1651 | - * ``` | ||
1652 | - */ | ||
1653 | -showdown.subParser('githubCodeBlocks', function (text, options, globals) { | ||
1654 | - 'use strict'; | ||
1655 | - | ||
1656 | - // early exit if option is not enabled | ||
1657 | - if (!options.ghCodeBlocks) { | ||
1658 | - return text; | ||
1659 | - } | ||
1660 | - | ||
1661 | - text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals); | ||
1662 | - | ||
1663 | - text += '~0'; | ||
1664 | - | ||
1665 | - text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g, function (wholeMatch, language, codeblock) { | ||
1666 | - var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n'; | ||
1667 | - | ||
1668 | - // First parse the github code block | ||
1669 | - codeblock = showdown.subParser('encodeCode')(codeblock); | ||
1670 | - codeblock = showdown.subParser('detab')(codeblock); | ||
1671 | - codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines | ||
1672 | - codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace | ||
1673 | - | ||
1674 | - codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>'; | ||
1675 | - | ||
1676 | - codeblock = showdown.subParser('hashBlock')(codeblock, options, globals); | ||
1677 | - | ||
1678 | - // Since GHCodeblocks can be false positives, we need to | ||
1679 | - // store the primitive text and the parsed text in a global var, | ||
1680 | - // and then return a token | ||
1681 | - return '\n\n~G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; | ||
1682 | - }); | ||
1683 | - | ||
1684 | - // attacklab: strip sentinel | ||
1685 | - text = text.replace(/~0/, ''); | ||
1686 | - | ||
1687 | - return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals); | ||
1688 | -}); | ||
1689 | - | ||
1690 | -showdown.subParser('hashBlock', function (text, options, globals) { | ||
1691 | - 'use strict'; | ||
1692 | - text = text.replace(/(^\n+|\n+$)/g, ''); | ||
1693 | - return '\n\n~K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n'; | ||
1694 | -}); | ||
1695 | - | ||
1696 | -showdown.subParser('hashElement', function (text, options, globals) { | ||
1697 | - 'use strict'; | ||
1698 | - | ||
1699 | - return function (wholeMatch, m1) { | ||
1700 | - var blockText = m1; | ||
1701 | - | ||
1702 | - // Undo double lines | ||
1703 | - blockText = blockText.replace(/\n\n/g, '\n'); | ||
1704 | - blockText = blockText.replace(/^\n/, ''); | ||
1705 | - | ||
1706 | - // strip trailing blank lines | ||
1707 | - blockText = blockText.replace(/\n+$/g, ''); | ||
1708 | - | ||
1709 | - // Replace the element text with a marker ("~KxK" where x is its key) | ||
1710 | - blockText = '\n\n~K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n'; | ||
1711 | - | ||
1712 | - return blockText; | ||
1713 | - }; | ||
1714 | -}); | ||
1715 | - | ||
1716 | -showdown.subParser('hashHTMLBlocks', function (text, options, globals) { | ||
1717 | - 'use strict'; | ||
1718 | - | ||
1719 | - var blockTags = [ | ||
1720 | - 'pre', | ||
1721 | - 'div', | ||
1722 | - 'h1', | ||
1723 | - 'h2', | ||
1724 | - 'h3', | ||
1725 | - 'h4', | ||
1726 | - 'h5', | ||
1727 | - 'h6', | ||
1728 | - 'blockquote', | ||
1729 | - 'table', | ||
1730 | - 'dl', | ||
1731 | - 'ol', | ||
1732 | - 'ul', | ||
1733 | - 'script', | ||
1734 | - 'noscript', | ||
1735 | - 'form', | ||
1736 | - 'fieldset', | ||
1737 | - 'iframe', | ||
1738 | - 'math', | ||
1739 | - 'style', | ||
1740 | - 'section', | ||
1741 | - 'header', | ||
1742 | - 'footer', | ||
1743 | - 'nav', | ||
1744 | - 'article', | ||
1745 | - 'aside', | ||
1746 | - 'address', | ||
1747 | - 'audio', | ||
1748 | - 'canvas', | ||
1749 | - 'figure', | ||
1750 | - 'hgroup', | ||
1751 | - 'output', | ||
1752 | - 'video', | ||
1753 | - 'p' | ||
1754 | - ], | ||
1755 | - repFunc = function (wholeMatch, match, left, right) { | ||
1756 | - var txt = wholeMatch; | ||
1757 | - // check if this html element is marked as markdown | ||
1758 | - // if so, it's contents should be parsed as markdown | ||
1759 | - if (left.search(/\bmarkdown\b/) !== -1) { | ||
1760 | - txt = left + globals.converter.makeHtml(match) + right; | ||
1761 | - } | ||
1762 | - return '\n\n~K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; | ||
1763 | - }; | ||
1764 | - | ||
1765 | - for (var i = 0; i < blockTags.length; ++i) { | ||
1766 | - text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^(?: |\\t){0,3}<' + blockTags[i] + '\\b[^>]*>', '</' + blockTags[i] + '>', 'gim'); | ||
1767 | - } | ||
1768 | - | ||
1769 | - // HR SPECIAL CASE | ||
1770 | - text = text.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, | ||
1771 | - showdown.subParser('hashElement')(text, options, globals)); | ||
1772 | - | ||
1773 | - // Special case for standalone HTML comments: | ||
1774 | - text = text.replace(/(<!--[\s\S]*?-->)/g, | ||
1775 | - showdown.subParser('hashElement')(text, options, globals)); | ||
1776 | - | ||
1777 | - // PHP and ASP-style processor instructions (<?...?> and <%...%>) | ||
1778 | - text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, | ||
1779 | - showdown.subParser('hashElement')(text, options, globals)); | ||
1780 | - return text; | ||
1781 | -}); | ||
1782 | - | ||
1783 | -/** | ||
1784 | - * Hash span elements that should not be parsed as markdown | ||
1785 | - */ | ||
1786 | -showdown.subParser('hashHTMLSpans', function (text, config, globals) { | ||
1787 | - 'use strict'; | ||
1788 | - | ||
1789 | - var matches = showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi'); | ||
1790 | - | ||
1791 | - for (var i = 0; i < matches.length; ++i) { | ||
1792 | - text = text.replace(matches[i][0], '~L' + (globals.gHtmlSpans.push(matches[i][0]) - 1) + 'L'); | ||
1793 | - } | ||
1794 | - return text; | ||
1795 | -}); | ||
1796 | - | ||
1797 | -/** | ||
1798 | - * Unhash HTML spans | ||
1799 | - */ | ||
1800 | -showdown.subParser('unhashHTMLSpans', function (text, config, globals) { | ||
1801 | - 'use strict'; | ||
1802 | - | ||
1803 | - for (var i = 0; i < globals.gHtmlSpans.length; ++i) { | ||
1804 | - text = text.replace('~L' + i + 'L', globals.gHtmlSpans[i]); | ||
1805 | - } | ||
1806 | - | ||
1807 | - return text; | ||
1808 | -}); | ||
1809 | - | ||
1810 | -/** | ||
1811 | - * Hash span elements that should not be parsed as markdown | ||
1812 | - */ | ||
1813 | -showdown.subParser('hashPreCodeTags', function (text, config, globals) { | ||
1814 | - 'use strict'; | ||
1815 | - | ||
1816 | - var repFunc = function (wholeMatch, match, left, right) { | ||
1817 | - // encode html entities | ||
1818 | - var codeblock = left + showdown.subParser('encodeCode')(match) + right; | ||
1819 | - return '\n\n~G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; | ||
1820 | - }; | ||
1821 | - | ||
1822 | - text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^(?: |\\t){0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^(?: |\\t){0,3}</code>\\s*</pre>', 'gim'); | ||
1823 | - return text; | ||
1824 | -}); | ||
1825 | - | ||
1826 | -showdown.subParser('headers', function (text, options, globals) { | ||
1827 | - 'use strict'; | ||
1828 | - | ||
1829 | - text = globals.converter._dispatch('headers.before', text, options, globals); | ||
1830 | - | ||
1831 | - var prefixHeader = options.prefixHeaderId, | ||
1832 | - headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart), | ||
1833 | - | ||
1834 | - // Set text-style headers: | ||
1835 | - // Header 1 | ||
1836 | - // ======== | ||
1837 | - // | ||
1838 | - // Header 2 | ||
1839 | - // -------- | ||
1840 | - // | ||
1841 | - setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm, | ||
1842 | - setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm; | ||
1843 | - | ||
1844 | - text = text.replace(setextRegexH1, function (wholeMatch, m1) { | ||
1845 | - | ||
1846 | - var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), | ||
1847 | - hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', | ||
1848 | - hLevel = headerLevelStart, | ||
1849 | - hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; | ||
1850 | - return showdown.subParser('hashBlock')(hashBlock, options, globals); | ||
1851 | - }); | ||
1852 | - | ||
1853 | - text = text.replace(setextRegexH2, function (matchFound, m1) { | ||
1854 | - var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), | ||
1855 | - hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', | ||
1856 | - hLevel = headerLevelStart + 1, | ||
1857 | - hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; | ||
1858 | - return showdown.subParser('hashBlock')(hashBlock, options, globals); | ||
1859 | - }); | ||
1860 | - | ||
1861 | - // atx-style headers: | ||
1862 | - // # Header 1 | ||
1863 | - // ## Header 2 | ||
1864 | - // ## Header 2 with closing hashes ## | ||
1865 | - // ... | ||
1866 | - // ###### Header 6 | ||
1867 | - // | ||
1868 | - text = text.replace(/^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm, function (wholeMatch, m1, m2) { | ||
1869 | - var span = showdown.subParser('spanGamut')(m2, options, globals), | ||
1870 | - hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"', | ||
1871 | - hLevel = headerLevelStart - 1 + m1.length, | ||
1872 | - header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>'; | ||
1873 | - | ||
1874 | - return showdown.subParser('hashBlock')(header, options, globals); | ||
1875 | - }); | ||
1876 | - | ||
1877 | - function headerId(m) { | ||
1878 | - var title, escapedId = m.replace(/[^\w]/g, '').toLowerCase(); | ||
1879 | - | ||
1880 | - if (globals.hashLinkCounts[escapedId]) { | ||
1881 | - title = escapedId + '-' + (globals.hashLinkCounts[escapedId]++); | ||
1882 | - } else { | ||
1883 | - title = escapedId; | ||
1884 | - globals.hashLinkCounts[escapedId] = 1; | ||
1885 | - } | ||
1886 | - | ||
1887 | - // Prefix id to prevent causing inadvertent pre-existing style matches. | ||
1888 | - if (prefixHeader === true) { | ||
1889 | - prefixHeader = 'section'; | ||
1890 | - } | ||
1891 | - | ||
1892 | - if (showdown.helper.isString(prefixHeader)) { | ||
1893 | - return prefixHeader + title; | ||
1894 | - } | ||
1895 | - return title; | ||
1896 | - } | ||
1897 | - | ||
1898 | - text = globals.converter._dispatch('headers.after', text, options, globals); | ||
1899 | - return text; | ||
1900 | -}); | ||
1901 | - | ||
1902 | -/** | ||
1903 | - * Turn Markdown image shortcuts into <img> tags. | ||
1904 | - */ | ||
1905 | -showdown.subParser('images', function (text, options, globals) { | ||
1906 | - 'use strict'; | ||
1907 | - | ||
1908 | - text = globals.converter._dispatch('images.before', text, options, globals); | ||
1909 | - | ||
1910 | - var inlineRegExp = /!\[(.*?)]\s?\([ \t]*()<?(\S+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(['"])(.*?)\6[ \t]*)?\)/g, | ||
1911 | - referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[(.*?)]()()()()()/g; | ||
1912 | - | ||
1913 | - function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) { | ||
1914 | - | ||
1915 | - var gUrls = globals.gUrls, | ||
1916 | - gTitles = globals.gTitles, | ||
1917 | - gDims = globals.gDimensions; | ||
1918 | - | ||
1919 | - linkId = linkId.toLowerCase(); | ||
1920 | - | ||
1921 | - if (!title) { | ||
1922 | - title = ''; | ||
1923 | - } | ||
1924 | - | ||
1925 | - if (url === '' || url === null) { | ||
1926 | - if (linkId === '' || linkId === null) { | ||
1927 | - // lower-case and turn embedded newlines into spaces | ||
1928 | - linkId = altText.toLowerCase().replace(/ ?\n/g, ' '); | ||
1929 | - } | ||
1930 | - url = '#' + linkId; | ||
1931 | - | ||
1932 | - if (!showdown.helper.isUndefined(gUrls[linkId])) { | ||
1933 | - url = gUrls[linkId]; | ||
1934 | - if (!showdown.helper.isUndefined(gTitles[linkId])) { | ||
1935 | - title = gTitles[linkId]; | ||
1936 | - } | ||
1937 | - if (!showdown.helper.isUndefined(gDims[linkId])) { | ||
1938 | - width = gDims[linkId].width; | ||
1939 | - height = gDims[linkId].height; | ||
1940 | - } | ||
1941 | - } else { | ||
1942 | - return wholeMatch; | ||
1943 | - } | ||
1944 | - } | ||
1945 | - | ||
1946 | - altText = altText.replace(/"/g, '"'); | ||
1947 | - altText = showdown.helper.escapeCharacters(altText, '*_', false); | ||
1948 | - url = showdown.helper.escapeCharacters(url, '*_', false); | ||
1949 | - var result = '<img src="' + url + '" alt="' + altText + '"'; | ||
1950 | - | ||
1951 | - if (title) { | ||
1952 | - title = title.replace(/"/g, '"'); | ||
1953 | - title = showdown.helper.escapeCharacters(title, '*_', false); | ||
1954 | - result += ' title="' + title + '"'; | ||
1955 | - } | ||
1956 | - | ||
1957 | - if (width && height) { | ||
1958 | - width = (width === '*') ? 'auto' : width; | ||
1959 | - height = (height === '*') ? 'auto' : height; | ||
1960 | - | ||
1961 | - result += ' width="' + width + '"'; | ||
1962 | - result += ' height="' + height + '"'; | ||
1963 | - } | ||
1964 | - | ||
1965 | - result += ' />'; | ||
1966 | - return result; | ||
1967 | - } | ||
1968 | - | ||
1969 | - // First, handle reference-style labeled images: ![alt text][id] | ||
1970 | - text = text.replace(referenceRegExp, writeImageTag); | ||
1971 | - | ||
1972 | - // Next, handle inline images: ![alt text](url =<width>x<height> "optional title") | ||
1973 | - text = text.replace(inlineRegExp, writeImageTag); | ||
1974 | - | ||
1975 | - text = globals.converter._dispatch('images.after', text, options, globals); | ||
1976 | - return text; | ||
1977 | -}); | ||
1978 | - | ||
1979 | -showdown.subParser('italicsAndBold', function (text, options, globals) { | ||
1980 | - 'use strict'; | ||
1981 | - | ||
1982 | - text = globals.converter._dispatch('italicsAndBold.before', text, options, globals); | ||
1983 | - | ||
1984 | - if (options.literalMidWordUnderscores) { | ||
1985 | - //underscores | ||
1986 | - // Since we are consuming a \s character, we need to add it | ||
1987 | - text = text.replace(/(^|\s|>|\b)__(?=\S)([\s\S]+?)__(?=\b|<|\s|$)/gm, '$1<strong>$2</strong>'); | ||
1988 | - text = text.replace(/(^|\s|>|\b)_(?=\S)([\s\S]+?)_(?=\b|<|\s|$)/gm, '$1<em>$2</em>'); | ||
1989 | - //asterisks | ||
1990 | - text = text.replace(/(\*\*)(?=\S)([^\r]*?\S[*]*)\1/g, '<strong>$2</strong>'); | ||
1991 | - text = text.replace(/(\*)(?=\S)([^\r]*?\S)\1/g, '<em>$2</em>'); | ||
1992 | - | ||
1993 | - } else { | ||
1994 | - // <strong> must go first: | ||
1995 | - text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g, '<strong>$2</strong>'); | ||
1996 | - text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g, '<em>$2</em>'); | ||
1997 | - } | ||
1998 | - | ||
1999 | - text = globals.converter._dispatch('italicsAndBold.after', text, options, globals); | ||
2000 | - return text; | ||
2001 | -}); | ||
2002 | - | ||
2003 | -/** | ||
2004 | - * Form HTML ordered (numbered) and unordered (bulleted) lists. | ||
2005 | - */ | ||
2006 | -showdown.subParser('lists', function (text, options, globals) { | ||
2007 | - 'use strict'; | ||
2008 | - | ||
2009 | - text = globals.converter._dispatch('lists.before', text, options, globals); | ||
2010 | - /** | ||
2011 | - * Process the contents of a single ordered or unordered list, splitting it | ||
2012 | - * into individual list items. | ||
2013 | - * @param {string} listStr | ||
2014 | - * @param {boolean} trimTrailing | ||
2015 | - * @returns {string} | ||
2016 | - */ | ||
2017 | - function processListItems (listStr, trimTrailing) { | ||
2018 | - // The $g_list_level global keeps track of when we're inside a list. | ||
2019 | - // Each time we enter a list, we increment it; when we leave a list, | ||
2020 | - // we decrement. If it's zero, we're not in a list anymore. | ||
2021 | - // | ||
2022 | - // We do this because when we're not inside a list, we want to treat | ||
2023 | - // something like this: | ||
2024 | - // | ||
2025 | - // I recommend upgrading to version | ||
2026 | - // 8. Oops, now this line is treated | ||
2027 | - // as a sub-list. | ||
2028 | - // | ||
2029 | - // As a single paragraph, despite the fact that the second line starts | ||
2030 | - // with a digit-period-space sequence. | ||
2031 | - // | ||
2032 | - // Whereas when we're inside a list (or sub-list), that line will be | ||
2033 | - // treated as the start of a sub-list. What a kludge, huh? This is | ||
2034 | - // an aspect of Markdown's syntax that's hard to parse perfectly | ||
2035 | - // without resorting to mind-reading. Perhaps the solution is to | ||
2036 | - // change the syntax rules such that sub-lists must start with a | ||
2037 | - // starting cardinal number; e.g. "1." or "a.". | ||
2038 | - globals.gListLevel++; | ||
2039 | - | ||
2040 | - // trim trailing blank lines: | ||
2041 | - listStr = listStr.replace(/\n{2,}$/, '\n'); | ||
2042 | - | ||
2043 | - // attacklab: add sentinel to emulate \z | ||
2044 | - listStr += '~0'; | ||
2045 | - | ||
2046 | - var rgx = /(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm, | ||
2047 | - isParagraphed = (/\n[ \t]*\n(?!~0)/.test(listStr)); | ||
2048 | - | ||
2049 | - listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) { | ||
2050 | - checked = (checked && checked.trim() !== ''); | ||
2051 | - var item = showdown.subParser('outdent')(m4, options, globals), | ||
2052 | - bulletStyle = ''; | ||
2053 | - | ||
2054 | - // Support for github tasklists | ||
2055 | - if (taskbtn && options.tasklists) { | ||
2056 | - bulletStyle = ' class="task-list-item" style="list-style-type: none;"'; | ||
2057 | - item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () { | ||
2058 | - var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"'; | ||
2059 | - if (checked) { | ||
2060 | - otp += ' checked'; | ||
2061 | - } | ||
2062 | - otp += '>'; | ||
2063 | - return otp; | ||
2064 | - }); | ||
2065 | - } | ||
2066 | - // m1 - Leading line or | ||
2067 | - // Has a double return (multi paragraph) or | ||
2068 | - // Has sublist | ||
2069 | - if (m1 || (item.search(/\n{2,}/) > -1)) { | ||
2070 | - item = showdown.subParser('githubCodeBlocks')(item, options, globals); | ||
2071 | - item = showdown.subParser('blockGamut')(item, options, globals); | ||
2072 | - } else { | ||
2073 | - // Recursion for sub-lists: | ||
2074 | - item = showdown.subParser('lists')(item, options, globals); | ||
2075 | - item = item.replace(/\n$/, ''); // chomp(item) | ||
2076 | - if (isParagraphed) { | ||
2077 | - item = showdown.subParser('paragraphs')(item, options, globals); | ||
2078 | - } else { | ||
2079 | - item = showdown.subParser('spanGamut')(item, options, globals); | ||
2080 | - } | ||
2081 | - } | ||
2082 | - item = '\n<li' + bulletStyle + '>' + item + '</li>\n'; | ||
2083 | - return item; | ||
2084 | - }); | ||
2085 | - | ||
2086 | - // attacklab: strip sentinel | ||
2087 | - listStr = listStr.replace(/~0/g, ''); | ||
2088 | - | ||
2089 | - globals.gListLevel--; | ||
2090 | - | ||
2091 | - if (trimTrailing) { | ||
2092 | - listStr = listStr.replace(/\s+$/, ''); | ||
2093 | - } | ||
2094 | - | ||
2095 | - return listStr; | ||
2096 | - } | ||
2097 | - | ||
2098 | - /** | ||
2099 | - * Check and parse consecutive lists (better fix for issue #142) | ||
2100 | - * @param {string} list | ||
2101 | - * @param {string} listType | ||
2102 | - * @param {boolean} trimTrailing | ||
2103 | - * @returns {string} | ||
2104 | - */ | ||
2105 | - function parseConsecutiveLists(list, listType, trimTrailing) { | ||
2106 | - // check if we caught 2 or more consecutive lists by mistake | ||
2107 | - // we use the counterRgx, meaning if listType is UL we look for UL and vice versa | ||
2108 | - var counterRxg = (listType === 'ul') ? /^ {0,2}\d+\.[ \t]/gm : /^ {0,2}[*+-][ \t]/gm, | ||
2109 | - subLists = [], | ||
2110 | - result = ''; | ||
2111 | - | ||
2112 | - if (list.search(counterRxg) !== -1) { | ||
2113 | - (function parseCL(txt) { | ||
2114 | - var pos = txt.search(counterRxg); | ||
2115 | - if (pos !== -1) { | ||
2116 | - // slice | ||
2117 | - result += '\n\n<' + listType + '>' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n\n'; | ||
2118 | - | ||
2119 | - // invert counterType and listType | ||
2120 | - listType = (listType === 'ul') ? 'ol' : 'ul'; | ||
2121 | - counterRxg = (listType === 'ul') ? /^ {0,2}\d+\.[ \t]/gm : /^ {0,2}[*+-][ \t]/gm; | ||
2122 | - | ||
2123 | - //recurse | ||
2124 | - parseCL(txt.slice(pos)); | ||
2125 | - } else { | ||
2126 | - result += '\n\n<' + listType + '>' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n\n'; | ||
2127 | - } | ||
2128 | - })(list); | ||
2129 | - for (var i = 0; i < subLists.length; ++i) { | ||
2130 | - | ||
2131 | - } | ||
2132 | - } else { | ||
2133 | - result = '\n\n<' + listType + '>' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n\n'; | ||
2134 | - } | ||
2135 | - | ||
2136 | - return result; | ||
2137 | - } | ||
2138 | - | ||
2139 | - // attacklab: add sentinel to hack around khtml/safari bug: | ||
2140 | - // http://bugs.webkit.org/show_bug.cgi?id=11231 | ||
2141 | - text += '~0'; | ||
2142 | - | ||
2143 | - // Re-usable pattern to match any entire ul or ol list: | ||
2144 | - var wholeList = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm; | ||
2145 | - | ||
2146 | - if (globals.gListLevel) { | ||
2147 | - text = text.replace(wholeList, function (wholeMatch, list, m2) { | ||
2148 | - var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; | ||
2149 | - return parseConsecutiveLists(list, listType, true); | ||
2150 | - }); | ||
2151 | - } else { | ||
2152 | - wholeList = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm; | ||
2153 | - //wholeList = /(\n\n|^\n?)( {0,3}([*+-]|\d+\.)[ \t]+[\s\S]+?)(?=(~0)|(\n\n(?!\t| {2,}| {0,3}([*+-]|\d+\.)[ \t])))/g; | ||
2154 | - text = text.replace(wholeList, function (wholeMatch, m1, list, m3) { | ||
2155 | - | ||
2156 | - var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; | ||
2157 | - return parseConsecutiveLists(list, listType); | ||
2158 | - }); | ||
2159 | - } | ||
2160 | - | ||
2161 | - // attacklab: strip sentinel | ||
2162 | - text = text.replace(/~0/, ''); | ||
2163 | - | ||
2164 | - text = globals.converter._dispatch('lists.after', text, options, globals); | ||
2165 | - return text; | ||
2166 | -}); | ||
2167 | - | ||
2168 | -/** | ||
2169 | - * Remove one level of line-leading tabs or spaces | ||
2170 | - */ | ||
2171 | -showdown.subParser('outdent', function (text) { | ||
2172 | - 'use strict'; | ||
2173 | - | ||
2174 | - // attacklab: hack around Konqueror 3.5.4 bug: | ||
2175 | - // "----------bug".replace(/^-/g,"") == "bug" | ||
2176 | - text = text.replace(/^(\t|[ ]{1,4})/gm, '~0'); // attacklab: g_tab_width | ||
2177 | - | ||
2178 | - // attacklab: clean up hack | ||
2179 | - text = text.replace(/~0/g, ''); | ||
2180 | - | ||
2181 | - return text; | ||
2182 | -}); | ||
2183 | - | ||
2184 | -/** | ||
2185 | - * | ||
2186 | - */ | ||
2187 | -showdown.subParser('paragraphs', function (text, options, globals) { | ||
2188 | - 'use strict'; | ||
2189 | - | ||
2190 | - text = globals.converter._dispatch('paragraphs.before', text, options, globals); | ||
2191 | - // Strip leading and trailing lines: | ||
2192 | - text = text.replace(/^\n+/g, ''); | ||
2193 | - text = text.replace(/\n+$/g, ''); | ||
2194 | - | ||
2195 | - var grafs = text.split(/\n{2,}/g), | ||
2196 | - grafsOut = [], | ||
2197 | - end = grafs.length; // Wrap <p> tags | ||
2198 | - | ||
2199 | - for (var i = 0; i < end; i++) { | ||
2200 | - var str = grafs[i]; | ||
2201 | - // if this is an HTML marker, copy it | ||
2202 | - if (str.search(/~(K|G)(\d+)\1/g) >= 0) { | ||
2203 | - grafsOut.push(str); | ||
2204 | - } else { | ||
2205 | - str = showdown.subParser('spanGamut')(str, options, globals); | ||
2206 | - str = str.replace(/^([ \t]*)/g, '<p>'); | ||
2207 | - str += '</p>'; | ||
2208 | - grafsOut.push(str); | ||
2209 | - } | ||
2210 | - } | ||
2211 | - | ||
2212 | - /** Unhashify HTML blocks */ | ||
2213 | - end = grafsOut.length; | ||
2214 | - for (i = 0; i < end; i++) { | ||
2215 | - var blockText = '', | ||
2216 | - grafsOutIt = grafsOut[i], | ||
2217 | - codeFlag = false; | ||
2218 | - // if this is a marker for an html block... | ||
2219 | - while (grafsOutIt.search(/~(K|G)(\d+)\1/) >= 0) { | ||
2220 | - var delim = RegExp.$1, | ||
2221 | - num = RegExp.$2; | ||
2222 | - | ||
2223 | - if (delim === 'K') { | ||
2224 | - blockText = globals.gHtmlBlocks[num]; | ||
2225 | - } else { | ||
2226 | - // we need to check if ghBlock is a false positive | ||
2227 | - if (codeFlag) { | ||
2228 | - // use encoded version of all text | ||
2229 | - blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text); | ||
2230 | - } else { | ||
2231 | - blockText = globals.ghCodeBlocks[num].codeblock; | ||
2232 | - } | ||
2233 | - } | ||
2234 | - blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs | ||
2235 | - | ||
2236 | - grafsOutIt = grafsOutIt.replace(/(\n\n)?~(K|G)\d+\2(\n\n)?/, blockText); | ||
2237 | - // Check if grafsOutIt is a pre->code | ||
2238 | - if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) { | ||
2239 | - codeFlag = true; | ||
2240 | - } | ||
2241 | - } | ||
2242 | - grafsOut[i] = grafsOutIt; | ||
2243 | - } | ||
2244 | - text = grafsOut.join('\n\n'); | ||
2245 | - // Strip leading and trailing lines: | ||
2246 | - text = text.replace(/^\n+/g, ''); | ||
2247 | - text = text.replace(/\n+$/g, ''); | ||
2248 | - return globals.converter._dispatch('paragraphs.after', text, options, globals); | ||
2249 | -}); | ||
2250 | - | ||
2251 | -/** | ||
2252 | - * Run extension | ||
2253 | - */ | ||
2254 | -showdown.subParser('runExtension', function (ext, text, options, globals) { | ||
2255 | - 'use strict'; | ||
2256 | - | ||
2257 | - if (ext.filter) { | ||
2258 | - text = ext.filter(text, globals.converter, options); | ||
2259 | - | ||
2260 | - } else if (ext.regex) { | ||
2261 | - // TODO remove this when old extension loading mechanism is deprecated | ||
2262 | - var re = ext.regex; | ||
2263 | - if (!re instanceof RegExp) { | ||
2264 | - re = new RegExp(re, 'g'); | ||
2265 | - } | ||
2266 | - text = text.replace(re, ext.replace); | ||
2267 | - } | ||
2268 | - | ||
2269 | - return text; | ||
2270 | -}); | ||
2271 | - | ||
2272 | -/** | ||
2273 | - * These are all the transformations that occur *within* block-level | ||
2274 | - * tags like paragraphs, headers, and list items. | ||
2275 | - */ | ||
2276 | -showdown.subParser('spanGamut', function (text, options, globals) { | ||
2277 | - 'use strict'; | ||
2278 | - | ||
2279 | - text = globals.converter._dispatch('spanGamut.before', text, options, globals); | ||
2280 | - text = showdown.subParser('codeSpans')(text, options, globals); | ||
2281 | - text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals); | ||
2282 | - text = showdown.subParser('encodeBackslashEscapes')(text, options, globals); | ||
2283 | - | ||
2284 | - // Process anchor and image tags. Images must come first, | ||
2285 | - // because ![foo][f] looks like an anchor. | ||
2286 | - text = showdown.subParser('images')(text, options, globals); | ||
2287 | - text = showdown.subParser('anchors')(text, options, globals); | ||
2288 | - | ||
2289 | - // Make links out of things like `<http://example.com/>` | ||
2290 | - // Must come after _DoAnchors(), because you can use < and > | ||
2291 | - // delimiters in inline links like [this](<url>). | ||
2292 | - text = showdown.subParser('autoLinks')(text, options, globals); | ||
2293 | - text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals); | ||
2294 | - text = showdown.subParser('italicsAndBold')(text, options, globals); | ||
2295 | - text = showdown.subParser('strikethrough')(text, options, globals); | ||
2296 | - | ||
2297 | - // Do hard breaks: | ||
2298 | - text = text.replace(/ +\n/g, ' <br />\n'); | ||
2299 | - | ||
2300 | - text = globals.converter._dispatch('spanGamut.after', text, options, globals); | ||
2301 | - return text; | ||
2302 | -}); | ||
2303 | - | ||
2304 | -showdown.subParser('strikethrough', function (text, options, globals) { | ||
2305 | - 'use strict'; | ||
2306 | - | ||
2307 | - if (options.strikethrough) { | ||
2308 | - text = globals.converter._dispatch('strikethrough.before', text, options, globals); | ||
2309 | - text = text.replace(/(?:~T){2}([\s\S]+?)(?:~T){2}/g, '<del>$1</del>'); | ||
2310 | - text = globals.converter._dispatch('strikethrough.after', text, options, globals); | ||
2311 | - } | ||
2312 | - | ||
2313 | - return text; | ||
2314 | -}); | ||
2315 | - | ||
2316 | -/** | ||
2317 | - * Strip any lines consisting only of spaces and tabs. | ||
2318 | - * This makes subsequent regexs easier to write, because we can | ||
2319 | - * match consecutive blank lines with /\n+/ instead of something | ||
2320 | - * contorted like /[ \t]*\n+/ | ||
2321 | - */ | ||
2322 | -showdown.subParser('stripBlankLines', function (text) { | ||
2323 | - 'use strict'; | ||
2324 | - return text.replace(/^[ \t]+$/mg, ''); | ||
2325 | -}); | ||
2326 | - | ||
2327 | -/** | ||
2328 | - * Strips link definitions from text, stores the URLs and titles in | ||
2329 | - * hash references. | ||
2330 | - * Link defs are in the form: ^[id]: url "optional title" | ||
2331 | - * | ||
2332 | - * ^[ ]{0,3}\[(.+)\]: // id = $1 attacklab: g_tab_width - 1 | ||
2333 | - * [ \t]* | ||
2334 | - * \n? // maybe *one* newline | ||
2335 | - * [ \t]* | ||
2336 | - * <?(\S+?)>? // url = $2 | ||
2337 | - * [ \t]* | ||
2338 | - * \n? // maybe one newline | ||
2339 | - * [ \t]* | ||
2340 | - * (?: | ||
2341 | - * (\n*) // any lines skipped = $3 attacklab: lookbehind removed | ||
2342 | - * ["(] | ||
2343 | - * (.+?) // title = $4 | ||
2344 | - * [")] | ||
2345 | - * [ \t]* | ||
2346 | - * )? // title is optional | ||
2347 | - * (?:\n+|$) | ||
2348 | - * /gm, | ||
2349 | - * function(){...}); | ||
2350 | - * | ||
2351 | - */ | ||
2352 | -showdown.subParser('stripLinkDefinitions', function (text, options, globals) { | ||
2353 | - 'use strict'; | ||
2354 | - | ||
2355 | - var regex = /^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?(\S+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=~0))/gm; | ||
2356 | - | ||
2357 | - // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug | ||
2358 | - text += '~0'; | ||
2359 | - | ||
2360 | - text = text.replace(regex, function (wholeMatch, linkId, url, width, height, blankLines, title) { | ||
2361 | - linkId = linkId.toLowerCase(); | ||
2362 | - globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url); // Link IDs are case-insensitive | ||
2363 | - | ||
2364 | - if (blankLines) { | ||
2365 | - // Oops, found blank lines, so it's not a title. | ||
2366 | - // Put back the parenthetical statement we stole. | ||
2367 | - return blankLines + title; | ||
2368 | - | ||
2369 | - } else { | ||
2370 | - if (title) { | ||
2371 | - globals.gTitles[linkId] = title.replace(/"|'/g, '"'); | ||
2372 | - } | ||
2373 | - if (options.parseImgDimensions && width && height) { | ||
2374 | - globals.gDimensions[linkId] = { | ||
2375 | - width: width, | ||
2376 | - height: height | ||
2377 | - }; | ||
2378 | - } | ||
2379 | - } | ||
2380 | - // Completely remove the definition from the text | ||
2381 | - return ''; | ||
2382 | - }); | ||
2383 | - | ||
2384 | - // attacklab: strip sentinel | ||
2385 | - text = text.replace(/~0/, ''); | ||
2386 | - | ||
2387 | - return text; | ||
2388 | -}); | ||
2389 | - | ||
2390 | -showdown.subParser('tables', function (text, options, globals) { | ||
2391 | - 'use strict'; | ||
2392 | - | ||
2393 | - if (!options.tables) { | ||
2394 | - return text; | ||
2395 | - } | ||
2396 | - | ||
2397 | - var tableRgx = /^[ \t]{0,3}\|?.+\|.+\n[ \t]{0,3}\|?[ \t]*:?[ \t]*(?:-|=){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:-|=){2,}[\s\S]+?(?:\n\n|~0)/gm; | ||
2398 | - | ||
2399 | - function parseStyles(sLine) { | ||
2400 | - if (/^:[ \t]*--*$/.test(sLine)) { | ||
2401 | - return ' style="text-align:left;"'; | ||
2402 | - } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) { | ||
2403 | - return ' style="text-align:right;"'; | ||
2404 | - } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) { | ||
2405 | - return ' style="text-align:center;"'; | ||
2406 | - } else { | ||
2407 | - return ''; | ||
2408 | - } | ||
2409 | - } | ||
2410 | - | ||
2411 | - function parseHeaders(header, style) { | ||
2412 | - var id = ''; | ||
2413 | - header = header.trim(); | ||
2414 | - if (options.tableHeaderId) { | ||
2415 | - id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"'; | ||
2416 | - } | ||
2417 | - header = showdown.subParser('spanGamut')(header, options, globals); | ||
2418 | - | ||
2419 | - return '<th' + id + style + '>' + header + '</th>\n'; | ||
2420 | - } | ||
2421 | - | ||
2422 | - function parseCells(cell, style) { | ||
2423 | - var subText = showdown.subParser('spanGamut')(cell, options, globals); | ||
2424 | - return '<td' + style + '>' + subText + '</td>\n'; | ||
2425 | - } | ||
2426 | - | ||
2427 | - function buildTable(headers, cells) { | ||
2428 | - var tb = '<table>\n<thead>\n<tr>\n', | ||
2429 | - tblLgn = headers.length; | ||
2430 | - | ||
2431 | - for (var i = 0; i < tblLgn; ++i) { | ||
2432 | - tb += headers[i]; | ||
2433 | - } | ||
2434 | - tb += '</tr>\n</thead>\n<tbody>\n'; | ||
2435 | - | ||
2436 | - for (i = 0; i < cells.length; ++i) { | ||
2437 | - tb += '<tr>\n'; | ||
2438 | - for (var ii = 0; ii < tblLgn; ++ii) { | ||
2439 | - tb += cells[i][ii]; | ||
2440 | - } | ||
2441 | - tb += '</tr>\n'; | ||
2442 | - } | ||
2443 | - tb += '</tbody>\n</table>\n'; | ||
2444 | - return tb; | ||
2445 | - } | ||
2446 | - | ||
2447 | - text = globals.converter._dispatch('tables.before', text, options, globals); | ||
2448 | - | ||
2449 | - text = text.replace(tableRgx, function (rawTable) { | ||
2450 | - | ||
2451 | - var i, tableLines = rawTable.split('\n'); | ||
2452 | - | ||
2453 | - // strip wrong first and last column if wrapped tables are used | ||
2454 | - for (i = 0; i < tableLines.length; ++i) { | ||
2455 | - if (/^[ \t]{0,3}\|/.test(tableLines[i])) { | ||
2456 | - tableLines[i] = tableLines[i].replace(/^[ \t]{0,3}\|/, ''); | ||
2457 | - } | ||
2458 | - if (/\|[ \t]*$/.test(tableLines[i])) { | ||
2459 | - tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, ''); | ||
2460 | - } | ||
2461 | - } | ||
2462 | - | ||
2463 | - var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}), | ||
2464 | - rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}), | ||
2465 | - rawCells = [], | ||
2466 | - headers = [], | ||
2467 | - styles = [], | ||
2468 | - cells = []; | ||
2469 | - | ||
2470 | - tableLines.shift(); | ||
2471 | - tableLines.shift(); | ||
2472 | - | ||
2473 | - for (i = 0; i < tableLines.length; ++i) { | ||
2474 | - if (tableLines[i].trim() === '') { | ||
2475 | - continue; | ||
2476 | - } | ||
2477 | - rawCells.push( | ||
2478 | - tableLines[i] | ||
2479 | - .split('|') | ||
2480 | - .map(function (s) { | ||
2481 | - return s.trim(); | ||
2482 | - }) | ||
2483 | - ); | ||
2484 | - } | ||
2485 | - | ||
2486 | - if (rawHeaders.length < rawStyles.length) { | ||
2487 | - return rawTable; | ||
2488 | - } | ||
2489 | - | ||
2490 | - for (i = 0; i < rawStyles.length; ++i) { | ||
2491 | - styles.push(parseStyles(rawStyles[i])); | ||
2492 | - } | ||
2493 | - | ||
2494 | - for (i = 0; i < rawHeaders.length; ++i) { | ||
2495 | - if (showdown.helper.isUndefined(styles[i])) { | ||
2496 | - styles[i] = ''; | ||
2497 | - } | ||
2498 | - headers.push(parseHeaders(rawHeaders[i], styles[i])); | ||
2499 | - } | ||
2500 | - | ||
2501 | - for (i = 0; i < rawCells.length; ++i) { | ||
2502 | - var row = []; | ||
2503 | - for (var ii = 0; ii < headers.length; ++ii) { | ||
2504 | - if (showdown.helper.isUndefined(rawCells[i][ii])) { | ||
2505 | - | ||
2506 | - } | ||
2507 | - row.push(parseCells(rawCells[i][ii], styles[ii])); | ||
2508 | - } | ||
2509 | - cells.push(row); | ||
2510 | - } | ||
2511 | - | ||
2512 | - return buildTable(headers, cells); | ||
2513 | - }); | ||
2514 | - | ||
2515 | - text = globals.converter._dispatch('tables.after', text, options, globals); | ||
2516 | - | ||
2517 | - return text; | ||
2518 | -}); | ||
2519 | - | ||
2520 | -/** | ||
2521 | - * Swap back in all the special characters we've hidden. | ||
2522 | - */ | ||
2523 | -showdown.subParser('unescapeSpecialChars', function (text) { | ||
2524 | - 'use strict'; | ||
2525 | - | ||
2526 | - text = text.replace(/~E(\d+)E/g, function (wholeMatch, m1) { | ||
2527 | - var charCodeToReplace = parseInt(m1); | ||
2528 | - return String.fromCharCode(charCodeToReplace); | ||
2529 | - }); | ||
2530 | - return text; | ||
2531 | -}); | ||
2532 | -module.exports = showdown; |
wxParse/wxDiscode.js
已删除
100644 → 0
1 | -// HTML 支持的数学符号 | ||
2 | -function strNumDiscode(str){ | ||
3 | - str = str.replace(/∀/g, '∀'); | ||
4 | - str = str.replace(/∂/g, '∂'); | ||
5 | - str = str.replace(/&exists;/g, '∃'); | ||
6 | - str = str.replace(/∅/g, '∅'); | ||
7 | - str = str.replace(/∇/g, '∇'); | ||
8 | - str = str.replace(/∈/g, '∈'); | ||
9 | - str = str.replace(/∉/g, '∉'); | ||
10 | - str = str.replace(/∋/g, '∋'); | ||
11 | - str = str.replace(/∏/g, '∏'); | ||
12 | - str = str.replace(/∑/g, '∑'); | ||
13 | - str = str.replace(/−/g, '−'); | ||
14 | - str = str.replace(/∗/g, '∗'); | ||
15 | - str = str.replace(/√/g, '√'); | ||
16 | - str = str.replace(/∝/g, '∝'); | ||
17 | - str = str.replace(/∞/g, '∞'); | ||
18 | - str = str.replace(/∠/g, '∠'); | ||
19 | - str = str.replace(/∧/g, '∧'); | ||
20 | - str = str.replace(/∨/g, '∨'); | ||
21 | - str = str.replace(/∩/g, '∩'); | ||
22 | - str = str.replace(/∩/g, '∪'); | ||
23 | - str = str.replace(/∫/g, '∫'); | ||
24 | - str = str.replace(/∴/g, '∴'); | ||
25 | - str = str.replace(/∼/g, '∼'); | ||
26 | - str = str.replace(/≅/g, '≅'); | ||
27 | - str = str.replace(/≈/g, '≈'); | ||
28 | - str = str.replace(/≠/g, '≠'); | ||
29 | - str = str.replace(/≤/g, '≤'); | ||
30 | - str = str.replace(/≥/g, '≥'); | ||
31 | - str = str.replace(/⊂/g, '⊂'); | ||
32 | - str = str.replace(/⊃/g, '⊃'); | ||
33 | - str = str.replace(/⊄/g, '⊄'); | ||
34 | - str = str.replace(/⊆/g, '⊆'); | ||
35 | - str = str.replace(/⊇/g, '⊇'); | ||
36 | - str = str.replace(/⊕/g, '⊕'); | ||
37 | - str = str.replace(/⊗/g, '⊗'); | ||
38 | - str = str.replace(/⊥/g, '⊥'); | ||
39 | - str = str.replace(/⋅/g, '⋅'); | ||
40 | - return str; | ||
41 | -} | ||
42 | - | ||
43 | -//HTML 支持的希腊字母 | ||
44 | -function strGreeceDiscode(str){ | ||
45 | - str = str.replace(/Α/g, 'Α'); | ||
46 | - str = str.replace(/Β/g, 'Β'); | ||
47 | - str = str.replace(/Γ/g, 'Γ'); | ||
48 | - str = str.replace(/Δ/g, 'Δ'); | ||
49 | - str = str.replace(/Ε/g, 'Ε'); | ||
50 | - str = str.replace(/Ζ/g, 'Ζ'); | ||
51 | - str = str.replace(/Η/g, 'Η'); | ||
52 | - str = str.replace(/Θ/g, 'Θ'); | ||
53 | - str = str.replace(/Ι/g, 'Ι'); | ||
54 | - str = str.replace(/Κ/g, 'Κ'); | ||
55 | - str = str.replace(/Λ/g, 'Λ'); | ||
56 | - str = str.replace(/Μ/g, 'Μ'); | ||
57 | - str = str.replace(/Ν/g, 'Ν'); | ||
58 | - str = str.replace(/Ξ/g, 'Ν'); | ||
59 | - str = str.replace(/Ο/g, 'Ο'); | ||
60 | - str = str.replace(/Π/g, 'Π'); | ||
61 | - str = str.replace(/Ρ/g, 'Ρ'); | ||
62 | - str = str.replace(/Σ/g, 'Σ'); | ||
63 | - str = str.replace(/Τ/g, 'Τ'); | ||
64 | - str = str.replace(/Υ/g, 'Υ'); | ||
65 | - str = str.replace(/Φ/g, 'Φ'); | ||
66 | - str = str.replace(/Χ/g, 'Χ'); | ||
67 | - str = str.replace(/Ψ/g, 'Ψ'); | ||
68 | - str = str.replace(/Ω/g, 'Ω'); | ||
69 | - | ||
70 | - str = str.replace(/α/g, 'α'); | ||
71 | - str = str.replace(/β/g, 'β'); | ||
72 | - str = str.replace(/γ/g, 'γ'); | ||
73 | - str = str.replace(/δ/g, 'δ'); | ||
74 | - str = str.replace(/ε/g, 'ε'); | ||
75 | - str = str.replace(/ζ/g, 'ζ'); | ||
76 | - str = str.replace(/η/g, 'η'); | ||
77 | - str = str.replace(/θ/g, 'θ'); | ||
78 | - str = str.replace(/ι/g, 'ι'); | ||
79 | - str = str.replace(/κ/g, 'κ'); | ||
80 | - str = str.replace(/λ/g, 'λ'); | ||
81 | - str = str.replace(/μ/g, 'μ'); | ||
82 | - str = str.replace(/ν/g, 'ν'); | ||
83 | - str = str.replace(/ξ/g, 'ξ'); | ||
84 | - str = str.replace(/ο/g, 'ο'); | ||
85 | - str = str.replace(/π/g, 'π'); | ||
86 | - str = str.replace(/ρ/g, 'ρ'); | ||
87 | - str = str.replace(/ς/g, 'ς'); | ||
88 | - str = str.replace(/σ/g, 'σ'); | ||
89 | - str = str.replace(/τ/g, 'τ'); | ||
90 | - str = str.replace(/υ/g, 'υ'); | ||
91 | - str = str.replace(/φ/g, 'φ'); | ||
92 | - str = str.replace(/χ/g, 'χ'); | ||
93 | - str = str.replace(/ψ/g, 'ψ'); | ||
94 | - str = str.replace(/ω/g, 'ω'); | ||
95 | - str = str.replace(/ϑ/g, 'ϑ'); | ||
96 | - str = str.replace(/ϒ/g, 'ϒ'); | ||
97 | - str = str.replace(/ϖ/g, 'ϖ'); | ||
98 | - str = str.replace(/·/g, '·'); | ||
99 | - return str; | ||
100 | -} | ||
101 | - | ||
102 | -// | ||
103 | - | ||
104 | -function strcharacterDiscode(str){ | ||
105 | - // 加入常用解析 | ||
106 | - str = str.replace(/ /g, ' '); | ||
107 | - str = str.replace(/"/g, "'"); | ||
108 | - str = str.replace(/&/g, '&'); | ||
109 | - // str = str.replace(/</g, '‹'); | ||
110 | - // str = str.replace(/>/g, '›'); | ||
111 | - | ||
112 | - str = str.replace(/</g, '<'); | ||
113 | - str = str.replace(/>/g, '>'); | ||
114 | - str = str.replace(/•/g, '•'); | ||
115 | - | ||
116 | - return str; | ||
117 | -} | ||
118 | - | ||
119 | -// HTML 支持的其他实体 | ||
120 | -function strOtherDiscode(str){ | ||
121 | - str = str.replace(/Œ/g, 'Œ'); | ||
122 | - str = str.replace(/œ/g, 'œ'); | ||
123 | - str = str.replace(/Š/g, 'Š'); | ||
124 | - str = str.replace(/š/g, 'š'); | ||
125 | - str = str.replace(/Ÿ/g, 'Ÿ'); | ||
126 | - str = str.replace(/ƒ/g, 'ƒ'); | ||
127 | - str = str.replace(/ˆ/g, 'ˆ'); | ||
128 | - str = str.replace(/˜/g, '˜'); | ||
129 | - str = str.replace(/ /g, ''); | ||
130 | - str = str.replace(/ /g, ''); | ||
131 | - str = str.replace(/ /g, ''); | ||
132 | - str = str.replace(/‌/g, ''); | ||
133 | - str = str.replace(/‍/g, ''); | ||
134 | - str = str.replace(/‎/g, ''); | ||
135 | - str = str.replace(/‏/g, ''); | ||
136 | - str = str.replace(/–/g, '–'); | ||
137 | - str = str.replace(/—/g, '—'); | ||
138 | - str = str.replace(/‘/g, '‘'); | ||
139 | - str = str.replace(/’/g, '’'); | ||
140 | - str = str.replace(/‚/g, '‚'); | ||
141 | - str = str.replace(/“/g, '“'); | ||
142 | - str = str.replace(/”/g, '”'); | ||
143 | - str = str.replace(/„/g, '„'); | ||
144 | - str = str.replace(/†/g, '†'); | ||
145 | - str = str.replace(/‡/g, '‡'); | ||
146 | - str = str.replace(/•/g, '•'); | ||
147 | - str = str.replace(/…/g, '…'); | ||
148 | - str = str.replace(/‰/g, '‰'); | ||
149 | - str = str.replace(/′/g, '′'); | ||
150 | - str = str.replace(/″/g, '″'); | ||
151 | - str = str.replace(/‹/g, '‹'); | ||
152 | - str = str.replace(/›/g, '›'); | ||
153 | - str = str.replace(/‾/g, '‾'); | ||
154 | - str = str.replace(/€/g, '€'); | ||
155 | - str = str.replace(/™/g, '™'); | ||
156 | - | ||
157 | - str = str.replace(/←/g, '←'); | ||
158 | - str = str.replace(/↑/g, '↑'); | ||
159 | - str = str.replace(/→/g, '→'); | ||
160 | - str = str.replace(/↓/g, '↓'); | ||
161 | - str = str.replace(/↔/g, '↔'); | ||
162 | - str = str.replace(/↵/g, '↵'); | ||
163 | - str = str.replace(/⌈/g, '⌈'); | ||
164 | - str = str.replace(/⌉/g, '⌉'); | ||
165 | - | ||
166 | - str = str.replace(/⌊/g, '⌊'); | ||
167 | - str = str.replace(/⌋/g, '⌋'); | ||
168 | - str = str.replace(/◊/g, '◊'); | ||
169 | - str = str.replace(/♠/g, '♠'); | ||
170 | - str = str.replace(/♣/g, '♣'); | ||
171 | - str = str.replace(/♥/g, '♥'); | ||
172 | - | ||
173 | - str = str.replace(/♦/g, '♦'); | ||
174 | - str = str.replace(/'/g, '\''); | ||
175 | - return str; | ||
176 | -} | ||
177 | - | ||
178 | -function strMoreDiscode(str){ | ||
179 | - str = str.replace(/\r\n/g,""); | ||
180 | - str = str.replace(/\n/g,""); | ||
181 | - | ||
182 | - str = str.replace(/code/g,"wxxxcode-style"); | ||
183 | - return str; | ||
184 | -} | ||
185 | - | ||
186 | -function strDiscode(str){ | ||
187 | - str = strNumDiscode(str); | ||
188 | - str = strGreeceDiscode(str); | ||
189 | - str = strcharacterDiscode(str); | ||
190 | - str = strOtherDiscode(str); | ||
191 | - str = strMoreDiscode(str); | ||
192 | - return str; | ||
193 | -} | ||
194 | -function urlToHttpUrl(url,rep){ | ||
195 | - | ||
196 | - var patt1 = new RegExp("^//"); | ||
197 | - var result = patt1.test(url); | ||
198 | - if(result){ | ||
199 | - url = rep+":"+url; | ||
200 | - } | ||
201 | - return url; | ||
202 | -} | ||
203 | - | ||
204 | -module.exports = { | ||
205 | - strDiscode:strDiscode, | ||
206 | - urlToHttpUrl:urlToHttpUrl | ||
207 | -} |
wxParse/wxParse.js
已删除
100644 → 0
1 | -/** | ||
2 | - * author: Di (微信小程序开发工程师) | ||
3 | - * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | ||
4 | - * 垂直微信小程序开发交流社区 | ||
5 | - * | ||
6 | - * github地址: https://github.com/icindy/wxParse | ||
7 | - * | ||
8 | - * for: 微信小程序富文本解析 | ||
9 | - * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | ||
10 | - */ | ||
11 | - | ||
12 | -/** | ||
13 | - * utils函数引入 | ||
14 | - **/ | ||
15 | -import showdown from './showdown.js'; | ||
16 | -import HtmlToJson from './html2json.js'; | ||
17 | -/** | ||
18 | - * 配置及公有属性 | ||
19 | - **/ | ||
20 | -var realWindowWidth = 0; | ||
21 | -var realWindowHeight = 0; | ||
22 | -wx.getSystemInfo({ | ||
23 | - success: function (res) { | ||
24 | - realWindowWidth = res.windowWidth | ||
25 | - realWindowHeight = res.windowHeight | ||
26 | - } | ||
27 | -}) | ||
28 | -/** | ||
29 | - * 主函数入口区 | ||
30 | - **/ | ||
31 | -function wxParse(bindName = 'wxParseData', type='html', data='<div class="color:red;">数据不能为空</div>', target,imagePadding) { | ||
32 | - var that = target; | ||
33 | - var transData = {};//存放转化后的数据 | ||
34 | - if (type == 'html') { | ||
35 | - transData = HtmlToJson.html2json(data, bindName); | ||
36 | - // console.log(JSON.stringify(transData, ' ', ' ')); | ||
37 | - } else if (type == 'md' || type == 'markdown') { | ||
38 | - var converter = new showdown.Converter(); | ||
39 | - var html = converter.makeHtml(data); | ||
40 | - transData = HtmlToJson.html2json(html, bindName); | ||
41 | - console.log(JSON.stringify(transData, ' ', ' ')); | ||
42 | - } | ||
43 | - transData.view = {}; | ||
44 | - transData.view.imagePadding = 0; | ||
45 | - if(typeof(imagePadding) != 'undefined'){ | ||
46 | - transData.view.imagePadding = imagePadding | ||
47 | - } | ||
48 | - var bindData = {}; | ||
49 | - bindData[bindName] = transData; | ||
50 | - that.setData(bindData) | ||
51 | - that.wxParseImgLoad = wxParseImgLoad; | ||
52 | - that.wxParseImgTap = wxParseImgTap; | ||
53 | -} | ||
54 | -// 图片点击事件 | ||
55 | -function wxParseImgTap(e) { | ||
56 | - var that = this; | ||
57 | - var nowImgUrl = e.target.dataset.src; | ||
58 | - var tagFrom = e.target.dataset.from; | ||
59 | - if (typeof (tagFrom) != 'undefined' && tagFrom.length > 0) { | ||
60 | - wx.previewImage({ | ||
61 | - current: nowImgUrl, // 当前显示图片的http链接 | ||
62 | - urls: that.data[tagFrom].imageUrls // 需要预览的图片http链接列表 | ||
63 | - }) | ||
64 | - } | ||
65 | -} | ||
66 | - | ||
67 | -/** | ||
68 | - * 图片视觉宽高计算函数区 | ||
69 | - **/ | ||
70 | -function wxParseImgLoad(e) { | ||
71 | - var that = this; | ||
72 | - var tagFrom = e.target.dataset.from; | ||
73 | - var idx = e.target.dataset.idx; | ||
74 | - if (typeof (tagFrom) != 'undefined' && tagFrom.length > 0) { | ||
75 | - calMoreImageInfo(e, idx, that, tagFrom) | ||
76 | - } | ||
77 | -} | ||
78 | -// 假循环获取计算图片视觉最佳宽高 | ||
79 | -function calMoreImageInfo(e, idx, that, bindName) { | ||
80 | - var temData = that.data[bindName]; | ||
81 | - if (!temData || temData.images.length == 0) { | ||
82 | - return; | ||
83 | - } | ||
84 | - var temImages = temData.images; | ||
85 | - //因为无法获取view宽度 需要自定义padding进行计算,稍后处理 | ||
86 | - var recal = wxAutoImageCal(e.detail.width, e.detail.height,that,bindName); | ||
87 | - // temImages[idx].width = recal.imageWidth; | ||
88 | - // temImages[idx].height = recal.imageheight; | ||
89 | - // temData.images = temImages; | ||
90 | - // var bindData = {}; | ||
91 | - // bindData[bindName] = temData; | ||
92 | - // that.setData(bindData); | ||
93 | - var index = temImages[idx].index | ||
94 | - var key = `${bindName}` | ||
95 | - for (var i of index.split('.')) key+=`.nodes[${i}]` | ||
96 | - var keyW = key + '.width' | ||
97 | - var keyH = key + '.height' | ||
98 | - that.setData({ | ||
99 | - [keyW]: recal.imageWidth, | ||
100 | - [keyH]: recal.imageheight, | ||
101 | - }) | ||
102 | -} | ||
103 | - | ||
104 | -// 计算视觉优先的图片宽高 | ||
105 | -function wxAutoImageCal(originalWidth, originalHeight,that,bindName) { | ||
106 | - //获取图片的原始长宽 | ||
107 | - var windowWidth = 0, windowHeight = 0; | ||
108 | - var autoWidth = 0, autoHeight = 0; | ||
109 | - var results = {}; | ||
110 | - var padding = that.data[bindName].view.imagePadding; | ||
111 | - windowWidth = realWindowWidth-2*padding; | ||
112 | - windowHeight = realWindowHeight; | ||
113 | - //判断按照那种方式进行缩放 | ||
114 | - // console.log("windowWidth" + windowWidth); | ||
115 | - if (originalWidth > windowWidth) {//在图片width大于手机屏幕width时候 | ||
116 | - autoWidth = windowWidth; | ||
117 | - // console.log("autoWidth" + autoWidth); | ||
118 | - autoHeight = (autoWidth * originalHeight) / originalWidth; | ||
119 | - // console.log("autoHeight" + autoHeight); | ||
120 | - results.imageWidth = autoWidth; | ||
121 | - results.imageheight = autoHeight; | ||
122 | - } else {//否则展示原来的数据 | ||
123 | - results.imageWidth = originalWidth; | ||
124 | - results.imageheight = originalHeight; | ||
125 | - } | ||
126 | - return results; | ||
127 | -} | ||
128 | - | ||
129 | -function wxParseTemArray(temArrayName,bindNameReg,total,that){ | ||
130 | - var array = []; | ||
131 | - var temData = that.data; | ||
132 | - var obj = null; | ||
133 | - for(var i = 0; i < total; i++){ | ||
134 | - var simArr = temData[bindNameReg+i].nodes; | ||
135 | - array.push(simArr); | ||
136 | - } | ||
137 | - | ||
138 | - temArrayName = temArrayName || 'wxParseTemArray'; | ||
139 | - obj = JSON.parse('{"'+ temArrayName +'":""}'); | ||
140 | - obj[temArrayName] = array; | ||
141 | - that.setData(obj); | ||
142 | -} | ||
143 | - | ||
144 | -/** | ||
145 | - * 配置emojis | ||
146 | - * | ||
147 | - */ | ||
148 | - | ||
149 | -function emojisInit(reg='',baseSrc="/wxParse/emojis/",emojis){ | ||
150 | - HtmlToJson.emojisInit(reg,baseSrc,emojis); | ||
151 | -} | ||
152 | - | ||
153 | -module.exports = { | ||
154 | - wxParse: wxParse, | ||
155 | - wxParseTemArray:wxParseTemArray, | ||
156 | - emojisInit:emojisInit | ||
157 | -} | ||
158 | - | ||
159 | - |
wxParse/wxParse.wxml
已删除
100644 → 0
1 | -<!--** | ||
2 | - * author: Di (微信小程序开发工程师) | ||
3 | - * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | ||
4 | - * 垂直微信小程序开发交流社区 | ||
5 | - * | ||
6 | - * github地址: https://github.com/icindy/wxParse | ||
7 | - * | ||
8 | - * for: 微信小程序富文本解析 | ||
9 | - * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | ||
10 | - */--> | ||
11 | - | ||
12 | -<!--基础元素--> | ||
13 | -<template name="wxParseVideo"> | ||
14 | - <!--增加video标签支持,并循环添加--> | ||
15 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
16 | - <video class="{{item.classStr}} wxParse-{{item.tag}}-video" src="{{item.attr.src}}"></video> | ||
17 | - </view> | ||
18 | -</template> | ||
19 | - | ||
20 | -<template name="wxParseImg"> | ||
21 | - <image class="{{item.classStr}} wxParse-{{item.tag}}" data-from="{{item.from}}" data-src="{{item.attr.src}}" data-idx="{{item.imgIndex}}" src="{{item.attr.src}}" mode="aspectFit" bindload="wxParseImgLoad" bindtap="wxParseImgTap" mode="widthFix" style="width:{{item.width}}px;" | ||
22 | - /> | ||
23 | -</template> | ||
24 | - | ||
25 | -<template name="WxEmojiView"> | ||
26 | - <view class="WxEmojiView wxParse-inline" style="{{item.styleStr}}"> | ||
27 | - <block wx:for="{{item.textArray}}" wx:key=""> | ||
28 | - <block class="{{item.text == '\\n' ? 'wxParse-hide':''}}" wx:if="{{item.node == 'text'}}">{{item.text}}</block> | ||
29 | - <block wx:elif="{{item.node == 'element'}}"> | ||
30 | - <image class="wxEmoji" src="{{item.baseSrc}}{{item.text}}" /> | ||
31 | - </block> | ||
32 | - </block> | ||
33 | - </view> | ||
34 | -</template> | ||
35 | - | ||
36 | -<template name="WxParseBr"> | ||
37 | - <text>\n</text> | ||
38 | -</template> | ||
39 | -<!--入口模版--> | ||
40 | - | ||
41 | -<template name="wxParse"> | ||
42 | - <block wx:for="{{wxParseData}}" wx:key=""> | ||
43 | - <template is="wxParse0" data="{{item}}" /> | ||
44 | - </block> | ||
45 | -</template> | ||
46 | - | ||
47 | - | ||
48 | -<!--循环模版--> | ||
49 | -<template name="wxParse0"> | ||
50 | - <!--<template is="wxParse1" data="{{item}}" />--> | ||
51 | - <!--判断是否是标签节点--> | ||
52 | - <block wx:if="{{item.node == 'element'}}"> | ||
53 | - <block wx:if="{{item.tag == 'button'}}"> | ||
54 | - <button type="default" size="mini"> | ||
55 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
56 | - <template is="wxParse1" data="{{item}}" /> | ||
57 | - </block> | ||
58 | - </button> | ||
59 | - </block> | ||
60 | - <!--li类型--> | ||
61 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
62 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
63 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
64 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
65 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
66 | - </view> | ||
67 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
68 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
69 | - <template is="wxParse1" data="{{item}}" /> | ||
70 | - </block> | ||
71 | - </view> | ||
72 | - </view> | ||
73 | - </view> | ||
74 | - </block> | ||
75 | - | ||
76 | - <!--video类型--> | ||
77 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
78 | - <template is="wxParseVideo" data="{{item}}" /> | ||
79 | - </block> | ||
80 | - | ||
81 | - <!--img类型--> | ||
82 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
83 | - <template is="wxParseImg" data="{{item}}" /> | ||
84 | - </block> | ||
85 | - | ||
86 | - <!--a类型--> | ||
87 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
88 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
89 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
90 | - <template is="wxParse1" data="{{item}}" /> | ||
91 | - </block> | ||
92 | - </view> | ||
93 | - </block> | ||
94 | - <block wx:elif="{{item.tag == 'table'}}"> | ||
95 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
96 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
97 | - <template is="wxParse1" data="{{item}}" /> | ||
98 | - </block> | ||
99 | - </view> | ||
100 | - </block> | ||
101 | - | ||
102 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
103 | - <template is="WxParseBr"></template> | ||
104 | - </block> | ||
105 | - <!--其他块级标签--> | ||
106 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
107 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
108 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
109 | - <template is="wxParse1" data="{{item}}" /> | ||
110 | - </block> | ||
111 | - </view> | ||
112 | - </block> | ||
113 | - | ||
114 | - <!--内联标签--> | ||
115 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
116 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
117 | - <template is="wxParse1" data="{{item}}" /> | ||
118 | - </block> | ||
119 | - </view> | ||
120 | - | ||
121 | - </block> | ||
122 | - | ||
123 | - <!--判断是否是文本节点--> | ||
124 | - <block wx:elif="{{item.node == 'text'}}"> | ||
125 | - <!--如果是,直接进行--> | ||
126 | - <template is="WxEmojiView" data="{{item}}" /> | ||
127 | - </block> | ||
128 | - | ||
129 | -</template> | ||
130 | - | ||
131 | - | ||
132 | - | ||
133 | -<!--循环模版--> | ||
134 | -<template name="wxParse1"> | ||
135 | - <!--<template is="wxParse2" data="{{item}}" />--> | ||
136 | - <!--判断是否是标签节点--> | ||
137 | - <block wx:if="{{item.node == 'element'}}"> | ||
138 | - <block wx:if="{{item.tag == 'button'}}"> | ||
139 | - <button type="default" size="mini"> | ||
140 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
141 | - <template is="wxParse2" data="{{item}}" /> | ||
142 | - </block> | ||
143 | - </button> | ||
144 | - </block> | ||
145 | - <!--li类型--> | ||
146 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
147 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
148 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
149 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
150 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
151 | - </view> | ||
152 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
153 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
154 | - <template is="wxParse2" data="{{item}}" /> | ||
155 | - </block> | ||
156 | - </view> | ||
157 | - </view> | ||
158 | - </view> | ||
159 | - </block> | ||
160 | - | ||
161 | - <!--video类型--> | ||
162 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
163 | - <template is="wxParseVideo" data="{{item}}" /> | ||
164 | - </block> | ||
165 | - | ||
166 | - <!--img类型--> | ||
167 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
168 | - <template is="wxParseImg" data="{{item}}" /> | ||
169 | - </block> | ||
170 | - | ||
171 | - <!--a类型--> | ||
172 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
173 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
174 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
175 | - <template is="wxParse2" data="{{item}}" /> | ||
176 | - </block> | ||
177 | - </view> | ||
178 | - </block> | ||
179 | - | ||
180 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
181 | - <template is="WxParseBr"></template> | ||
182 | - </block> | ||
183 | - <!--其他块级标签--> | ||
184 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
185 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
186 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
187 | - <template is="wxParse2" data="{{item}}" /> | ||
188 | - </block> | ||
189 | - </view> | ||
190 | - </block> | ||
191 | - | ||
192 | - <!--内联标签--> | ||
193 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
194 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
195 | - <template is="wxParse2" data="{{item}}" /> | ||
196 | - </block> | ||
197 | - </view> | ||
198 | - | ||
199 | - </block> | ||
200 | - | ||
201 | - <!--判断是否是文本节点--> | ||
202 | - <block wx:elif="{{item.node == 'text'}}"> | ||
203 | - <!--如果是,直接进行--> | ||
204 | - <template is="WxEmojiView" data="{{item}}" /> | ||
205 | - </block> | ||
206 | - | ||
207 | -</template> | ||
208 | - | ||
209 | - | ||
210 | -<!--循环模版--> | ||
211 | -<template name="wxParse2"> | ||
212 | - <!--<template is="wxParse3" data="{{item}}" />--> | ||
213 | - <!--判断是否是标签节点--> | ||
214 | - <block wx:if="{{item.node == 'element'}}"> | ||
215 | - <block wx:if="{{item.tag == 'button'}}"> | ||
216 | - <button type="default" size="mini"> | ||
217 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
218 | - <template is="wxParse3" data="{{item}}" /> | ||
219 | - </block> | ||
220 | - </button> | ||
221 | - </block> | ||
222 | - <!--li类型--> | ||
223 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
224 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
225 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
226 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
227 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
228 | - </view> | ||
229 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
230 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
231 | - <template is="wxParse3" data="{{item}}" /> | ||
232 | - </block> | ||
233 | - </view> | ||
234 | - </view> | ||
235 | - </view> | ||
236 | - </block> | ||
237 | - | ||
238 | - <!--video类型--> | ||
239 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
240 | - <template is="wxParseVideo" data="{{item}}" /> | ||
241 | - </block> | ||
242 | - | ||
243 | - <!--img类型--> | ||
244 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
245 | - <template is="wxParseImg" data="{{item}}" /> | ||
246 | - </block> | ||
247 | - | ||
248 | - <!--a类型--> | ||
249 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
250 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
251 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
252 | - <template is="wxParse3" data="{{item}}" /> | ||
253 | - </block> | ||
254 | - </view> | ||
255 | - </block> | ||
256 | - | ||
257 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
258 | - <template is="WxParseBr"></template> | ||
259 | - </block> | ||
260 | - <!--其他块级标签--> | ||
261 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
262 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
263 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
264 | - <template is="wxParse3" data="{{item}}" /> | ||
265 | - </block> | ||
266 | - </view> | ||
267 | - </block> | ||
268 | - | ||
269 | - <!--内联标签--> | ||
270 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
271 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
272 | - <template is="wxParse3" data="{{item}}" /> | ||
273 | - </block> | ||
274 | - </view> | ||
275 | - | ||
276 | - </block> | ||
277 | - | ||
278 | - <!--判断是否是文本节点--> | ||
279 | - <block wx:elif="{{item.node == 'text'}}"> | ||
280 | - <!--如果是,直接进行--> | ||
281 | - <template is="WxEmojiView" data="{{item}}" /> | ||
282 | - </block> | ||
283 | - | ||
284 | -</template> | ||
285 | - | ||
286 | -<!--循环模版--> | ||
287 | -<template name="wxParse3"> | ||
288 | - <!--<template is="wxParse4" data="{{item}}" />--> | ||
289 | - <!--判断是否是标签节点--> | ||
290 | - <block wx:if="{{item.node == 'element'}}"> | ||
291 | - <block wx:if="{{item.tag == 'button'}}"> | ||
292 | - <button type="default" size="mini"> | ||
293 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
294 | - <template is="wxParse4" data="{{item}}" /> | ||
295 | - </block> | ||
296 | - </button> | ||
297 | - </block> | ||
298 | - <!--li类型--> | ||
299 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
300 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
301 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
302 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
303 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
304 | - </view> | ||
305 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
306 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
307 | - <template is="wxParse4" data="{{item}}" /> | ||
308 | - </block> | ||
309 | - </view> | ||
310 | - </view> | ||
311 | - </view> | ||
312 | - </block> | ||
313 | - | ||
314 | - <!--video类型--> | ||
315 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
316 | - <template is="wxParseVideo" data="{{item}}" /> | ||
317 | - </block> | ||
318 | - | ||
319 | - <!--img类型--> | ||
320 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
321 | - <template is="wxParseImg" data="{{item}}" /> | ||
322 | - </block> | ||
323 | - | ||
324 | - <!--a类型--> | ||
325 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
326 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
327 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
328 | - <template is="wxParse4" data="{{item}}" /> | ||
329 | - </block> | ||
330 | - </view> | ||
331 | - </block> | ||
332 | - | ||
333 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
334 | - <template is="WxParseBr"></template> | ||
335 | - </block> | ||
336 | - <!--其他块级标签--> | ||
337 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
338 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
339 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
340 | - <template is="wxParse4" data="{{item}}" /> | ||
341 | - </block> | ||
342 | - </view> | ||
343 | - </block> | ||
344 | - | ||
345 | - <!--内联标签--> | ||
346 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
347 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
348 | - <template is="wxParse4" data="{{item}}" /> | ||
349 | - </block> | ||
350 | - </view> | ||
351 | - | ||
352 | - </block> | ||
353 | - | ||
354 | - <!--判断是否是文本节点--> | ||
355 | - <block wx:elif="{{item.node == 'text'}}"> | ||
356 | - <!--如果是,直接进行--> | ||
357 | - <template is="WxEmojiView" data="{{item}}" /> | ||
358 | - </block> | ||
359 | - | ||
360 | -</template> | ||
361 | - | ||
362 | -<!--循环模版--> | ||
363 | -<template name="wxParse4"> | ||
364 | - <!--<template is="wxParse5" data="{{item}}" />--> | ||
365 | - <!--判断是否是标签节点--> | ||
366 | - <block wx:if="{{item.node == 'element'}}"> | ||
367 | - <block wx:if="{{item.tag == 'button'}}"> | ||
368 | - <button type="default" size="mini"> | ||
369 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
370 | - <template is="wxParse5" data="{{item}}" /> | ||
371 | - </block> | ||
372 | - </button> | ||
373 | - </block> | ||
374 | - <!--li类型--> | ||
375 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
376 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
377 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
378 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
379 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
380 | - </view> | ||
381 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
382 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
383 | - <template is="wxParse5" data="{{item}}" /> | ||
384 | - </block> | ||
385 | - </view> | ||
386 | - </view> | ||
387 | - </view> | ||
388 | - </block> | ||
389 | - | ||
390 | - <!--video类型--> | ||
391 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
392 | - <template is="wxParseVideo" data="{{item}}" /> | ||
393 | - </block> | ||
394 | - | ||
395 | - <!--img类型--> | ||
396 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
397 | - <template is="wxParseImg" data="{{item}}" /> | ||
398 | - </block> | ||
399 | - | ||
400 | - <!--a类型--> | ||
401 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
402 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
403 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
404 | - <template is="wxParse5" data="{{item}}" /> | ||
405 | - </block> | ||
406 | - </view> | ||
407 | - </block> | ||
408 | - | ||
409 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
410 | - <template is="WxParseBr"></template> | ||
411 | - </block> | ||
412 | - <!--其他块级标签--> | ||
413 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
414 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
415 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
416 | - <template is="wxParse5" data="{{item}}" /> | ||
417 | - </block> | ||
418 | - </view> | ||
419 | - </block> | ||
420 | - | ||
421 | - <!--内联标签--> | ||
422 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
423 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
424 | - <template is="wxParse5" data="{{item}}" /> | ||
425 | - </block> | ||
426 | - </view> | ||
427 | - | ||
428 | - </block> | ||
429 | - | ||
430 | - <!--判断是否是文本节点--> | ||
431 | - <block wx:elif="{{item.node == 'text'}}"> | ||
432 | - <!--如果是,直接进行--> | ||
433 | - <template is="WxEmojiView" data="{{item}}" /> | ||
434 | - </block> | ||
435 | - | ||
436 | -</template> | ||
437 | - | ||
438 | -<!--循环模版--> | ||
439 | -<template name="wxParse5"> | ||
440 | - <!--<template is="wxParse6" data="{{item}}" />--> | ||
441 | - <!--判断是否是标签节点--> | ||
442 | - <block wx:if="{{item.node == 'element'}}"> | ||
443 | - <block wx:if="{{item.tag == 'button'}}"> | ||
444 | - <button type="default" size="mini"> | ||
445 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
446 | - <template is="wxParse6" data="{{item}}" /> | ||
447 | - </block> | ||
448 | - </button> | ||
449 | - </block> | ||
450 | - <!--li类型--> | ||
451 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
452 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
453 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
454 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
455 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
456 | - </view> | ||
457 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
458 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
459 | - <template is="wxParse6" data="{{item}}" /> | ||
460 | - </block> | ||
461 | - </view> | ||
462 | - </view> | ||
463 | - </view> | ||
464 | - </block> | ||
465 | - | ||
466 | - <!--video类型--> | ||
467 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
468 | - <template is="wxParseVideo" data="{{item}}" /> | ||
469 | - </block> | ||
470 | - | ||
471 | - <!--img类型--> | ||
472 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
473 | - <template is="wxParseImg" data="{{item}}" /> | ||
474 | - </block> | ||
475 | - | ||
476 | - <!--a类型--> | ||
477 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
478 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
479 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
480 | - <template is="wxParse6" data="{{item}}" /> | ||
481 | - </block> | ||
482 | - </view> | ||
483 | - </block> | ||
484 | - | ||
485 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
486 | - <template is="WxParseBr"></template> | ||
487 | - </block> | ||
488 | - <!--其他块级标签--> | ||
489 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
490 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
491 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
492 | - <template is="wxParse6" data="{{item}}" /> | ||
493 | - </block> | ||
494 | - </view> | ||
495 | - </block> | ||
496 | - | ||
497 | - <!--内联标签--> | ||
498 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
499 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
500 | - <template is="wxParse6" data="{{item}}" /> | ||
501 | - </block> | ||
502 | - </view> | ||
503 | - | ||
504 | - </block> | ||
505 | - | ||
506 | - <!--判断是否是文本节点--> | ||
507 | - <block wx:elif="{{item.node == 'text'}}"> | ||
508 | - <!--如果是,直接进行--> | ||
509 | - <template is="WxEmojiView" data="{{item}}" /> | ||
510 | - </block> | ||
511 | - | ||
512 | -</template> | ||
513 | - | ||
514 | -<!--循环模版--> | ||
515 | -<template name="wxParse6"> | ||
516 | - <!--<template is="wxParse7" data="{{item}}" />--> | ||
517 | - <!--判断是否是标签节点--> | ||
518 | - <block wx:if="{{item.node == 'element'}}"> | ||
519 | - <block wx:if="{{item.tag == 'button'}}"> | ||
520 | - <button type="default" size="mini"> | ||
521 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
522 | - <template is="wxParse7" data="{{item}}" /> | ||
523 | - </block> | ||
524 | - </button> | ||
525 | - </block> | ||
526 | - <!--li类型--> | ||
527 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
528 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
529 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
530 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
531 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
532 | - </view> | ||
533 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
534 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
535 | - <template is="wxParse7" data="{{item}}" /> | ||
536 | - </block> | ||
537 | - </view> | ||
538 | - </view> | ||
539 | - </view> | ||
540 | - </block> | ||
541 | - | ||
542 | - <!--video类型--> | ||
543 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
544 | - <template is="wxParseVideo" data="{{item}}" /> | ||
545 | - </block> | ||
546 | - | ||
547 | - <!--img类型--> | ||
548 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
549 | - <template is="wxParseImg" data="{{item}}" /> | ||
550 | - </block> | ||
551 | - | ||
552 | - <!--a类型--> | ||
553 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
554 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
555 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
556 | - <template is="wxParse7" data="{{item}}" /> | ||
557 | - </block> | ||
558 | - </view> | ||
559 | - </block> | ||
560 | - | ||
561 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
562 | - <template is="WxParseBr"></template> | ||
563 | - </block> | ||
564 | - <!--其他块级标签--> | ||
565 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
566 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
567 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
568 | - <template is="wxParse7" data="{{item}}" /> | ||
569 | - </block> | ||
570 | - </view> | ||
571 | - </block> | ||
572 | - | ||
573 | - <!--内联标签--> | ||
574 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
575 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
576 | - <template is="wxParse7" data="{{item}}" /> | ||
577 | - </block> | ||
578 | - </view> | ||
579 | - | ||
580 | - </block> | ||
581 | - | ||
582 | - <!--判断是否是文本节点--> | ||
583 | - <block wx:elif="{{item.node == 'text'}}"> | ||
584 | - <!--如果是,直接进行--> | ||
585 | - <template is="WxEmojiView" data="{{item}}" /> | ||
586 | - </block> | ||
587 | - | ||
588 | -</template> | ||
589 | -<!--循环模版--> | ||
590 | -<template name="wxParse7"> | ||
591 | - <!--<template is="wxParse8" data="{{item}}" />--> | ||
592 | - <!--判断是否是标签节点--> | ||
593 | - <block wx:if="{{item.node == 'element'}}"> | ||
594 | - <block wx:if="{{item.tag == 'button'}}"> | ||
595 | - <button type="default" size="mini"> | ||
596 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
597 | - <template is="wxParse8" data="{{item}}" /> | ||
598 | - </block> | ||
599 | - </button> | ||
600 | - </block> | ||
601 | - <!--li类型--> | ||
602 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
603 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
604 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
605 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
606 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
607 | - </view> | ||
608 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
609 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
610 | - <template is="wxParse8" data="{{item}}" /> | ||
611 | - </block> | ||
612 | - </view> | ||
613 | - </view> | ||
614 | - </view> | ||
615 | - </block> | ||
616 | - | ||
617 | - <!--video类型--> | ||
618 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
619 | - <template is="wxParseVideo" data="{{item}}" /> | ||
620 | - </block> | ||
621 | - | ||
622 | - <!--img类型--> | ||
623 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
624 | - <template is="wxParseImg" data="{{item}}" /> | ||
625 | - </block> | ||
626 | - | ||
627 | - <!--a类型--> | ||
628 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
629 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
630 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
631 | - <template is="wxParse8" data="{{item}}" /> | ||
632 | - </block> | ||
633 | - </view> | ||
634 | - </block> | ||
635 | - | ||
636 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
637 | - <template is="WxParseBr"></template> | ||
638 | - </block> | ||
639 | - <!--其他块级标签--> | ||
640 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
641 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
642 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
643 | - <template is="wxParse8" data="{{item}}" /> | ||
644 | - </block> | ||
645 | - </view> | ||
646 | - </block> | ||
647 | - | ||
648 | - <!--内联标签--> | ||
649 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
650 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
651 | - <template is="wxParse8" data="{{item}}" /> | ||
652 | - </block> | ||
653 | - </view> | ||
654 | - | ||
655 | - </block> | ||
656 | - | ||
657 | - <!--判断是否是文本节点--> | ||
658 | - <block wx:elif="{{item.node == 'text'}}"> | ||
659 | - <!--如果是,直接进行--> | ||
660 | - <template is="WxEmojiView" data="{{item}}" /> | ||
661 | - </block> | ||
662 | - | ||
663 | -</template> | ||
664 | - | ||
665 | -<!--循环模版--> | ||
666 | -<template name="wxParse8"> | ||
667 | - <!--<template is="wxParse9" data="{{item}}" />--> | ||
668 | - <!--判断是否是标签节点--> | ||
669 | - <block wx:if="{{item.node == 'element'}}"> | ||
670 | - <block wx:if="{{item.tag == 'button'}}"> | ||
671 | - <button type="default" size="mini"> | ||
672 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
673 | - <template is="wxParse9" data="{{item}}" /> | ||
674 | - </block> | ||
675 | - </button> | ||
676 | - </block> | ||
677 | - <!--li类型--> | ||
678 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
679 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
680 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
681 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
682 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
683 | - </view> | ||
684 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
685 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
686 | - <template is="wxParse9" data="{{item}}" /> | ||
687 | - </block> | ||
688 | - </view> | ||
689 | - </view> | ||
690 | - </view> | ||
691 | - </block> | ||
692 | - | ||
693 | - <!--video类型--> | ||
694 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
695 | - <template is="wxParseVideo" data="{{item}}" /> | ||
696 | - </block> | ||
697 | - | ||
698 | - <!--img类型--> | ||
699 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
700 | - <template is="wxParseImg" data="{{item}}" /> | ||
701 | - </block> | ||
702 | - | ||
703 | - <!--a类型--> | ||
704 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
705 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
706 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
707 | - <template is="wxParse9" data="{{item}}" /> | ||
708 | - </block> | ||
709 | - </view> | ||
710 | - </block> | ||
711 | - | ||
712 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
713 | - <template is="WxParseBr"></template> | ||
714 | - </block> | ||
715 | - <!--其他块级标签--> | ||
716 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
717 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
718 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
719 | - <template is="wxParse9" data="{{item}}" /> | ||
720 | - </block> | ||
721 | - </view> | ||
722 | - </block> | ||
723 | - | ||
724 | - <!--内联标签--> | ||
725 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
726 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
727 | - <template is="wxParse9" data="{{item}}" /> | ||
728 | - </block> | ||
729 | - </view> | ||
730 | - | ||
731 | - </block> | ||
732 | - | ||
733 | - <!--判断是否是文本节点--> | ||
734 | - <block wx:elif="{{item.node == 'text'}}"> | ||
735 | - <!--如果是,直接进行--> | ||
736 | - <template is="WxEmojiView" data="{{item}}" /> | ||
737 | - </block> | ||
738 | - | ||
739 | -</template> | ||
740 | - | ||
741 | -<!--循环模版--> | ||
742 | -<template name="wxParse9"> | ||
743 | - <!--<template is="wxParse10" data="{{item}}" />--> | ||
744 | - <!--判断是否是标签节点--> | ||
745 | - <block wx:if="{{item.node == 'element'}}"> | ||
746 | - <block wx:if="{{item.tag == 'button'}}"> | ||
747 | - <button type="default" size="mini"> | ||
748 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
749 | - <template is="wxParse10" data="{{item}}" /> | ||
750 | - </block> | ||
751 | - </button> | ||
752 | - </block> | ||
753 | - <!--li类型--> | ||
754 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
755 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
756 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
757 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
758 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
759 | - </view> | ||
760 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
761 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
762 | - <template is="wxParse10" data="{{item}}" /> | ||
763 | - </block> | ||
764 | - </view> | ||
765 | - </view> | ||
766 | - </view> | ||
767 | - </block> | ||
768 | - | ||
769 | - <!--video类型--> | ||
770 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
771 | - <template is="wxParseVideo" data="{{item}}" /> | ||
772 | - </block> | ||
773 | - | ||
774 | - <!--img类型--> | ||
775 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
776 | - <template is="wxParseImg" data="{{item}}" /> | ||
777 | - </block> | ||
778 | - | ||
779 | - <!--a类型--> | ||
780 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
781 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
782 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
783 | - <template is="wxParse10" data="{{item}}" /> | ||
784 | - </block> | ||
785 | - </view> | ||
786 | - </block> | ||
787 | - | ||
788 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
789 | - <template is="WxParseBr"></template> | ||
790 | - </block> | ||
791 | - <!--其他块级标签--> | ||
792 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
793 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
794 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
795 | - <template is="wxParse10" data="{{item}}" /> | ||
796 | - </block> | ||
797 | - </view> | ||
798 | - </block> | ||
799 | - | ||
800 | - <!--内联标签--> | ||
801 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
802 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
803 | - <template is="wxParse10" data="{{item}}" /> | ||
804 | - </block> | ||
805 | - </view> | ||
806 | - | ||
807 | - </block> | ||
808 | - | ||
809 | - <!--判断是否是文本节点--> | ||
810 | - <block wx:elif="{{item.node == 'text'}}"> | ||
811 | - <!--如果是,直接进行--> | ||
812 | - <template is="WxEmojiView" data="{{item}}" /> | ||
813 | - </block> | ||
814 | - | ||
815 | -</template> | ||
816 | - | ||
817 | -<!--循环模版--> | ||
818 | -<template name="wxParse10"> | ||
819 | - <!--<template is="wxParse11" data="{{item}}" />--> | ||
820 | - <!--判断是否是标签节点--> | ||
821 | - <block wx:if="{{item.node == 'element'}}"> | ||
822 | - <block wx:if="{{item.tag == 'button'}}"> | ||
823 | - <button type="default" size="mini"> | ||
824 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
825 | - <template is="wxParse11" data="{{item}}" /> | ||
826 | - </block> | ||
827 | - </button> | ||
828 | - </block> | ||
829 | - <!--li类型--> | ||
830 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
831 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
832 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
833 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
834 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
835 | - </view> | ||
836 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
837 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
838 | - <template is="wxParse11" data="{{item}}" /> | ||
839 | - </block> | ||
840 | - </view> | ||
841 | - </view> | ||
842 | - </view> | ||
843 | - </block> | ||
844 | - | ||
845 | - <!--video类型--> | ||
846 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
847 | - <template is="wxParseVideo" data="{{item}}" /> | ||
848 | - </block> | ||
849 | - | ||
850 | - <!--img类型--> | ||
851 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
852 | - <template is="wxParseImg" data="{{item}}" /> | ||
853 | - </block> | ||
854 | - | ||
855 | - <!--a类型--> | ||
856 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
857 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
858 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
859 | - <template is="wxParse11" data="{{item}}" /> | ||
860 | - </block> | ||
861 | - </view> | ||
862 | - </block> | ||
863 | - | ||
864 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
865 | - <template is="WxParseBr"></template> | ||
866 | - </block> | ||
867 | - <!--其他块级标签--> | ||
868 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
869 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
870 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
871 | - <template is="wxParse11" data="{{item}}" /> | ||
872 | - </block> | ||
873 | - </view> | ||
874 | - </block> | ||
875 | - | ||
876 | - <!--内联标签--> | ||
877 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
878 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
879 | - <template is="wxParse11" data="{{item}}" /> | ||
880 | - </block> | ||
881 | - </view> | ||
882 | - | ||
883 | - </block> | ||
884 | - | ||
885 | - <!--判断是否是文本节点--> | ||
886 | - <block wx:elif="{{item.node == 'text'}}"> | ||
887 | - <!--如果是,直接进行--> | ||
888 | - <template is="WxEmojiView" data="{{item}}" /> | ||
889 | - </block> | ||
890 | - | ||
891 | -</template> | ||
892 | - | ||
893 | -<!--循环模版--> | ||
894 | -<template name="wxParse11"> | ||
895 | - <!--<template is="wxParse12" data="{{item}}" />--> | ||
896 | - <!--判断是否是标签节点--> | ||
897 | - <block wx:if="{{item.node == 'element'}}"> | ||
898 | - <block wx:if="{{item.tag == 'button'}}"> | ||
899 | - <button type="default" size="mini"> | ||
900 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
901 | - <template is="wxParse12" data="{{item}}" /> | ||
902 | - </block> | ||
903 | - </button> | ||
904 | - </block> | ||
905 | - <!--li类型--> | ||
906 | - <block wx:elif="{{item.tag == 'li'}}"> | ||
907 | - <view class="{{item.classStr}} wxParse-li" style="{{item.styleStr}}"> | ||
908 | - <view class="{{item.classStr}} wxParse-li-inner"> | ||
909 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
910 | - <view class="{{item.classStr}} wxParse-li-circle"></view> | ||
911 | - </view> | ||
912 | - <view class="{{item.classStr}} wxParse-li-text"> | ||
913 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
914 | - <template is="wxParse12" data="{{item}}" /> | ||
915 | - </block> | ||
916 | - </view> | ||
917 | - </view> | ||
918 | - </view> | ||
919 | - </block> | ||
920 | - | ||
921 | - <!--video类型--> | ||
922 | - <block wx:elif="{{item.tag == 'video'}}"> | ||
923 | - <template is="wxParseVideo" data="{{item}}" /> | ||
924 | - </block> | ||
925 | - | ||
926 | - <!--img类型--> | ||
927 | - <block wx:elif="{{item.tag == 'img'}}"> | ||
928 | - <template is="wxParseImg" data="{{item}}" /> | ||
929 | - </block> | ||
930 | - | ||
931 | - <!--a类型--> | ||
932 | - <block wx:elif="{{item.tag == 'a'}}"> | ||
933 | - <view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}"> | ||
934 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
935 | - <template is="wxParse12" data="{{item}}" /> | ||
936 | - </block> | ||
937 | - </view> | ||
938 | - </block> | ||
939 | - | ||
940 | - <block wx:elif="{{item.tag == 'br'}}"> | ||
941 | - <template is="WxParseBr"></template> | ||
942 | - </block> | ||
943 | - <!--其他块级标签--> | ||
944 | - <block wx:elif="{{item.tagType == 'block'}}"> | ||
945 | - <view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}"> | ||
946 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
947 | - <template is="wxParse12" data="{{item}}" /> | ||
948 | - </block> | ||
949 | - </view> | ||
950 | - </block> | ||
951 | - | ||
952 | - <!--内联标签--> | ||
953 | - <view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}"> | ||
954 | - <block wx:for="{{item.nodes}}" wx:for-item="item" wx:key=""> | ||
955 | - <template is="wxParse12" data="{{item}}" /> | ||
956 | - </block> | ||
957 | - </view> | ||
958 | - | ||
959 | - </block> | ||
960 | - | ||
961 | - <!--判断是否是文本节点--> | ||
962 | - <block wx:elif="{{item.node == 'text'}}"> | ||
963 | - <!--如果是,直接进行--> | ||
964 | - <template is="WxEmojiView" data="{{item}}" /> | ||
965 | - </block> | ||
966 | - | ||
967 | -</template> |
wxParse/wxParse.wxss
已删除
100644 → 0
1 | - | ||
2 | -/** | ||
3 | - * author: Di (微信小程序开发工程师) | ||
4 | - * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | ||
5 | - * 垂直微信小程序开发交流社区 | ||
6 | - * | ||
7 | - * github地址: https://github.com/icindy/wxParse | ||
8 | - * | ||
9 | - * for: 微信小程序富文本解析 | ||
10 | - * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | ||
11 | - */ | ||
12 | - | ||
13 | -.wxParse{ | ||
14 | - margin: 0 5px; | ||
15 | - font-family: Helvetica,sans-serif; | ||
16 | - font-size: 28rpx; | ||
17 | - color: #666; | ||
18 | - line-height: 1.8; | ||
19 | -} | ||
20 | -view{ | ||
21 | - word-break:break-all; | ||
22 | - /*overflow:auto;*/ | ||
23 | -} | ||
24 | -.wxParse-inline{ | ||
25 | - display: inline; | ||
26 | - line-height: 50rpx; | ||
27 | - margin: 0; | ||
28 | - padding: 0; | ||
29 | -} | ||
30 | -/*//标题 */ | ||
31 | -.wxParse-div{margin: 0;padding: 0;} | ||
32 | -.wxParse-h1{ font-size:2em; margin: .67em 0 } | ||
33 | -.wxParse-h2{ font-size:1.5em; margin: .75em 0 } | ||
34 | -.wxParse-h3{ font-size:1.17em; margin: .83em 0 } | ||
35 | -.wxParse-h4{ margin: 1.12em 0} | ||
36 | -.wxParse-h5 { font-size:.83em; margin: 1.5em 0 } | ||
37 | -.wxParse-h6{ font-size:.75em; margin: 1.67em 0 } | ||
38 | - | ||
39 | -.wxParse-h1 { | ||
40 | - font-size: 18px; | ||
41 | - font-weight: 400; | ||
42 | - margin-bottom: .9em; | ||
43 | -} | ||
44 | -.wxParse-h2 { | ||
45 | - font-size: 16px; | ||
46 | - font-weight: 400; | ||
47 | - margin-bottom: .34em; | ||
48 | -} | ||
49 | -.wxParse-h3 { | ||
50 | - font-weight: 400; | ||
51 | - font-size: 15px; | ||
52 | - margin-bottom: .34em; | ||
53 | -} | ||
54 | -.wxParse-h4 { | ||
55 | - font-weight: 400; | ||
56 | - font-size: 14px; | ||
57 | - margin-bottom: .24em; | ||
58 | -} | ||
59 | -.wxParse-h5 { | ||
60 | - font-weight: 400; | ||
61 | - font-size: 13px; | ||
62 | - margin-bottom: .14em; | ||
63 | -} | ||
64 | -.wxParse-h6 { | ||
65 | - font-weight: 400; | ||
66 | - font-size: 12px; | ||
67 | - margin-bottom: .04em; | ||
68 | -} | ||
69 | - | ||
70 | -.wxParse-h1, .wxParse-h2, .wxParse-h3, .wxParse-h4, .wxParse-h5, .wxParse-h6, .wxParse-b, .wxParse-strong { font-weight: bolder } | ||
71 | - | ||
72 | -.wxParse-i,.wxParse-cite,.wxParse-em,.wxParse-var,.wxParse-address{font-style:italic} | ||
73 | -.wxParse-pre,.wxParse-tt,.wxParse-code,.wxParse-kbd,.wxParse-samp{font-family:monospace} | ||
74 | -.wxParse-pre{white-space:pre} | ||
75 | -.wxParse-big{font-size:1.17em} | ||
76 | -.wxParse-small,.wxParse-sub,.wxParse-sup{font-size:.83em} | ||
77 | -.wxParse-sub{vertical-align:sub} | ||
78 | -.wxParse-sup{vertical-align:super} | ||
79 | -.wxParse-s,.wxParse-strike,.wxParse-del{text-decoration:line-through} | ||
80 | -/*wxparse-自定义个性化的css样式*/ | ||
81 | -/*增加video的css样式*/ | ||
82 | -.wxParse-strong,.wxParse-s{display: inline} | ||
83 | -.wxParse-a{ | ||
84 | - color: deepskyblue; | ||
85 | - word-break:break-all; | ||
86 | - overflow:auto; | ||
87 | -} | ||
88 | - | ||
89 | -.wxParse-video{ | ||
90 | - text-align: center; | ||
91 | - margin: 10px 0; | ||
92 | -} | ||
93 | - | ||
94 | -.wxParse-video-video{ | ||
95 | - width:100%; | ||
96 | -} | ||
97 | - | ||
98 | -.wxParse-img{ | ||
99 | - /*background-color: #efefef;*/ | ||
100 | - overflow: hidden; | ||
101 | -} | ||
102 | - | ||
103 | -.wxParse-blockquote { | ||
104 | - margin: 0; | ||
105 | - padding:10px 0 10px 5px; | ||
106 | - font-family:Courier, Calibri,"宋体"; | ||
107 | - background:#f5f5f5; | ||
108 | - border-left: 3px solid #dbdbdb; | ||
109 | -} | ||
110 | - | ||
111 | -.wxParse-code,.wxParse-wxxxcode-style{ | ||
112 | - display: inline; | ||
113 | - background:#f5f5f5; | ||
114 | -} | ||
115 | -.wxParse-ul{ | ||
116 | - margin: 20rpx 10rpx; | ||
117 | -} | ||
118 | - | ||
119 | -.wxParse-li,.wxParse-li-inner{ | ||
120 | - display: flex; | ||
121 | - align-items: baseline; | ||
122 | - margin: 10rpx 0; | ||
123 | -} | ||
124 | -.wxParse-li-text{ | ||
125 | - | ||
126 | - align-items: center; | ||
127 | - line-height: 20px; | ||
128 | -} | ||
129 | - | ||
130 | -.wxParse-li-circle{ | ||
131 | - display: inline-flex; | ||
132 | - width: 5px; | ||
133 | - height: 5px; | ||
134 | - background-color: #333; | ||
135 | - margin-right: 5px; | ||
136 | -} | ||
137 | - | ||
138 | -.wxParse-li-square{ | ||
139 | - display: inline-flex; | ||
140 | - width: 10rpx; | ||
141 | - height: 10rpx; | ||
142 | - background-color: #333; | ||
143 | - margin-right: 5px; | ||
144 | -} | ||
145 | -.wxParse-li-ring{ | ||
146 | - display: inline-flex; | ||
147 | - width: 10rpx; | ||
148 | - height: 10rpx; | ||
149 | - border: 2rpx solid #333; | ||
150 | - border-radius: 50%; | ||
151 | - background-color: #fff; | ||
152 | - margin-right: 5px; | ||
153 | -} | ||
154 | - | ||
155 | -/*.wxParse-table{ | ||
156 | - width: 100%; | ||
157 | - height: 400px; | ||
158 | -} | ||
159 | -.wxParse-thead,.wxParse-tfoot,.wxParse-tr{ | ||
160 | - display: flex; | ||
161 | - flex-direction: row; | ||
162 | -} | ||
163 | -.wxParse-th,.wxParse-td{ | ||
164 | - display: flex; | ||
165 | - width: 580px; | ||
166 | - overflow: auto; | ||
167 | -}*/ | ||
168 | - | ||
169 | -.wxParse-u { | ||
170 | - text-decoration: underline; | ||
171 | -} | ||
172 | -.wxParse-hide{ | ||
173 | - display: none; | ||
174 | -} | ||
175 | -.WxEmojiView{ | ||
176 | - align-items: center; | ||
177 | -} | ||
178 | -.wxEmoji{ | ||
179 | - width: 16px; | ||
180 | - height:16px; | ||
181 | -} | ||
182 | -.wxParse-tr{ | ||
183 | - display: flex; | ||
184 | - border-right:1px solid #e0e0e0; | ||
185 | - border-bottom:1px solid #e0e0e0; | ||
186 | - border-top:1px solid #e0e0e0; | ||
187 | -} | ||
188 | -.wxParse-th, | ||
189 | -.wxParse-td{ | ||
190 | - flex:1; | ||
191 | - padding:5px; | ||
192 | - font-size:28rpx; | ||
193 | - border-left:1px solid #e0e0e0; | ||
194 | - word-break: break-all; | ||
195 | -} | ||
196 | -.wxParse-td:last{ | ||
197 | - border-top:1px solid #e0e0e0; | ||
198 | -} | ||
199 | -.wxParse-th{ | ||
200 | - background:#f0f0f0; | ||
201 | - border-top:1px solid #e0e0e0; | ||
202 | -} | ||
203 | -.wxParse-del{ | ||
204 | - display: inline; | ||
205 | -} | ||
206 | -.wxParse-figure { | ||
207 | - overflow: hidden; | ||
208 | -} |
新建文本文档.txt
0 → 100644
-
请 注册 或 登录 后发表评论