qiita_marker 0.23.2.1 → 0.23.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +19 -17
- data/README.md +2 -0
- data/Rakefile +57 -56
- data/bin/qiita_marker +2 -7
- data/ext/qiita_marker/autolink.c +57 -10
- data/ext/qiita_marker/cmark-gfm_version.h +2 -2
- data/ext/qiita_marker/html.c +1 -1
- data/ext/qiita_marker/qfm.h +3 -0
- data/ext/qiita_marker/qfm_custom_block.c +1 -14
- data/ext/qiita_marker/qfm_mention_no_emphasis.c +1 -1
- data/ext/qiita_marker/qiita_marker.c +30 -44
- data/ext/qiita_marker/scanners.c +2438 -2450
- data/ext/qiita_marker/table.c +28 -2
- data/lib/qiita_marker/config.rb +5 -3
- data/lib/qiita_marker/node/inspect.rb +8 -18
- data/lib/qiita_marker/node.rb +6 -6
- data/lib/qiita_marker/renderer/html_renderer.rb +39 -39
- data/lib/qiita_marker/renderer.rb +5 -5
- data/lib/qiita_marker/version.rb +1 -1
- data/lib/qiita_marker.rb +9 -11
- data/qiita_marker.gemspec +27 -29
- metadata +3 -61
- data/test/benchmark.rb +0 -32
- data/test/fixtures/curly.md +0 -1
- data/test/fixtures/dingus.md +0 -10
- data/test/fixtures/strong.md +0 -1
- data/test/fixtures/table.md +0 -10
- data/test/test_attributes.rb +0 -24
- data/test/test_basics.rb +0 -35
- data/test/test_commands.rb +0 -72
- data/test/test_commonmark.rb +0 -36
- data/test/test_doc.rb +0 -130
- data/test/test_encoding.rb +0 -23
- data/test/test_extensions.rb +0 -116
- data/test/test_footnotes.rb +0 -60
- data/test/test_gc.rb +0 -47
- data/test/test_helper.rb +0 -71
- data/test/test_linebreaks.rb +0 -15
- data/test/test_maliciousness.rb +0 -262
- data/test/test_node.rb +0 -89
- data/test/test_options.rb +0 -37
- data/test/test_pathological_inputs.rb +0 -94
- data/test/test_plaintext.rb +0 -46
- data/test/test_qfm_code_data_metadata.rb +0 -26
- data/test/test_qfm_custom_block.rb +0 -23
- data/test/test_qfm_mention_no_emphasis.rb +0 -60
- data/test/test_renderer.rb +0 -47
- data/test/test_smartpunct.rb +0 -27
- data/test/test_spec.rb +0 -30
- data/test/test_tasklists.rb +0 -43
- data/test/test_xml.rb +0 -107
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15bfc4813af77558d6c0b4ffbb931229e00d558d0c417048b636ce7c27ac31a7
|
4
|
+
data.tar.gz: af9febe461508838d294f9d2d20dfe896c30c467b82b50b36924040c7287c070
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2fc608ddea2a044b4c64b9f32e8dbc44cf838213f6c67e9457f36fa303b7223a20c932a261e3f21fac256ceab34d018b9c6d9757ce86eecf250a3aefa585407b
|
7
|
+
data.tar.gz: 66b65a1652e9a0904423490cb8999de85d21928f169f72965ca2b90bc32cfadda46193662ebdae70dea6bcb5819a349256a24911f53c65d168bd9285db107968
|
data/LICENSE.txt
CHANGED
@@ -1,21 +1,23 @@
|
|
1
|
-
|
1
|
+
Copyright (c) 2015 Garen J. Torikian
|
2
|
+
Copyright (c) 2021 Qiita Inc.
|
2
3
|
|
3
|
-
|
4
|
+
MIT License
|
4
5
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
of this software and associated documentation files (the
|
7
|
-
in the Software without restriction, including
|
8
|
-
to use, copy, modify, merge, publish,
|
9
|
-
copies of the Software, and to
|
10
|
-
furnished to do so, subject to
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
11
13
|
|
12
|
-
The above copyright notice and this permission notice shall be
|
13
|
-
copies or substantial portions of the Software.
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
14
16
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
SOFTWARE.
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -20,6 +20,7 @@ In addition to CommonMarker's options and extensions, the following are availabl
|
|
20
20
|
| Name | Description |
|
21
21
|
| --- | --- |
|
22
22
|
| `:MENTION_NO_EMPHASIS` | Prevent parsing mentions as emphasis. |
|
23
|
+
| `:AUTOLINK_CLASS_NAME` | Append `class="autolink"` to extension's autolinks. |
|
23
24
|
|
24
25
|
#### Render options
|
25
26
|
|
@@ -27,6 +28,7 @@ In addition to CommonMarker's options and extensions, the following are availabl
|
|
27
28
|
| --- | --- |
|
28
29
|
| `:CODE_DATA_METADATA` | Use `<code data-metadata>` for fenced code blocks. |
|
29
30
|
| `:MENTION_NO_EMPHASIS` | Prevent parsing mentions as emphasis. |
|
31
|
+
| `:AUTOLINK_CLASS_NAME` | Append `class="autolink"` to extension's autolinks. |
|
30
32
|
|
31
33
|
### Original extensions
|
32
34
|
|
data/Rakefile
CHANGED
@@ -1,113 +1,114 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require "date"
|
4
|
+
require "rake/clean"
|
5
|
+
require "rake/extensiontask"
|
6
|
+
require "digest/md5"
|
7
7
|
|
8
|
-
host_os = RbConfig::CONFIG[
|
9
|
-
require
|
8
|
+
host_os = RbConfig::CONFIG["host_os"]
|
9
|
+
require "devkit" if host_os == "mingw32"
|
10
10
|
|
11
11
|
task default: [:test]
|
12
12
|
|
13
13
|
# Gem Spec
|
14
|
-
gem_spec = Gem::Specification.load(
|
14
|
+
gem_spec = Gem::Specification.load("qiita_marker.gemspec")
|
15
15
|
|
16
16
|
# Ruby Extension
|
17
|
-
Rake::ExtensionTask.new(
|
18
|
-
ext.lib_dir = File.join(
|
17
|
+
Rake::ExtensionTask.new("qiita_marker", gem_spec) do |ext|
|
18
|
+
ext.lib_dir = File.join("lib", "qiita_marker")
|
19
19
|
end
|
20
20
|
|
21
21
|
# Packaging
|
22
|
-
require
|
22
|
+
require "bundler/gem_tasks"
|
23
23
|
|
24
24
|
# Testing
|
25
|
-
require
|
25
|
+
require "rake/testtask"
|
26
26
|
|
27
|
-
Rake::TestTask.new(
|
28
|
-
t.libs <<
|
29
|
-
t.libs <<
|
30
|
-
t.pattern =
|
27
|
+
Rake::TestTask.new("test:unit") do |t|
|
28
|
+
t.libs << "lib"
|
29
|
+
t.libs << "test"
|
30
|
+
t.pattern = "test/test_*.rb"
|
31
31
|
t.verbose = true
|
32
32
|
t.warning = false
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
desc "Run unit tests"
|
36
|
+
task "test:unit" => :compile
|
36
37
|
|
37
|
-
desc
|
38
|
-
task test:
|
38
|
+
desc "Run unit and conformance tests"
|
39
|
+
task test: ["test:unit"]
|
39
40
|
|
40
|
-
require
|
41
|
+
require "rubocop/rake_task"
|
41
42
|
|
42
43
|
RuboCop::RakeTask.new(:rubocop)
|
43
44
|
|
44
|
-
desc
|
45
|
+
desc "Run benchmarks"
|
45
46
|
task :benchmark do
|
46
|
-
if ENV[
|
47
|
-
|
48
|
-
|
49
|
-
langs =
|
47
|
+
if ENV["FETCH_PROGIT"]
|
48
|
+
%x(rm -rf test/progit)
|
49
|
+
%x(git clone https://github.com/progit/progit.git test/progit)
|
50
|
+
langs = ["ar", "az", "be", "ca", "cs", "de", "en", "eo", "es", "es-ni", "fa", "fi", "fr", "hi", "hu", "id", "it", "ja", "ko", "mk", "nl", "no-nb", "pl", "pt-br", "ro", "ru", "sr", "th", "tr", "uk", "vi", "zh", "zh-tw"]
|
50
51
|
langs.each do |lang|
|
51
|
-
|
52
|
+
%x(cat test/progit/#{lang}/*/*.markdown >> test/benchinput.md)
|
52
53
|
end
|
53
54
|
end
|
54
|
-
$LOAD_PATH.unshift
|
55
|
-
load
|
55
|
+
$LOAD_PATH.unshift("lib")
|
56
|
+
load "test/benchmark.rb"
|
56
57
|
end
|
57
58
|
|
58
|
-
desc
|
59
|
+
desc "Match C style of cmark"
|
59
60
|
task :format do
|
60
|
-
sh
|
61
|
+
sh "clang-format -style llvm -i ext/qiita_marker/*.c ext/qiita_marker/*.h"
|
61
62
|
end
|
62
63
|
|
63
64
|
# Documentation
|
64
|
-
require
|
65
|
+
require "rdoc/task"
|
65
66
|
|
66
|
-
desc
|
67
|
+
desc "Generate API documentation"
|
67
68
|
RDoc::Task.new do |rd|
|
68
|
-
rd.rdoc_dir =
|
69
|
-
rd.main =
|
70
|
-
rd.rdoc_files.include
|
71
|
-
|
72
|
-
rd.options <<
|
73
|
-
rd.options <<
|
74
|
-
rd.options <<
|
75
|
-
rd.options <<
|
76
|
-
rd.options <<
|
69
|
+
rd.rdoc_dir = "docs"
|
70
|
+
rd.main = "README.md"
|
71
|
+
rd.rdoc_files.include("README.md", "lib/**/*.rb", "ext/qiita_marker/qiita_marker.c")
|
72
|
+
|
73
|
+
rd.options << "--markup tomdoc"
|
74
|
+
rd.options << "--inline-source"
|
75
|
+
rd.options << "--line-numbers"
|
76
|
+
rd.options << "--all"
|
77
|
+
rd.options << "--fileboxes"
|
77
78
|
end
|
78
79
|
|
79
|
-
desc
|
80
|
+
desc "Generate the documentation and run a web server"
|
80
81
|
task serve: [:rdoc] do
|
81
|
-
require
|
82
|
+
require "webrick"
|
82
83
|
|
83
|
-
puts
|
84
|
+
puts "Navigate to http://localhost:3000 to see the docs"
|
84
85
|
|
85
|
-
server = WEBrick::HTTPServer.new
|
86
|
-
server.mount
|
87
|
-
trap(
|
86
|
+
server = WEBrick::HTTPServer.new(Port: 3000)
|
87
|
+
server.mount("/", WEBrick::HTTPServlet::FileHandler, "docs")
|
88
|
+
trap("INT") { server.stop }
|
88
89
|
server.start
|
89
90
|
end
|
90
91
|
|
91
|
-
desc
|
92
|
+
desc "Generate and publish docs to gh-pages"
|
92
93
|
task publish: [:rdoc] do
|
93
|
-
require
|
94
|
-
require
|
94
|
+
require "tmpdir"
|
95
|
+
require "shellwords"
|
95
96
|
|
96
97
|
Dir.mktmpdir do |tmp|
|
97
98
|
system "mv docs/* #{tmp}"
|
98
|
-
system
|
99
|
-
system
|
99
|
+
system "git checkout origin/gh-pages"
|
100
|
+
system "rm -rf *"
|
100
101
|
system "mv #{tmp}/* ."
|
101
102
|
message = Shellwords.escape("Site updated at #{Time.now.utc}")
|
102
|
-
system
|
103
|
+
system "git add ."
|
103
104
|
system "git commit -am #{message}"
|
104
|
-
system
|
105
|
-
system
|
106
|
-
system
|
105
|
+
system "git push origin gh-pages --force"
|
106
|
+
system "git checkout master"
|
107
|
+
system "echo yolo"
|
107
108
|
end
|
108
109
|
end
|
109
110
|
|
110
111
|
# Custom tasks
|
111
|
-
Dir.glob(
|
112
|
+
Dir.glob("tasks/*.rake").each do |f|
|
112
113
|
load f
|
113
114
|
end
|
data/bin/qiita_marker
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'optparse'
|
5
|
-
require 'ostruct'
|
6
5
|
|
7
6
|
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
8
7
|
require 'qiita_marker'
|
@@ -11,17 +10,13 @@ root = File.expand_path('..', __dir__)
|
|
11
10
|
$LOAD_PATH.unshift File.expand_path('lib', root)
|
12
11
|
|
13
12
|
def parse_options
|
14
|
-
options =
|
13
|
+
options = Struct.new(:active_extensions, :active_parse_options, :active_render_options, :output_format, :renderer)
|
14
|
+
.new([], [:DEFAULT], [:DEFAULT], :html)
|
15
15
|
extensions = QiitaMarker.extensions
|
16
16
|
parse_options = QiitaMarker::Config::OPTS.fetch(:parse)
|
17
17
|
render_options = QiitaMarker::Config::OPTS.fetch(:render)
|
18
18
|
format_options = QiitaMarker::Config::OPTS.fetch(:format)
|
19
19
|
|
20
|
-
options.active_extensions = []
|
21
|
-
options.active_parse_options = [:DEFAULT]
|
22
|
-
options.active_render_options = [:DEFAULT]
|
23
|
-
options.output_format = :html
|
24
|
-
|
25
20
|
option_parser = OptionParser.new do |opts|
|
26
21
|
opts.banner = 'Usage: qiita_marker [--html-renderer] [--extension=EXTENSION]'
|
27
22
|
opts.separator ' [--to=FORMAT]'
|
data/ext/qiita_marker/autolink.c
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
#include "autolink.h"
|
2
|
+
#include "houdini.h"
|
3
|
+
#include "qfm.h"
|
4
|
+
#include "scanners.h"
|
2
5
|
#include <parser.h>
|
6
|
+
#include <render.h>
|
3
7
|
#include <string.h>
|
4
8
|
#include <utf8.h>
|
5
9
|
|
@@ -9,6 +13,11 @@
|
|
9
13
|
#include <strings.h>
|
10
14
|
#endif
|
11
15
|
|
16
|
+
static void escape_html(cmark_strbuf *dest, const unsigned char *source,
|
17
|
+
bufsize_t length) {
|
18
|
+
houdini_escape_html0(dest, source, length, 0);
|
19
|
+
}
|
20
|
+
|
12
21
|
static int is_valid_hostchar(const uint8_t *link, size_t link_len) {
|
13
22
|
int32_t ch;
|
14
23
|
int r = cmark_utf8proc_iterate(link, (bufsize_t)link_len, &ch);
|
@@ -144,7 +153,8 @@ static size_t check_domain(uint8_t *data, size_t size, int allow_short) {
|
|
144
153
|
}
|
145
154
|
|
146
155
|
static cmark_node *www_match(cmark_parser *parser, cmark_node *parent,
|
147
|
-
cmark_inline_parser *inline_parser
|
156
|
+
cmark_inline_parser *inline_parser,
|
157
|
+
cmark_syntax_extension *ext) {
|
148
158
|
cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser);
|
149
159
|
size_t max_rewind = cmark_inline_parser_get_offset(inline_parser);
|
150
160
|
uint8_t *data = chunk->data + max_rewind;
|
@@ -176,6 +186,9 @@ static cmark_node *www_match(cmark_parser *parser, cmark_node *parent,
|
|
176
186
|
cmark_inline_parser_set_offset(inline_parser, (int)(max_rewind + link_end));
|
177
187
|
|
178
188
|
cmark_node *node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);
|
189
|
+
if (parser->options & CMARK_OPT_AUTOLINK_CLASS_NAME) {
|
190
|
+
cmark_node_set_syntax_extension(node, ext);
|
191
|
+
}
|
179
192
|
|
180
193
|
cmark_strbuf buf;
|
181
194
|
cmark_strbuf_init(parser->mem, &buf, 10);
|
@@ -199,7 +212,8 @@ static cmark_node *www_match(cmark_parser *parser, cmark_node *parent,
|
|
199
212
|
}
|
200
213
|
|
201
214
|
static cmark_node *url_match(cmark_parser *parser, cmark_node *parent,
|
202
|
-
cmark_inline_parser *inline_parser
|
215
|
+
cmark_inline_parser *inline_parser,
|
216
|
+
cmark_syntax_extension *ext) {
|
203
217
|
size_t link_end, domain_len;
|
204
218
|
int rewind = 0;
|
205
219
|
|
@@ -237,6 +251,9 @@ static cmark_node *url_match(cmark_parser *parser, cmark_node *parent,
|
|
237
251
|
cmark_node_unput(parent, rewind);
|
238
252
|
|
239
253
|
cmark_node *node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);
|
254
|
+
if (parser->options & CMARK_OPT_AUTOLINK_CLASS_NAME) {
|
255
|
+
cmark_node_set_syntax_extension(node, ext);
|
256
|
+
}
|
240
257
|
|
241
258
|
cmark_chunk url = cmark_chunk_dup(chunk, max_rewind - rewind,
|
242
259
|
(bufsize_t)(link_end + rewind));
|
@@ -257,10 +274,10 @@ static cmark_node *match(cmark_syntax_extension *ext, cmark_parser *parser,
|
|
257
274
|
return NULL;
|
258
275
|
|
259
276
|
if (c == ':')
|
260
|
-
return url_match(parser, parent, inline_parser);
|
277
|
+
return url_match(parser, parent, inline_parser, ext);
|
261
278
|
|
262
279
|
if (c == 'w')
|
263
|
-
return www_match(parser, parent, inline_parser);
|
280
|
+
return www_match(parser, parent, inline_parser, ext);
|
264
281
|
|
265
282
|
return NULL;
|
266
283
|
|
@@ -269,7 +286,8 @@ static cmark_node *match(cmark_syntax_extension *ext, cmark_parser *parser,
|
|
269
286
|
// inline was finished in inlines.c.
|
270
287
|
}
|
271
288
|
|
272
|
-
static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset,
|
289
|
+
static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset,
|
290
|
+
int depth, cmark_syntax_extension *ext) {
|
273
291
|
// postprocess_text can recurse very deeply if there is a very long line of
|
274
292
|
// '@' only. Stop at a reasonable depth to ensure it cannot crash.
|
275
293
|
if (depth > 1000) return;
|
@@ -311,7 +329,7 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset,
|
|
311
329
|
}
|
312
330
|
|
313
331
|
if (rewind == 0 || ns > 0) {
|
314
|
-
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
|
332
|
+
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1, ext);
|
315
333
|
return;
|
316
334
|
}
|
317
335
|
|
@@ -331,20 +349,23 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset,
|
|
331
349
|
|
332
350
|
if (link_end < 2 || nb != 1 || np == 0 ||
|
333
351
|
(!cmark_isalpha(data[link_end - 1]) && data[link_end - 1] != '.')) {
|
334
|
-
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
|
352
|
+
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1, ext);
|
335
353
|
return;
|
336
354
|
}
|
337
355
|
|
338
356
|
link_end = autolink_delim(data, link_end);
|
339
357
|
|
340
358
|
if (link_end == 0) {
|
341
|
-
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
|
359
|
+
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1, ext);
|
342
360
|
return;
|
343
361
|
}
|
344
362
|
|
345
363
|
cmark_chunk_to_cstr(parser->mem, &text->as.literal);
|
346
364
|
|
347
365
|
cmark_node *link_node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);
|
366
|
+
if (parser->options & CMARK_OPT_AUTOLINK_CLASS_NAME) {
|
367
|
+
cmark_node_set_syntax_extension(link_node, ext);
|
368
|
+
}
|
348
369
|
cmark_strbuf buf;
|
349
370
|
cmark_strbuf_init(parser->mem, &buf, 10);
|
350
371
|
cmark_strbuf_puts(&buf, "mailto:");
|
@@ -373,7 +394,7 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset,
|
|
373
394
|
text->as.literal.len = offset + max_rewind - rewind;
|
374
395
|
text->as.literal.data[text->as.literal.len] = 0;
|
375
396
|
|
376
|
-
postprocess_text(parser, post, 0, depth + 1);
|
397
|
+
postprocess_text(parser, post, 0, depth + 1, ext);
|
377
398
|
}
|
378
399
|
|
379
400
|
static cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser, cmark_node *root) {
|
@@ -400,7 +421,7 @@ static cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser
|
|
400
421
|
}
|
401
422
|
|
402
423
|
if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_TEXT) {
|
403
|
-
postprocess_text(parser, node, 0, /*depth*/0);
|
424
|
+
postprocess_text(parser, node, 0, /*depth*/ 0, ext);
|
404
425
|
}
|
405
426
|
}
|
406
427
|
|
@@ -409,12 +430,38 @@ static cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser
|
|
409
430
|
return root;
|
410
431
|
}
|
411
432
|
|
433
|
+
static void html_render(cmark_syntax_extension *extension,
|
434
|
+
cmark_html_renderer *renderer, cmark_node *node,
|
435
|
+
cmark_event_type ev_type, int options) {
|
436
|
+
bool entering = (ev_type == CMARK_EVENT_ENTER);
|
437
|
+
cmark_strbuf *html = renderer->html;
|
438
|
+
|
439
|
+
if (entering) {
|
440
|
+
cmark_strbuf_puts(html, "<a href=\"");
|
441
|
+
if ((options & CMARK_OPT_UNSAFE) ||
|
442
|
+
!(scan_dangerous_url(&node->as.link.url, 0))) {
|
443
|
+
houdini_escape_href(html, node->as.link.url.data, node->as.link.url.len);
|
444
|
+
}
|
445
|
+
if (node->as.link.title.len) {
|
446
|
+
cmark_strbuf_puts(html, "\" title=\"");
|
447
|
+
escape_html(html, node->as.link.title.data, node->as.link.title.len);
|
448
|
+
}
|
449
|
+
if (options & CMARK_OPT_AUTOLINK_CLASS_NAME) {
|
450
|
+
cmark_strbuf_puts(html, "\" class=\"autolink");
|
451
|
+
}
|
452
|
+
cmark_strbuf_puts(html, "\">");
|
453
|
+
} else {
|
454
|
+
cmark_strbuf_puts(html, "</a>");
|
455
|
+
}
|
456
|
+
}
|
457
|
+
|
412
458
|
cmark_syntax_extension *create_autolink_extension(void) {
|
413
459
|
cmark_syntax_extension *ext = cmark_syntax_extension_new("autolink");
|
414
460
|
cmark_llist *special_chars = NULL;
|
415
461
|
|
416
462
|
cmark_syntax_extension_set_match_inline_func(ext, match);
|
417
463
|
cmark_syntax_extension_set_postprocess_func(ext, postprocess);
|
464
|
+
cmark_syntax_extension_set_html_render_func(ext, html_render);
|
418
465
|
|
419
466
|
cmark_mem *mem = cmark_get_default_mem_allocator();
|
420
467
|
special_chars = cmark_llist_append(mem, special_chars, (void *)':');
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#ifndef CMARK_GFM_VERSION_H
|
2
2
|
#define CMARK_GFM_VERSION_H
|
3
3
|
|
4
|
-
#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) |
|
5
|
-
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.
|
4
|
+
#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 4)
|
5
|
+
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.4"
|
6
6
|
|
7
7
|
#endif
|
data/ext/qiita_marker/html.c
CHANGED
@@ -227,7 +227,7 @@ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
|
|
227
227
|
cmark_strbuf_puts(html, "<pre");
|
228
228
|
cmark_html_render_sourcepos(node, html, options);
|
229
229
|
cmark_strbuf_puts(html, "><code data-metadata=\"");
|
230
|
-
escape_html(html, node->as.code.info.data,
|
230
|
+
escape_html(html, node->as.code.info.data, node->as.code.info.len);
|
231
231
|
if (first_tag < node->as.code.info.len &&
|
232
232
|
(options & CMARK_OPT_FULL_INFO_STRING)) {
|
233
233
|
cmark_strbuf_puts(html, "\" data-meta=\"");
|
data/ext/qiita_marker/qfm.h
CHANGED
@@ -12,6 +12,9 @@ extern "C" {
|
|
12
12
|
/* Prevent parsing Qiita-style Mentions as emphasis. */
|
13
13
|
#define CMARK_OPT_MENTION_NO_EMPHASIS (1 << 26)
|
14
14
|
|
15
|
+
/* Render autolinks with class name */
|
16
|
+
#define CMARK_OPT_AUTOLINK_CLASS_NAME (1 << 27)
|
17
|
+
|
15
18
|
#ifdef __cplusplus
|
16
19
|
}
|
17
20
|
#endif
|
@@ -157,20 +157,7 @@ static int can_contain(cmark_syntax_extension *self, cmark_node *node,
|
|
157
157
|
cmark_node_type child_type) {
|
158
158
|
cmark_node_type node_type = cmark_node_get_type(node);
|
159
159
|
|
160
|
-
|
161
|
-
return
|
162
|
-
// Block
|
163
|
-
child_type == CMARK_NODE_LIST || child_type == CMARK_NODE_PARAGRAPH ||
|
164
|
-
// Inline
|
165
|
-
child_type == CMARK_NODE_TEXT || child_type == CMARK_NODE_CODE ||
|
166
|
-
child_type == CMARK_NODE_HTML_INLINE || child_type == CMARK_NODE_EMPH ||
|
167
|
-
child_type == CMARK_NODE_STRONG || child_type == CMARK_NODE_LINK ||
|
168
|
-
child_type == CMARK_NODE_IMAGE ||
|
169
|
-
child_type == CMARK_NODE_FOOTNOTE_REFERENCE ||
|
170
|
-
child_type == CMARK_NODE_STRIKETHROUGH;
|
171
|
-
}
|
172
|
-
|
173
|
-
return 0;
|
160
|
+
return node_type == CMARK_NODE_QFM_CUSTOM_BLOCK;
|
174
161
|
}
|
175
162
|
|
176
163
|
static int contains_inlines(cmark_syntax_extension *self, cmark_node *node) {
|