clearmarked 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 326d592fdcac8d087d1a1d4ed2edb6200a8e736f
4
+ data.tar.gz: 3027d8ae3eae1653a339ec64ee7fbd78e2570e8d
5
+ SHA512:
6
+ metadata.gz: f8d2691d90e96a8d691d5a742068542f2bc21ecb4e4b506ca9c2997be486c05967c4d4db67edda424c743969a8b9755079f7f80feb4b61352b642a15af18fc3f
7
+ data.tar.gz: 4ea99a365d7e4ad3b5385c8c3090944edad3d5f0847d0ec005d34c683d4a098cd7026759592e65659aa684d1dc61938b74d30d2c09099b9f186c75e349aa20d6
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.14.5
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at jgaskins@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in clearmarked.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Jamie Gaskins
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ # Clearmarked
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/clearmarked`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'clearmarked'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install clearmarked
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/clearmarked. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "clearmarked"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'clearmarked/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "clearmarked"
8
+ spec.version = Clearmarked::VERSION
9
+ spec.authors = ["Jamie Gaskins"]
10
+ spec.email = ["jgaskins@gmail.com"]
11
+
12
+ spec.summary = %q{Convert markdown into Clearwater components}
13
+ spec.homepage = "https://github.com/clearwater-rb/clearmarked"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_runtime_dependency "clearwater"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.14"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ end
@@ -0,0 +1,6 @@
1
+ require "clearmarked/version"
2
+
3
+ module Clearmarked
4
+ end
5
+
6
+ Opal.append_path File.expand_path '../../opal', __FILE__
@@ -0,0 +1,3 @@
1
+ module Clearmarked
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,108 @@
1
+ require 'clearwater/component'
2
+
3
+ require 'clearmarked/js/marked'
4
+
5
+ module Clearmarked
6
+ module_function
7
+
8
+ def call string
9
+ Clearwater::Component.div({ class_name: 'markdown' }, native.call(string))
10
+ end
11
+
12
+ def native
13
+ @native ||= build_native
14
+ end
15
+
16
+ def build_native
17
+ md = `marked`
18
+
19
+ %x{
20
+ marked.setOptions({
21
+ renderer: #{Renderer.new},
22
+ });
23
+ }
24
+
25
+ md
26
+ end
27
+
28
+ class Renderer
29
+ include Clearwater::Component
30
+
31
+ def initialize
32
+ # Block elements
33
+ @heading = proc do |text, level|
34
+ id = text_for(text)
35
+ tag("h#{level}", { id: id }, text)
36
+ end
37
+ @code = proc { |code, lang| pre(code({ lang: lang }, code)) }
38
+ @list = proc { |content, ordered| tag(ordered ? :ol : :ul, nil, content) }
39
+ @listitem = proc { |content| li(content) }
40
+ @text = proc { |text| text }
41
+ @blockquote = proc { |text| blockquote(text) }
42
+ @html = proc { |html| div(innerHTML: html) }
43
+ @hr = proc { hr }
44
+ @paragraph = proc { |content| p content }
45
+ @table = proc do |header, body|
46
+ table([
47
+ thead(header),
48
+ tbody(body),
49
+ ])
50
+ end
51
+ @tablerow = proc { |cells| tr(cells) }
52
+ @tablecell = proc do |content, flags={}|
53
+ flags = Hash.new(flags) # Convert from JS object
54
+ tag_type = flags[:header] ? :th : :td
55
+ properties = {
56
+ style: {
57
+ text_align: flags[:align],
58
+ }
59
+ }
60
+
61
+ tag(tag_type, properties, content)
62
+ end
63
+
64
+ # Inline elements
65
+ @em = proc { |text| em text }
66
+ @strong = proc { |text| strong text }
67
+ @codespan = proc { |code| code code }
68
+ @br = proc { br }
69
+ @del = proc { |text| del text }
70
+ @link = proc do |href, title, text|
71
+ properties = { href: href, title: title }
72
+ .select { |_, v| v }
73
+
74
+ if href =~ %r{^(https?:)?//}
75
+ a(properties, text)
76
+ else
77
+ Link.new(properties, text)
78
+ end
79
+ end
80
+ @image = proc do |src, title, alt|
81
+ img({ src: src, title: title, alt: alt }
82
+ .select { |_, v| v })
83
+ end
84
+ end
85
+
86
+ def text_for text
87
+ case `typeof #{text}`
88
+ when :string, :number
89
+ text.to_s
90
+ when :object
91
+ if `!!#{text}.$$class`
92
+ case text
93
+ when Array
94
+ text.map { |t| text_for t }.join
95
+ else
96
+ text.to_s
97
+ end
98
+ elsif `!!#{text}.children`
99
+ text_for `#{text}.children`
100
+ elsif `!!#{text}.text`
101
+ text_for `#{text}.text`
102
+ elsif `#{text} instanceof Array`
103
+ text.map { |t| text_for t }.join
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,1136 @@
1
+ /**
2
+ * marked - a markdown parser
3
+ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
4
+ * https://github.com/chjj/marked
5
+ */
6
+
7
+ ;(function() {
8
+
9
+ /**
10
+ * Block-Level Grammar
11
+ */
12
+
13
+ var block = {
14
+ newline: /^\n+/,
15
+ code: /^( {4}[^\n]+\n*)+/,
16
+ fences: noop,
17
+ hr: /^( *[-*_]){3,} *(?:\n+|$)/,
18
+ heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
19
+ nptable: noop,
20
+ lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
21
+ blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
22
+ list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
23
+ html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
24
+ def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
25
+ table: noop,
26
+ paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
27
+ text: /^[^\n]+/
28
+ };
29
+
30
+ block.bullet = /(?:[*+-]|\d+\.)/;
31
+ block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
32
+ block.item = replace(block.item, 'gm')
33
+ (/bull/g, block.bullet)
34
+ ();
35
+
36
+ block.list = replace(block.list)
37
+ (/bull/g, block.bullet)
38
+ ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
39
+ ('def', '\\n+(?=' + block.def.source + ')')
40
+ ();
41
+
42
+ block.blockquote = replace(block.blockquote)
43
+ ('def', block.def)
44
+ ();
45
+
46
+ block._tag = '(?!(?:'
47
+ + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
48
+ + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
49
+ + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
50
+
51
+ block.html = replace(block.html)
52
+ ('comment', /<!--[\s\S]*?-->/)
53
+ ('closed', /<(tag)[\s\S]+?<\/\1>/)
54
+ ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
55
+ (/tag/g, block._tag)
56
+ ();
57
+
58
+ block.paragraph = replace(block.paragraph)
59
+ ('hr', block.hr)
60
+ ('heading', block.heading)
61
+ ('lheading', block.lheading)
62
+ ('blockquote', block.blockquote)
63
+ ('tag', '<' + block._tag)
64
+ ('def', block.def)
65
+ ();
66
+
67
+ /**
68
+ * Normal Block Grammar
69
+ */
70
+
71
+ block.normal = merge({}, block);
72
+
73
+ /**
74
+ * GFM Block Grammar
75
+ */
76
+
77
+ block.gfm = merge({}, block.normal, {
78
+ fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
79
+ paragraph: /^/,
80
+ heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
81
+ });
82
+
83
+ block.gfm.paragraph = replace(block.paragraph)
84
+ ('(?!', '(?!'
85
+ + block.gfm.fences.source.replace('\\1', '\\2') + '|'
86
+ + block.list.source.replace('\\1', '\\3') + '|')
87
+ ();
88
+
89
+ /**
90
+ * GFM + Tables Block Grammar
91
+ */
92
+
93
+ block.tables = merge({}, block.gfm, {
94
+ nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
95
+ table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
96
+ });
97
+
98
+ /**
99
+ * Block Lexer
100
+ */
101
+
102
+ function Lexer(options) {
103
+ this.tokens = [];
104
+ this.tokens.links = {};
105
+ this.options = options || marked.defaults;
106
+ this.rules = block.normal;
107
+
108
+ if (this.options.gfm) {
109
+ if (this.options.tables) {
110
+ this.rules = block.tables;
111
+ } else {
112
+ this.rules = block.gfm;
113
+ }
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Expose Block Rules
119
+ */
120
+
121
+ Lexer.rules = block;
122
+
123
+ /**
124
+ * Static Lex Method
125
+ */
126
+
127
+ Lexer.lex = function(src, options) {
128
+ var lexer = new Lexer(options);
129
+ return lexer.lex(src);
130
+ };
131
+
132
+ /**
133
+ * Preprocessing
134
+ */
135
+
136
+ Lexer.prototype.lex = function(src) {
137
+ src = src
138
+ .replace(/\r\n|\r/g, '\n')
139
+ .replace(/\t/g, ' ')
140
+ .replace(/\u00a0/g, ' ')
141
+ .replace(/\u2424/g, '\n');
142
+
143
+ return this.token(src, true);
144
+ };
145
+
146
+ /**
147
+ * Lexing
148
+ */
149
+
150
+ Lexer.prototype.token = function(src, top, bq) {
151
+ var src = src.replace(/^ +$/gm, '')
152
+ , next
153
+ , loose
154
+ , cap
155
+ , bull
156
+ , b
157
+ , item
158
+ , space
159
+ , i
160
+ , l;
161
+
162
+ while (src) {
163
+ // newline
164
+ if (cap = this.rules.newline.exec(src)) {
165
+ src = src.substring(cap[0].length);
166
+ if (cap[0].length > 1) {
167
+ this.tokens.push({
168
+ type: 'space'
169
+ });
170
+ }
171
+ }
172
+
173
+ // code
174
+ if (cap = this.rules.code.exec(src)) {
175
+ src = src.substring(cap[0].length);
176
+ cap = cap[0].replace(/^ {4}/gm, '');
177
+ this.tokens.push({
178
+ type: 'code',
179
+ text: !this.options.pedantic
180
+ ? cap.replace(/\n+$/, '')
181
+ : cap
182
+ });
183
+ continue;
184
+ }
185
+
186
+ // fences (gfm)
187
+ if (cap = this.rules.fences.exec(src)) {
188
+ src = src.substring(cap[0].length);
189
+ this.tokens.push({
190
+ type: 'code',
191
+ lang: cap[2],
192
+ text: cap[3] || ''
193
+ });
194
+ continue;
195
+ }
196
+
197
+ // heading
198
+ if (cap = this.rules.heading.exec(src)) {
199
+ src = src.substring(cap[0].length);
200
+ this.tokens.push({
201
+ type: 'heading',
202
+ depth: cap[1].length,
203
+ text: cap[2]
204
+ });
205
+ continue;
206
+ }
207
+
208
+ // table no leading pipe (gfm)
209
+ if (top && (cap = this.rules.nptable.exec(src))) {
210
+ src = src.substring(cap[0].length);
211
+
212
+ item = {
213
+ type: 'table',
214
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
215
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
216
+ cells: cap[3].replace(/\n$/, '').split('\n')
217
+ };
218
+
219
+ for (i = 0; i < item.align.length; i++) {
220
+ if (/^ *-+: *$/.test(item.align[i])) {
221
+ item.align[i] = 'right';
222
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
223
+ item.align[i] = 'center';
224
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
225
+ item.align[i] = 'left';
226
+ } else {
227
+ item.align[i] = null;
228
+ }
229
+ }
230
+
231
+ for (i = 0; i < item.cells.length; i++) {
232
+ item.cells[i] = item.cells[i].split(/ *\| */);
233
+ }
234
+
235
+ this.tokens.push(item);
236
+
237
+ continue;
238
+ }
239
+
240
+ // lheading
241
+ if (cap = this.rules.lheading.exec(src)) {
242
+ src = src.substring(cap[0].length);
243
+ this.tokens.push({
244
+ type: 'heading',
245
+ depth: cap[2] === '=' ? 1 : 2,
246
+ text: cap[1]
247
+ });
248
+ continue;
249
+ }
250
+
251
+ // hr
252
+ if (cap = this.rules.hr.exec(src)) {
253
+ src = src.substring(cap[0].length);
254
+ this.tokens.push({
255
+ type: 'hr'
256
+ });
257
+ continue;
258
+ }
259
+
260
+ // blockquote
261
+ if (cap = this.rules.blockquote.exec(src)) {
262
+ src = src.substring(cap[0].length);
263
+
264
+ this.tokens.push({
265
+ type: 'blockquote_start'
266
+ });
267
+
268
+ cap = cap[0].replace(/^ *> ?/gm, '');
269
+
270
+ // Pass `top` to keep the current
271
+ // "toplevel" state. This is exactly
272
+ // how markdown.pl works.
273
+ this.token(cap, top, true);
274
+
275
+ this.tokens.push({
276
+ type: 'blockquote_end'
277
+ });
278
+
279
+ continue;
280
+ }
281
+
282
+ // list
283
+ if (cap = this.rules.list.exec(src)) {
284
+ src = src.substring(cap[0].length);
285
+ bull = cap[2];
286
+
287
+ this.tokens.push({
288
+ type: 'list_start',
289
+ ordered: bull.length > 1
290
+ });
291
+
292
+ // Get each top-level item.
293
+ cap = cap[0].match(this.rules.item);
294
+
295
+ next = false;
296
+ l = cap.length;
297
+ i = 0;
298
+
299
+ for (; i < l; i++) {
300
+ item = cap[i];
301
+
302
+ // Remove the list item's bullet
303
+ // so it is seen as the next token.
304
+ space = item.length;
305
+ item = item.replace(/^ *([*+-]|\d+\.) +/, '');
306
+
307
+ // Outdent whatever the
308
+ // list item contains. Hacky.
309
+ if (~item.indexOf('\n ')) {
310
+ space -= item.length;
311
+ item = !this.options.pedantic
312
+ ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
313
+ : item.replace(/^ {1,4}/gm, '');
314
+ }
315
+
316
+ // Determine whether the next list item belongs here.
317
+ // Backpedal if it does not belong in this list.
318
+ if (this.options.smartLists && i !== l - 1) {
319
+ b = block.bullet.exec(cap[i + 1])[0];
320
+ if (bull !== b && !(bull.length > 1 && b.length > 1)) {
321
+ src = cap.slice(i + 1).join('\n') + src;
322
+ i = l - 1;
323
+ }
324
+ }
325
+
326
+ // Determine whether item is loose or not.
327
+ // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
328
+ // for discount behavior.
329
+ loose = next || /\n\n(?!\s*$)/.test(item);
330
+ if (i !== l - 1) {
331
+ next = item.charAt(item.length - 1) === '\n';
332
+ if (!loose) loose = next;
333
+ }
334
+
335
+ this.tokens.push({
336
+ type: loose
337
+ ? 'loose_item_start'
338
+ : 'list_item_start'
339
+ });
340
+
341
+ // Recurse.
342
+ this.token(item, false, bq);
343
+
344
+ this.tokens.push({
345
+ type: 'list_item_end'
346
+ });
347
+ }
348
+
349
+ this.tokens.push({
350
+ type: 'list_end'
351
+ });
352
+
353
+ continue;
354
+ }
355
+
356
+ // html
357
+ if (cap = this.rules.html.exec(src)) {
358
+ src = src.substring(cap[0].length);
359
+ this.tokens.push({
360
+ type: this.options.sanitize
361
+ ? 'paragraph'
362
+ : 'html',
363
+ pre: !this.options.sanitizer
364
+ && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
365
+ text: cap[0]
366
+ });
367
+ continue;
368
+ }
369
+
370
+ // def
371
+ if ((!bq && top) && (cap = this.rules.def.exec(src))) {
372
+ src = src.substring(cap[0].length);
373
+ this.tokens.links[cap[1].toLowerCase()] = {
374
+ href: cap[2],
375
+ title: cap[3]
376
+ };
377
+ continue;
378
+ }
379
+
380
+ // table (gfm)
381
+ if (top && (cap = this.rules.table.exec(src))) {
382
+ src = src.substring(cap[0].length);
383
+
384
+ item = {
385
+ type: 'table',
386
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
387
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
388
+ cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
389
+ };
390
+
391
+ for (i = 0; i < item.align.length; i++) {
392
+ if (/^ *-+: *$/.test(item.align[i])) {
393
+ item.align[i] = 'right';
394
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
395
+ item.align[i] = 'center';
396
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
397
+ item.align[i] = 'left';
398
+ } else {
399
+ item.align[i] = null;
400
+ }
401
+ }
402
+
403
+ for (i = 0; i < item.cells.length; i++) {
404
+ item.cells[i] = item.cells[i]
405
+ .replace(/^ *\| *| *\| *$/g, '')
406
+ .split(/ *\| */);
407
+ }
408
+
409
+ this.tokens.push(item);
410
+
411
+ continue;
412
+ }
413
+
414
+ // top-level paragraph
415
+ if (top && (cap = this.rules.paragraph.exec(src))) {
416
+ src = src.substring(cap[0].length);
417
+ this.tokens.push({
418
+ type: 'paragraph',
419
+ text: cap[1].charAt(cap[1].length - 1) === '\n'
420
+ ? cap[1].slice(0, -1)
421
+ : cap[1]
422
+ });
423
+ continue;
424
+ }
425
+
426
+ // text
427
+ if (cap = this.rules.text.exec(src)) {
428
+ // Top-level should never reach here.
429
+ src = src.substring(cap[0].length);
430
+ this.tokens.push({
431
+ type: 'text',
432
+ text: cap[0]
433
+ });
434
+ continue;
435
+ }
436
+
437
+ if (src) {
438
+ throw new
439
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
440
+ }
441
+ }
442
+
443
+ return this.tokens;
444
+ };
445
+
446
+ /**
447
+ * Inline-Level Grammar
448
+ */
449
+
450
+ var inline = {
451
+ escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
452
+ autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
453
+ url: noop,
454
+ tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
455
+ link: /^!?\[(inside)\]\(href\)/,
456
+ reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
457
+ nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
458
+ strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
459
+ em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
460
+ code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
461
+ br: /^ {2,}\n(?!\s*$)/,
462
+ del: noop,
463
+ text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
464
+ };
465
+
466
+ inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
467
+ inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
468
+
469
+ inline.link = replace(inline.link)
470
+ ('inside', inline._inside)
471
+ ('href', inline._href)
472
+ ();
473
+
474
+ inline.reflink = replace(inline.reflink)
475
+ ('inside', inline._inside)
476
+ ();
477
+
478
+ /**
479
+ * Normal Inline Grammar
480
+ */
481
+
482
+ inline.normal = merge({}, inline);
483
+
484
+ /**
485
+ * Pedantic Inline Grammar
486
+ */
487
+
488
+ inline.pedantic = merge({}, inline.normal, {
489
+ strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
490
+ em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
491
+ });
492
+
493
+ /**
494
+ * GFM Inline Grammar
495
+ */
496
+
497
+ inline.gfm = merge({}, inline.normal, {
498
+ escape: replace(inline.escape)('])', '~|])')(),
499
+ url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
500
+ del: /^~~(?=\S)([\s\S]*?\S)~~/,
501
+ text: replace(inline.text)
502
+ (']|', '~]|')
503
+ ('|', '|https?://|')
504
+ ()
505
+ });
506
+
507
+ /**
508
+ * GFM + Line Breaks Inline Grammar
509
+ */
510
+
511
+ inline.breaks = merge({}, inline.gfm, {
512
+ br: replace(inline.br)('{2,}', '*')(),
513
+ text: replace(inline.gfm.text)('{2,}', '*')()
514
+ });
515
+
516
+ /**
517
+ * Inline Lexer & Compiler
518
+ */
519
+
520
+ function InlineLexer(links, options) {
521
+ this.options = options || marked.defaults;
522
+ this.links = links;
523
+ this.rules = inline.normal;
524
+ this.renderer = this.options.renderer;
525
+ this.renderer.options = this.options;
526
+
527
+ if (!this.links) {
528
+ throw new
529
+ Error('Tokens array requires a `links` property.');
530
+ }
531
+
532
+ if (this.options.gfm) {
533
+ if (this.options.breaks) {
534
+ this.rules = inline.breaks;
535
+ } else {
536
+ this.rules = inline.gfm;
537
+ }
538
+ } else if (this.options.pedantic) {
539
+ this.rules = inline.pedantic;
540
+ }
541
+ }
542
+
543
+ /**
544
+ * Expose Inline Rules
545
+ */
546
+
547
+ InlineLexer.rules = inline;
548
+
549
+ /**
550
+ * Static Lexing/Compiling Method
551
+ */
552
+
553
+ InlineLexer.output = function(src, links, options) {
554
+ var inline = new InlineLexer(links, options);
555
+ return inline.output(src);
556
+ };
557
+
558
+ /**
559
+ * Lexing/Compiling
560
+ */
561
+
562
+ InlineLexer.prototype.output = function(src) {
563
+ var out = []
564
+ , link
565
+ , text
566
+ , href
567
+ , cap;
568
+
569
+ if(src instanceof Array) { src = src.join() }
570
+
571
+ while (src) {
572
+ // escape
573
+ if (cap = this.rules.escape.exec(src)) {
574
+ src = src.substring(cap[0].length);
575
+ out.push(cap[1]);
576
+ continue;
577
+ }
578
+
579
+ // autolink
580
+ if (cap = this.rules.autolink.exec(src)) {
581
+ src = src.substring(cap[0].length);
582
+ if (cap[2] === '@') {
583
+ text = cap[1].charAt(6) === ':'
584
+ ? this.mangle(cap[1].substring(7))
585
+ : this.mangle(cap[1]);
586
+ href = this.mangle('mailto:') + text;
587
+ } else {
588
+ text = escape(cap[1]);
589
+ href = text;
590
+ }
591
+ out.push(this.renderer.link(href, null, text));
592
+ continue;
593
+ }
594
+
595
+ // url (gfm)
596
+ if (!this.inLink && (cap = this.rules.url.exec(src))) {
597
+ src = src.substring(cap[0].length);
598
+ text = escape(cap[1]);
599
+ href = text;
600
+ out.push(this.renderer.link(href, null, text));
601
+ continue;
602
+ }
603
+
604
+ // tag
605
+ if (cap = this.rules.tag.exec(src)) {
606
+ if (!this.inLink && /^<a /i.test(cap[0])) {
607
+ this.inLink = true;
608
+ } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
609
+ this.inLink = false;
610
+ }
611
+ src = src.substring(cap[0].length);
612
+ out.push(this.options.sanitize
613
+ ? this.options.sanitizer
614
+ ? this.options.sanitizer(cap[0])
615
+ : escape(cap[0])
616
+ : cap[0])
617
+ continue;
618
+ }
619
+
620
+ // link
621
+ if (cap = this.rules.link.exec(src)) {
622
+ src = src.substring(cap[0].length);
623
+ this.inLink = true;
624
+ out.push(this.outputLink(cap, {
625
+ href: cap[2],
626
+ title: cap[3]
627
+ }));
628
+ this.inLink = false;
629
+ continue;
630
+ }
631
+
632
+ // reflink, nolink
633
+ if ((cap = this.rules.reflink.exec(src))
634
+ || (cap = this.rules.nolink.exec(src))) {
635
+ src = src.substring(cap[0].length);
636
+ link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
637
+ link = this.links[link.toLowerCase()];
638
+ if (!link || !link.href) {
639
+ out.push(cap[0].charAt(0));
640
+ src = cap[0].substring(1) + src;
641
+ continue;
642
+ }
643
+ this.inLink = true;
644
+ out.push(this.outputLink(cap, link));
645
+ this.inLink = false;
646
+ continue;
647
+ }
648
+
649
+ // strong
650
+ if (cap = this.rules.strong.exec(src)) {
651
+ src = src.substring(cap[0].length);
652
+ out.push(this.renderer.strong(this.output(cap[2] || cap[1])));
653
+ continue;
654
+ }
655
+
656
+ // em
657
+ if (cap = this.rules.em.exec(src)) {
658
+ src = src.substring(cap[0].length);
659
+ out.push(this.renderer.em(this.output(cap[2] || cap[1])));
660
+ continue;
661
+ }
662
+
663
+ // code
664
+ if (cap = this.rules.code.exec(src)) {
665
+ src = src.substring(cap[0].length);
666
+ out.push(this.renderer.codespan(escape(cap[2], true)));
667
+ continue;
668
+ }
669
+
670
+ // br
671
+ if (cap = this.rules.br.exec(src)) {
672
+ src = src.substring(cap[0].length);
673
+ out.push(this.renderer.br());
674
+ continue;
675
+ }
676
+
677
+ // del (gfm)
678
+ if (cap = this.rules.del.exec(src)) {
679
+ src = src.substring(cap[0].length);
680
+ out.push(this.renderer.del(this.output(cap[1])));
681
+ continue;
682
+ }
683
+
684
+ // text
685
+ if (cap = this.rules.text.exec(src)) {
686
+ src = src.substring(cap[0].length);
687
+ out.push(this.renderer.text(escape(this.smartypants(cap[0]))));
688
+ continue;
689
+ }
690
+
691
+ if (src) {
692
+ throw new
693
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
694
+ }
695
+ }
696
+
697
+ return out;
698
+ };
699
+
700
+ /**
701
+ * Compile Link
702
+ */
703
+
704
+ InlineLexer.prototype.outputLink = function(cap, link) {
705
+ var href = escape(link.href)
706
+ , title = link.title ? escape(link.title) : null;
707
+
708
+ return cap[0].charAt(0) !== '!'
709
+ ? this.renderer.link(href, title, this.output(cap[1]))
710
+ : this.renderer.image(href, title, escape(cap[1]));
711
+ };
712
+
713
+ /**
714
+ * Smartypants Transformations
715
+ */
716
+
717
+ InlineLexer.prototype.smartypants = function(text) {
718
+ if (!this.options.smartypants) return text;
719
+ return text
720
+ // em-dashes
721
+ .replace(/---/g, '\u2014')
722
+ // en-dashes
723
+ .replace(/--/g, '\u2013')
724
+ // opening singles
725
+ .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
726
+ // closing singles & apostrophes
727
+ .replace(/'/g, '\u2019')
728
+ // opening doubles
729
+ .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
730
+ // closing doubles
731
+ .replace(/"/g, '\u201d')
732
+ // ellipses
733
+ .replace(/\.{3}/g, '\u2026');
734
+ };
735
+
736
+ /**
737
+ * Mangle Links
738
+ */
739
+
740
+ InlineLexer.prototype.mangle = function(text) {
741
+ if (!this.options.mangle) return text;
742
+ var out = ''
743
+ , l = text.length
744
+ , i = 0
745
+ , ch;
746
+
747
+ for (; i < l; i++) {
748
+ ch = text.charCodeAt(i);
749
+ if (Math.random() > 0.5) {
750
+ ch = 'x' + ch.toString(16);
751
+ }
752
+ out += '&#' + ch + ';';
753
+ }
754
+
755
+ return out;
756
+ };
757
+
758
+ /**
759
+ * Parsing & Compiling
760
+ */
761
+
762
+ function Parser(options) {
763
+ this.tokens = [];
764
+ this.token = null;
765
+ this.options = options || marked.defaults;
766
+ this.options.renderer = this.options.renderer;
767
+ this.renderer = this.options.renderer;
768
+ this.renderer.options = this.options;
769
+ }
770
+
771
+ /**
772
+ * Static Parse Method
773
+ */
774
+
775
+ Parser.parse = function(src, options, renderer) {
776
+ var parser = new Parser(options, renderer);
777
+ return parser.parse(src);
778
+ };
779
+
780
+ /**
781
+ * Parse Loop
782
+ */
783
+
784
+ Parser.prototype.parse = function(src) {
785
+ this.inline = new InlineLexer(src.links, this.options, this.renderer);
786
+ this.tokens = src.reverse();
787
+
788
+ var out = [];
789
+ while (this.next()) {
790
+ out.push(this.tok());
791
+ }
792
+
793
+ return out;
794
+ };
795
+
796
+ /**
797
+ * Next Token
798
+ */
799
+
800
+ Parser.prototype.next = function() {
801
+ return this.token = this.tokens.pop();
802
+ };
803
+
804
+ /**
805
+ * Preview Next Token
806
+ */
807
+
808
+ Parser.prototype.peek = function() {
809
+ return this.tokens[this.tokens.length - 1] || 0;
810
+ };
811
+
812
+ /**
813
+ * Parse Text Tokens
814
+ */
815
+
816
+ Parser.prototype.parseText = function() {
817
+ var body = [this.token.text];
818
+
819
+ while (this.peek().type === 'text') {
820
+ body.push('\n' + this.next().text);
821
+ }
822
+
823
+ return this.inline.output(body);
824
+ };
825
+
826
+ /**
827
+ * Parse Current Token
828
+ */
829
+
830
+ Parser.prototype.tok = function() {
831
+ switch (this.token.type) {
832
+ case 'space': {
833
+ return '';
834
+ }
835
+ case 'hr': {
836
+ return this.renderer.hr();
837
+ }
838
+ case 'heading': {
839
+ return this.renderer.heading(
840
+ this.inline.output(this.token.text),
841
+ this.token.depth,
842
+ this.token.text);
843
+ }
844
+ case 'code': {
845
+ return this.renderer.code(this.token.text,
846
+ this.token.lang,
847
+ this.token.escaped);
848
+ }
849
+ case 'table': {
850
+ var header = []
851
+ , body = []
852
+ , i
853
+ , row
854
+ , cell
855
+ , flags
856
+ , j;
857
+
858
+ // header
859
+ cell = [];
860
+ for (i = 0; i < this.token.header.length; i++) {
861
+ flags = { header: true, align: this.token.align[i] };
862
+ cell.push(this.renderer.tablecell(
863
+ this.inline.output(this.token.header[i]),
864
+ { header: true, align: this.token.align[i] }
865
+ ));
866
+ }
867
+ header.push(this.renderer.tablerow(cell));
868
+
869
+ for (i = 0; i < this.token.cells.length; i++) {
870
+ row = this.token.cells[i];
871
+
872
+ cell = [];
873
+ for (j = 0; j < row.length; j++) {
874
+ cell.push(this.renderer.tablecell(
875
+ this.inline.output(row[j]),
876
+ { header: false, align: this.token.align[j] }
877
+ ));
878
+ }
879
+
880
+ body.push(this.renderer.tablerow(cell));
881
+ }
882
+ return this.renderer.table(header, body);
883
+ }
884
+ case 'blockquote_start': {
885
+ var body = [];
886
+
887
+ while (this.next().type !== 'blockquote_end') {
888
+ body.push(this.tok());
889
+ }
890
+
891
+ return this.renderer.blockquote(body);
892
+ }
893
+ case 'list_start': {
894
+ var body = []
895
+ , ordered = this.token.ordered;
896
+
897
+ while (this.next().type !== 'list_end') {
898
+ body.push(this.tok());
899
+ }
900
+
901
+ return this.renderer.list(body, ordered);
902
+ }
903
+ case 'list_item_start': {
904
+ var body = [];
905
+
906
+ while (this.next().type !== 'list_item_end') {
907
+ body.push(this.token.type === 'text'
908
+ ? this.parseText()
909
+ : this.tok());
910
+ }
911
+
912
+ return this.renderer.listitem(body);
913
+ }
914
+ case 'loose_item_start': {
915
+ var body = [];
916
+
917
+ while (this.next().type !== 'list_item_end') {
918
+ body.push(this.tok());
919
+ }
920
+
921
+ return this.renderer.listitem(body);
922
+ }
923
+ case 'html': {
924
+ var html = !this.token.pre && !this.options.pedantic
925
+ ? this.inline.output(this.token.text)
926
+ : this.token.text;
927
+ return this.renderer.html(html);
928
+ }
929
+ case 'paragraph': {
930
+ return this.renderer.paragraph(this.inline.output(this.token.text));
931
+ }
932
+ case 'text': {
933
+ return this.renderer.paragraph(this.parseText());
934
+ }
935
+ }
936
+ };
937
+
938
+ /**
939
+ * Helpers
940
+ */
941
+
942
+ // No-op for now. The virtual-DOM engine doesn't require escaping anything
943
+ // because it never invokes the parser.
944
+ function escape(html, encode) {
945
+ return html
946
+ }
947
+
948
+ function unescape(html) {
949
+ // explicitly match decimal, hex, and named HTML entities
950
+ return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) {
951
+ n = n.toLowerCase();
952
+ if (n === 'colon') return ':';
953
+ if (n.charAt(0) === '#') {
954
+ return n.charAt(1) === 'x'
955
+ ? String.fromCharCode(parseInt(n.substring(2), 16))
956
+ : String.fromCharCode(+n.substring(1));
957
+ }
958
+ return '';
959
+ });
960
+ }
961
+
962
+ function replace(regex, opt) {
963
+ regex = regex.source;
964
+ opt = opt || '';
965
+ return function self(name, val) {
966
+ if (!name) return new RegExp(regex, opt);
967
+ val = val.source || val;
968
+ val = val.replace(/(^|[^\[])\^/g, '$1');
969
+ regex = regex.replace(name, val);
970
+ return self;
971
+ };
972
+ }
973
+
974
+ function noop() {}
975
+ noop.exec = noop;
976
+
977
+ function merge(obj) {
978
+ var i = 1
979
+ , target
980
+ , key;
981
+
982
+ for (; i < arguments.length; i++) {
983
+ target = arguments[i];
984
+ for (key in target) {
985
+ if (Object.prototype.hasOwnProperty.call(target, key)) {
986
+ obj[key] = target[key];
987
+ }
988
+ }
989
+ }
990
+
991
+ return obj;
992
+ }
993
+
994
+
995
+ /**
996
+ * Marked
997
+ */
998
+
999
+ function marked(src, opt, callback) {
1000
+ if (callback || typeof opt === 'function') {
1001
+ if (!callback) {
1002
+ callback = opt;
1003
+ opt = null;
1004
+ }
1005
+
1006
+ opt = merge({}, marked.defaults, opt || {});
1007
+
1008
+ var highlight = opt.highlight
1009
+ , tokens
1010
+ , pending
1011
+ , i = 0;
1012
+
1013
+ try {
1014
+ tokens = Lexer.lex(src, opt)
1015
+ } catch (e) {
1016
+ return callback(e);
1017
+ }
1018
+
1019
+ pending = tokens.length;
1020
+
1021
+ var done = function(err) {
1022
+ if (err) {
1023
+ opt.highlight = highlight;
1024
+ return callback(err);
1025
+ }
1026
+
1027
+ var out;
1028
+
1029
+ try {
1030
+ out = Parser.parse(tokens, opt);
1031
+ } catch (e) {
1032
+ err = e;
1033
+ }
1034
+
1035
+ opt.highlight = highlight;
1036
+
1037
+ return err
1038
+ ? callback(err)
1039
+ : callback(null, out);
1040
+ };
1041
+
1042
+ if (!highlight || highlight.length < 3) {
1043
+ return done();
1044
+ }
1045
+
1046
+ delete opt.highlight;
1047
+
1048
+ if (!pending) return done();
1049
+
1050
+ for (; i < tokens.length; i++) {
1051
+ (function(token) {
1052
+ if (token.type !== 'code') {
1053
+ return --pending || done();
1054
+ }
1055
+ return highlight(token.text, token.lang, function(err, code) {
1056
+ if (err) return done(err);
1057
+ if (code == null || code === token.text) {
1058
+ return --pending || done();
1059
+ }
1060
+ token.text = code;
1061
+ token.escaped = true;
1062
+ --pending || done();
1063
+ });
1064
+ })(tokens[i]);
1065
+ }
1066
+
1067
+ return;
1068
+ }
1069
+ try {
1070
+ if (opt) opt = merge({}, marked.defaults, opt);
1071
+ return Parser.parse(Lexer.lex(src, opt), opt);
1072
+ } catch (e) {
1073
+ e.message += '\nPlease report this to https://github.com/chjj/marked.';
1074
+ if ((opt || marked.defaults).silent) {
1075
+ return '<p>An error occured:</p><pre>'
1076
+ + escape(e.message + '', true)
1077
+ + '</pre>';
1078
+ }
1079
+ throw e;
1080
+ }
1081
+ }
1082
+
1083
+ /**
1084
+ * Options
1085
+ */
1086
+
1087
+ marked.options =
1088
+ marked.setOptions = function(opt) {
1089
+ merge(marked.defaults, opt);
1090
+ return marked;
1091
+ };
1092
+
1093
+ marked.defaults = {
1094
+ gfm: true,
1095
+ tables: true,
1096
+ breaks: false,
1097
+ pedantic: false,
1098
+ sanitize: false,
1099
+ sanitizer: null,
1100
+ mangle: true,
1101
+ smartLists: false,
1102
+ silent: false,
1103
+ highlight: null,
1104
+ langPrefix: 'lang-',
1105
+ smartypants: false,
1106
+ headerPrefix: '',
1107
+ renderer: null,
1108
+ xhtml: false
1109
+ };
1110
+
1111
+ /**
1112
+ * Expose
1113
+ */
1114
+
1115
+ marked.Parser = Parser;
1116
+ marked.parser = Parser.parse;
1117
+
1118
+ marked.Lexer = Lexer;
1119
+ marked.lexer = Lexer.lex;
1120
+
1121
+ marked.InlineLexer = InlineLexer;
1122
+ marked.inlineLexer = InlineLexer.output;
1123
+
1124
+ marked.parse = marked;
1125
+
1126
+ if (typeof module !== 'undefined' && typeof exports === 'object') {
1127
+ module.exports = marked;
1128
+ } else if (typeof define === 'function' && define.amd) {
1129
+ define(function() { return marked; });
1130
+ } else {
1131
+ this.marked = marked;
1132
+ }
1133
+
1134
+ }).call(function() {
1135
+ return this || (typeof window !== 'undefined' ? window : global);
1136
+ }());