greenmat 3.5.1.0 → 3.5.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f39bc77cb9919af4e018b008bbc6d1cd8347d7bee919592dbe96d09b8eeab19f
4
- data.tar.gz: c3f07e638dddaa7bd603d0d044a6c847abd425c65aa2106701d1e8ccf4b547ce
3
+ metadata.gz: bb401dc6f336d00057b17f5e59b2c9b99a1d55e3c7949d662aa06e781a8b8284
4
+ data.tar.gz: 0e3acbf68f1ec78bc8b2832a2ed163d350b6576d6f1b7de40b5aafe0b4e00a32
5
5
  SHA512:
6
- metadata.gz: '02870d7ebb28e12b26c38b80363be12db1961fcb0c1e2f2a99d0e95eded8f5c203c8750e95afa2300e08784c17ae3ccc5f73d19ff1ef8c3133cb98bf0eae1f22'
7
- data.tar.gz: 722bb67d5443e75f266881a60a2dd090c4417dd44f1049ebaaf4185c9e4fa5d72232182794ce648a31cb3a33b0315e2ec7b6c4458428567b4c1a9449c6bfabc9
6
+ metadata.gz: 5a64e6ecef30e67ff86c96a1d9a17a7f86ab6282264729952a6b1cb72a3fe7b530a01a5a5b285cd8369998196c9eb3903825d9b5f2c332bcfd2a835750ec5e50
7
+ data.tar.gz: 5cf349212cf416ee2a0bc0dda663297b3166954c4552d5160ce1f9ebeace107cb238e90c3630cdd85f3bd144b7750c2dba1f57b83b8314eedce1d9796072f0f0
@@ -0,0 +1,47 @@
1
+ name: Test
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - master
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ test:
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ os: ['ubuntu-18.04', 'macos-latest']
19
+ ruby: ['2.5', '2.6', '2.7', '3.0', '3.1']
20
+ experimental: [false]
21
+ include:
22
+ - os: 'ubuntu-18.04'
23
+ ruby: 'head'
24
+ experimental: true
25
+ runs-on: ${{ matrix.os }}
26
+ continue-on-error: ${{ matrix.experimental }}
27
+ env:
28
+ BUNDLE_WITHOUT: benchmark
29
+ steps:
30
+ - uses: actions/checkout@v2
31
+ - name: Install prerequirements
32
+ if: runner.os == 'Linux'
33
+ run: |
34
+ sudo apt-get update
35
+ sudo apt-get install tidy
36
+ - uses: ruby/setup-ruby@v1
37
+ with:
38
+ ruby-version: ${{ matrix.ruby }}
39
+ bundler-cache: true
40
+ - name: Build
41
+ run: bundle exec rake compile
42
+ - name: Check prerequirements
43
+ run: |
44
+ tidy --version
45
+ bin/greenmat --version
46
+ - name: Run test
47
+ run: bundle exec rake
data/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## v3.5.1.3
6
+
7
+ * Remove support for ruby 2.5 and below
8
+ * Bump nokogiri from 1.6.0 to 1.11.7
9
+ * Support cpu archtecture for arm64/aarch64 systems (like Apple's M1)
10
+ * Change ci platform to Github Actions
11
+
12
+ ## v3.5.1.2
13
+
14
+ * Support custom block notation.
15
+ * It starts with `:::` and ends with `:::`.
16
+ * Output a `<div data-type="customblock" data-metadata="">` element.
17
+ * Passes the string following `:::` to the `data-metadata` attribute.
18
+
19
+ ## v3.5.1.1
20
+
21
+ * Unsupport details and summary tags.
22
+
5
23
  ## v3.5.1.0
6
24
 
7
25
  * Update base Redcarpet version to 3.5.1.
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ require 'rake/extensiontask'
4
4
  require 'digest/md5'
5
5
 
6
6
  task :default => [:test, :spec]
7
+ task :spec => [:compile]
7
8
 
8
9
  # Gem Spec
9
10
  gem_spec = Gem::Specification.load('greenmat.gemspec')
@@ -34,7 +35,7 @@ task 'test:conformance' => :compile do |t|
34
35
  lib_dir = "#{pwd}/lib"
35
36
 
36
37
  chdir("test/MarkdownTest_#{version}") do
37
- sh "RUBYLIB=#{lib_dir} ./MarkdownTest.pl --script='#{script}' --tidy"
38
+ sh "RUBYLIB=\"$RUBYLIB:#{lib_dir}\" ./MarkdownTest.pl --script='#{script}' --tidy"
38
39
  end
39
40
  end
40
41
 
@@ -48,6 +48,9 @@ static void rb_greenmat_md_flags(VALUE hash, unsigned int *enabled_extensions_p)
48
48
  if (rb_hash_lookup(hash, CSTR2SYM("fenced_code_blocks")) == Qtrue)
49
49
  extensions |= MKDEXT_FENCED_CODE;
50
50
 
51
+ if (rb_hash_lookup(hash, CSTR2SYM("fenced_custom_blocks")) == Qtrue)
52
+ extensions |= MKDEXT_FENCED_CUSTOM;
53
+
51
54
  if (rb_hash_lookup(hash, CSTR2SYM("disable_indented_code_blocks")) == Qtrue)
52
55
  extensions |= MKDEXT_DISABLE_INDENTED_CODE;
53
56
 
@@ -54,6 +54,12 @@ rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, v
54
54
  BLOCK_CALLBACK("block_code", 2, buf2str(text), buf2str(lang));
55
55
  }
56
56
 
57
+ static void
58
+ rndr_blockcustom(struct buf *ob, const struct buf *text, const struct buf *type, void *opaque)
59
+ {
60
+ BLOCK_CALLBACK("block_custom", 2, buf2str(text), buf2str(type));
61
+ }
62
+
57
63
  static void
58
64
  rndr_blockquote(struct buf *ob, const struct buf *text, void *opaque)
59
65
  {
@@ -293,6 +299,7 @@ rndr_link_attributes(struct buf *ob, const struct buf *url, void *opaque)
293
299
 
294
300
  static struct sd_callbacks rb_greenmat_callbacks = {
295
301
  rndr_blockcode,
302
+ rndr_blockcustom,
296
303
  rndr_blockquote,
297
304
  rndr_raw_block,
298
305
  rndr_header,
@@ -331,6 +338,7 @@ static struct sd_callbacks rb_greenmat_callbacks = {
331
338
 
332
339
  static const char *rb_greenmat_method_names[] = {
333
340
  "block_code",
341
+ "block_custom",
334
342
  "block_quote",
335
343
  "block_html",
336
344
  "header",
data/ext/greenmat/html.c CHANGED
@@ -120,6 +120,52 @@ rndr_autolink(struct buf *ob, const struct buf *link, enum mkd_autolink type, vo
120
120
  return 1;
121
121
  }
122
122
 
123
+ static void
124
+ rndr_blockcustom(struct buf *ob, const struct buf *text, const struct buf *type, void *opaque)
125
+ {
126
+ struct html_renderopt *options = opaque;
127
+
128
+ if (ob->size) bufputc(ob, '\n');
129
+
130
+ if (type && type->size) {
131
+ size_t i, cls;
132
+ if (options->flags & HTML_PRETTIFY) {
133
+ BUFPUTSL(ob, "<div data-type=\"customblock prettyprint\" data-metadata=\"");
134
+ cls++;
135
+ } else {
136
+ BUFPUTSL(ob, "<div data-type=\"customblock\" data-metadata=\"");
137
+ }
138
+
139
+ for (i = 0, cls = 0; i < type->size; ++i, ++cls) {
140
+ while (i < type->size && isspace(type->data[i]))
141
+ i++;
142
+
143
+ if (i < type->size) {
144
+ size_t org = i;
145
+ while (i < type->size && is_non_space(type->data[i]))
146
+ i++;
147
+
148
+ if (type->data[org] == '.')
149
+ org++;
150
+
151
+ if (cls) bufputc(ob, ' ');
152
+ escape_html(ob, type->data + org, i - org);
153
+ }
154
+ }
155
+
156
+ BUFPUTSL(ob, "\">");
157
+ } else if (options->flags & HTML_PRETTIFY) {
158
+ BUFPUTSL(ob, "<div data-type=\"customblock prettyprint\">");
159
+ } else {
160
+ BUFPUTSL(ob, "<div data-type=\"customblock\">");
161
+ }
162
+
163
+ if (text)
164
+ escape_html(ob, text->data, text->size);
165
+
166
+ BUFPUTSL(ob, "</div>\n");
167
+ }
168
+
123
169
  static void
124
170
  rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque)
125
171
  {
@@ -749,6 +795,7 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio
749
795
  NULL,
750
796
  NULL,
751
797
  NULL,
798
+ NULL,
752
799
  toc_header,
753
800
  NULL,
754
801
  NULL,
@@ -794,6 +841,7 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options,
794
841
  {
795
842
  static const struct sd_callbacks cb_default = {
796
843
  rndr_blockcode,
844
+ rndr_blockcustom,
797
845
  rndr_blockquote,
798
846
  rndr_raw_block,
799
847
  rndr_header,
@@ -1,6 +1,6 @@
1
- /* C code produced by gperf version 3.0.3 */
1
+ /* C code produced by gperf version 3.0.4 */
2
2
  /* Command-line: gperf -N find_block_tag -H hash_block_tag -C -c -E --ignore-case html_block_names.txt */
3
- /* See https://git.io/vPLqa for the list of recognized elements */
3
+ /* See http://git.io/RN0ncw for the list of recognized elements */
4
4
  /* Computed positions: -k'1-2' */
5
5
 
6
6
  #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -30,7 +30,7 @@
30
30
  error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
31
31
  #endif
32
32
 
33
- /* maximum key range = 72, duplicates = 0 */
33
+ /* maximum key range = 67, duplicates = 0 */
34
34
 
35
35
  #ifndef GPERF_DOWNCASE
36
36
  #define GPERF_DOWNCASE 1
@@ -94,34 +94,34 @@ hash_block_tag (str, len)
94
94
  {
95
95
  static const unsigned char asso_values[] =
96
96
  {
97
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
98
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
99
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
100
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
101
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
102
- 26, 60, 55, 45, 40, 35, 73, 73, 73, 73,
103
- 73, 73, 73, 73, 73, 20, 15, 15, 0, 35,
104
- 0, 25, 10, 10, 5, 73, 73, 0, 15, 15,
105
- 0, 73, 73, 15, 20, 10, 10, 73, 73, 73,
106
- 73, 73, 73, 73, 73, 73, 73, 20, 15, 15,
107
- 0, 35, 0, 25, 10, 10, 5, 73, 73, 0,
108
- 15, 15, 0, 73, 73, 15, 20, 10, 10, 73,
109
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
110
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
111
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
112
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
113
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
114
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
115
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
116
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
117
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
118
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
119
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
120
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
121
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
122
- 73, 73, 73, 73, 73, 73, 73
97
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
98
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
99
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
100
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
101
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
102
+ 55, 50, 45, 40, 35, 30, 68, 68, 68, 68,
103
+ 68, 68, 68, 68, 68, 15, 10, 15, 15, 15,
104
+ 0, 20, 10, 10, 5, 68, 68, 0, 20, 25,
105
+ 0, 68, 68, 0, 25, 0, 15, 68, 68, 68,
106
+ 68, 68, 68, 68, 68, 68, 68, 15, 10, 15,
107
+ 15, 15, 0, 20, 10, 10, 5, 68, 68, 0,
108
+ 20, 25, 0, 68, 68, 0, 25, 0, 15, 68,
109
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
110
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
111
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
112
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
113
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
114
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
115
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
116
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
117
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
118
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
119
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
120
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
121
+ 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
122
+ 68, 68, 68, 68, 68, 68, 68
123
123
  };
124
- register unsigned int hval = len;
124
+ register int hval = len;
125
125
 
126
126
  switch (hval)
127
127
  {
@@ -135,6 +135,12 @@ hash_block_tag (str, len)
135
135
  return hval;
136
136
  }
137
137
 
138
+ #ifdef __GNUC__
139
+ __inline
140
+ #if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
141
+ __attribute__ ((__gnu_inline__))
142
+ #endif
143
+ #endif
138
144
  const char *
139
145
  find_block_tag (str, len)
140
146
  register const char *str;
@@ -142,80 +148,76 @@ find_block_tag (str, len)
142
148
  {
143
149
  enum
144
150
  {
145
- TOTAL_KEYWORDS = 43,
151
+ TOTAL_KEYWORDS = 41,
146
152
  MIN_WORD_LENGTH = 1,
147
153
  MAX_WORD_LENGTH = 10,
148
154
  MIN_HASH_VALUE = 1,
149
- MAX_HASH_VALUE = 72
155
+ MAX_HASH_VALUE = 67
150
156
  };
151
157
 
152
158
  static const char * const wordlist[] =
153
159
  {
154
160
  "",
155
161
  "p",
156
- "dl",
157
- "del",
162
+ "ul",
163
+ "pre",
158
164
  "form",
159
- "",
165
+ "style",
160
166
  "footer",
161
- "details",
162
- "div",
163
- "", "",
167
+ "section",
168
+ "", "", "",
164
169
  "figure",
165
- "ul",
170
+ "hr",
166
171
  "fieldset",
167
- "",
172
+ "math",
168
173
  "figcaption",
169
174
  "header",
170
- "ol",
171
- "pre",
172
- "math",
173
- "video",
174
- "script",
175
- "section",
176
- "noscript",
175
+ "dl",
176
+ "del",
177
177
  "",
178
178
  "blockquote",
179
- "hgroup",
180
- "hr",
181
- "ins",
182
- "",
183
- "style",
184
- "output",
185
- "summary",
186
- "nav",
179
+ "script",
180
+ "article",
181
+ "div",
187
182
  "",
188
- "audio",
183
+ "video",
184
+ "hgroup",
185
+ "ol",
186
+ "noscript",
187
+ "", "",
189
188
  "canvas",
190
189
  "dd",
191
- "h1",
190
+ "nav",
192
191
  "abbr",
193
- "table",
192
+ "audio",
194
193
  "iframe",
195
- "article",
196
- "", "",
197
- "aside",
194
+ "address",
195
+ "ins",
196
+ "",
197
+ "table",
198
198
  "",
199
199
  "h6",
200
200
  "", "",
201
+ "aside",
202
+ "output",
203
+ "h5",
204
+ "", "",
201
205
  "tfoot",
202
206
  "",
203
- "h5",
204
- "", "", "", "",
205
207
  "h4",
206
208
  "", "", "", "",
207
- "address",
208
- "", "", "", "",
209
209
  "h3",
210
210
  "", "", "", "",
211
- "h2"
211
+ "h2",
212
+ "", "", "", "",
213
+ "h1"
212
214
  };
213
215
 
214
216
  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
215
217
  {
216
- unsigned int key = hash_block_tag (str, len);
218
+ register int key = hash_block_tag (str, len);
217
219
 
218
- if (key <= MAX_HASH_VALUE)
220
+ if (key <= MAX_HASH_VALUE && key >= 0)
219
221
  {
220
222
  register const char *s = wordlist[key];
221
223
 
@@ -1442,6 +1442,37 @@ prefix_codefence(uint8_t *data, size_t size)
1442
1442
  return i;
1443
1443
  }
1444
1444
 
1445
+ /* check if a line begins with a custom fence; return the
1446
+ * width of the custom fence */
1447
+ static size_t
1448
+ prefix_customfence(uint8_t *data, size_t size)
1449
+ {
1450
+ size_t i = 0, n = 0;
1451
+ uint8_t c;
1452
+
1453
+ /* skipping initial spaces */
1454
+ if (size < 3) return 0;
1455
+ if (data[0] == ' ') { i++;
1456
+ if (data[1] == ' ') { i++;
1457
+ if (data[2] == ' ') { i++; } } }
1458
+
1459
+ /* looking at the hrule uint8_t */
1460
+ if (i + 2 >= size || !(data[i] == ':'))
1461
+ return 0;
1462
+
1463
+ c = data[i];
1464
+
1465
+ /* the whole line must be the uint8_t or whitespace */
1466
+ while (i < size && data[i] == c) {
1467
+ n++; i++;
1468
+ }
1469
+
1470
+ if (n < 3)
1471
+ return 0;
1472
+
1473
+ return i;
1474
+ }
1475
+
1445
1476
  /* check if a line is a code fence; return its size if it is */
1446
1477
  static size_t
1447
1478
  is_codefence(uint8_t *data, size_t size, struct buf *syntax)
@@ -1499,6 +1530,63 @@ is_codefence(uint8_t *data, size_t size, struct buf *syntax)
1499
1530
  return i + 1;
1500
1531
  }
1501
1532
 
1533
+ /* check if a line is a custom fence; return its size if it is */
1534
+ static size_t
1535
+ is_customfence(uint8_t *data, size_t size, struct buf *syntax)
1536
+ {
1537
+ size_t i = 0, syn_len = 0;
1538
+ uint8_t *syn_start;
1539
+
1540
+ i = prefix_customfence(data, size);
1541
+ if (i == 0)
1542
+ return 0;
1543
+
1544
+ while (i < size && data[i] == ' ')
1545
+ i++;
1546
+
1547
+ syn_start = data + i;
1548
+
1549
+ if (i < size && data[i] == '{') {
1550
+ i++; syn_start++;
1551
+
1552
+ while (i < size && data[i] != '}' && data[i] != '\n') {
1553
+ syn_len++; i++;
1554
+ }
1555
+
1556
+ if (i == size || data[i] != '}')
1557
+ return 0;
1558
+
1559
+ /* strip all whitespace at the beginning and the end
1560
+ * of the {} block */
1561
+ while (syn_len > 0 && _isspace(syn_start[0])) {
1562
+ syn_start++; syn_len--;
1563
+ }
1564
+
1565
+ while (syn_len > 0 && _isspace(syn_start[syn_len - 1]))
1566
+ syn_len--;
1567
+
1568
+ i++;
1569
+ } else {
1570
+ while (i < size && data[i] != '\n') {
1571
+ syn_len++; i++;
1572
+ }
1573
+ }
1574
+
1575
+ if (syntax) {
1576
+ syntax->data = syn_start;
1577
+ syntax->size = syn_len;
1578
+ }
1579
+
1580
+ while (i < size && data[i] != '\n') {
1581
+ if (!_isspace(data[i]))
1582
+ return 0;
1583
+
1584
+ i++;
1585
+ }
1586
+
1587
+ return i + 1;
1588
+ }
1589
+
1502
1590
  /* is_atxheader • returns whether the line is a hash-prefixed header */
1503
1591
  static int
1504
1592
  is_atxheader(struct sd_markdown *rndr, uint8_t *data, size_t size)
@@ -1877,6 +1965,53 @@ parse_blockcode(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t
1877
1965
  return beg;
1878
1966
  }
1879
1967
 
1968
+
1969
+
1970
+ /* parse_fencedcustom • handles parsing of a block-level custom fragment */
1971
+ static size_t
1972
+ parse_fencedcustom(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size)
1973
+ {
1974
+ size_t beg, end;
1975
+ struct buf *work = 0;
1976
+ struct buf type = { 0, 0, 0, 0 };
1977
+
1978
+ beg = is_customfence(data, size, &type);
1979
+ if (beg == 0) return 0;
1980
+
1981
+ work = rndr_newbuf(rndr, BUFFER_BLOCK);
1982
+
1983
+ while (beg < size) {
1984
+ size_t fence_end;
1985
+ struct buf fence_trail = { 0, 0, 0, 0 };
1986
+
1987
+ fence_end = is_customfence(data + beg, size - beg, &fence_trail);
1988
+ if (fence_end != 0 && fence_trail.size == 0) {
1989
+ beg += fence_end;
1990
+ break;
1991
+ }
1992
+
1993
+ for (end = beg + 1; end < size && data[end - 1] != '\n'; end++);
1994
+
1995
+ if (beg < end) {
1996
+ /* verbatim copy to the working buffer,
1997
+ escaping entities */
1998
+ if (is_empty(data + beg, end - beg))
1999
+ bufputc(work, '\n');
2000
+ else bufput(work, data + beg, end - beg);
2001
+ }
2002
+ beg = end;
2003
+ }
2004
+
2005
+ if (work->size && work->data[work->size - 1] != '\n')
2006
+ bufputc(work, '\n');
2007
+
2008
+ if (rndr->cb.blockcustom)
2009
+ rndr->cb.blockcustom(ob, work, type.size ? &type : NULL, rndr->opaque);
2010
+
2011
+ rndr_popbuf(rndr, BUFFER_BLOCK);
2012
+ return beg;
2013
+ }
2014
+
1880
2015
  /* parse_listitem • parsing of a single list item */
1881
2016
  /* assuming initial prefix is already removed */
1882
2017
  static size_t
@@ -2513,6 +2648,10 @@ parse_block(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size
2513
2648
  (i = parse_fencedcode(ob, rndr, txt_data, end)) != 0)
2514
2649
  beg += i;
2515
2650
 
2651
+ else if ((rndr->ext_flags & MKDEXT_FENCED_CUSTOM) != 0 &&
2652
+ (i = parse_fencedcustom(ob, rndr, txt_data, end)) != 0)
2653
+ beg += i;
2654
+
2516
2655
  else if ((rndr->ext_flags & MKDEXT_TABLES) != 0 &&
2517
2656
  (i = parse_table(ob, rndr, txt_data, end)) != 0)
2518
2657
  beg += i;
@@ -64,13 +64,15 @@ enum mkd_extensions {
64
64
  MKDEXT_HIGHLIGHT = (1 << 10),
65
65
  MKDEXT_FOOTNOTES = (1 << 11),
66
66
  MKDEXT_QUOTE = (1 << 12),
67
- MKDEXT_NO_MENTION_EMPHASIS = (1 << 13)
67
+ MKDEXT_NO_MENTION_EMPHASIS = (1 << 13),
68
+ MKDEXT_FENCED_CUSTOM = (1 << 14)
68
69
  };
69
70
 
70
71
  /* sd_callbacks - functions for rendering parsed data */
71
72
  struct sd_callbacks {
72
73
  /* block level callbacks - NULL skips the block */
73
74
  void (*blockcode)(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque);
75
+ void (*blockcustom)(struct buf *ob, const struct buf *text, const struct buf *type, void *opaque);
74
76
  void (*blockquote)(struct buf *ob, const struct buf *text, void *opaque);
75
77
  void (*blockhtml)(struct buf *ob,const struct buf *text, void *opaque);
76
78
  void (*header)(struct buf *ob, const struct buf *text, int level, void *opaque);
data/greenmat.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.homepage = 'https://github.com/increments/greenmat'
13
13
  s.authors = ["Natacha Porté", "Vicent Martí"]
14
14
  s.license = 'MIT'
15
- s.required_ruby_version = '>= 2.0.0'
15
+ s.required_ruby_version = '>= 2.5.0'
16
16
 
17
17
  s.files = `git ls-files -z`.split("\x0")
18
18
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.require_paths = ["lib"]
23
23
 
24
24
  s.add_development_dependency "activesupport"
25
- s.add_development_dependency "nokogiri", "~> 1.6.0"
25
+ s.add_development_dependency "nokogiri", "~> 1.11.7"
26
26
  s.add_development_dependency "rake", "~> 12.2.1"
27
27
  s.add_development_dependency "rake-compiler", "~> 1.0.3"
28
28
  s.add_development_dependency "rspec", "~> 3.2"
@@ -1,3 +1,3 @@
1
1
  module Greenmat
2
- VERSION = '3.5.1.0'
2
+ VERSION = '3.5.1.3'
3
3
  end
@@ -184,5 +184,48 @@ module Greenmat
184
184
  EOS
185
185
  end
186
186
  end
187
+
188
+ context 'with fenced_custom_blocks option' do
189
+ let(:options) { { fenced_custom_blocks: true } }
190
+
191
+ context 'with custom block with any metadata' do
192
+ let(:text) do
193
+ <<-EOS.strip_heredoc
194
+ :::foo bar
195
+ message
196
+ :::
197
+ EOS
198
+ end
199
+
200
+ it 'renders text with <div> tag that have customblock class & metadata in a data-metadata attribute' do
201
+ expect(rendered_html).to eq <<-EOS.strip_heredoc
202
+ <div data-type="customblock" data-metadata="foo bar">message
203
+ </div>
204
+ EOS
205
+ end
206
+ end
207
+ end
208
+
209
+ context 'without fenced_custom_blocks option' do
210
+ let(:options) { {} }
211
+
212
+ context 'with custom block with any metadata' do
213
+ let(:text) do
214
+ <<-EOS.strip_heredoc
215
+ :::foo bar
216
+ message
217
+ :::
218
+ EOS
219
+ end
220
+
221
+ it 'renders text with p tag' do
222
+ expect(rendered_html).to eq <<-EOS.strip_heredoc
223
+ <p>:::foo bar
224
+ message
225
+ :::</p>
226
+ EOS
227
+ end
228
+ end
229
+ end
187
230
  end
188
231
  end
data/test/html5_test.rb CHANGED
@@ -68,15 +68,24 @@ class HTML5Test < Greenmat::TestCase
68
68
  assert_renders html, html
69
69
  end
70
70
 
71
- def test_new_html5_tags_not_escaped
71
+ def test_details_tags_ignoring
72
72
  details = <<-HTML.chomp.strip_heredoc
73
- <details>
74
- log:
73
+ <details><summary>Folding sample</summary><div>
75
74
 
76
- </details>
75
+ ```rb
76
+ puts 'Hello, World'
77
+ ```
78
+ </div></details>
77
79
  HTML
80
+ html = <<-HTML.chomp.strip_heredoc
81
+ <p><details><summary>Folding sample</summary><div></p>
78
82
 
79
- assert_renders details, details
80
- end
83
+ <p><code>rb
84
+ puts &#39;Hello, World&#39;
85
+ </code>
86
+ </div></details></p>
87
+ HTML
81
88
 
89
+ assert_renders html, details
90
+ end
82
91
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: greenmat
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.1.0
4
+ version: 3.5.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Natacha Porté
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-02-16 00:00:00.000000000 Z
12
+ date: 2022-03-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 1.6.0
34
+ version: 1.11.7
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 1.6.0
41
+ version: 1.11.7
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: rake
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -104,9 +104,9 @@ extensions:
104
104
  extra_rdoc_files:
105
105
  - COPYING
106
106
  files:
107
+ - ".github/workflows/test.yml"
107
108
  - ".gitignore"
108
109
  - ".rspec"
109
- - ".travis.yml"
110
110
  - CHANGELOG.md
111
111
  - COPYING
112
112
  - Gemfile
@@ -254,14 +254,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
254
254
  requirements:
255
255
  - - ">="
256
256
  - !ruby/object:Gem::Version
257
- version: 2.0.0
257
+ version: 2.5.0
258
258
  required_rubygems_version: !ruby/object:Gem::Requirement
259
259
  requirements:
260
260
  - - ">="
261
261
  - !ruby/object:Gem::Version
262
262
  version: '0'
263
263
  requirements: []
264
- rubygems_version: 3.0.3
264
+ rubygems_version: 3.1.4
265
265
  signing_key:
266
266
  specification_version: 4
267
267
  summary: A Markdown parser for Qiita, based on Redcarpet.
data/.travis.yml DELETED
@@ -1,27 +0,0 @@
1
- sudo: false
2
- dist: trusty
3
-
4
- addons:
5
- apt:
6
- packages:
7
- - tidy
8
- - tcl
9
- - tk
10
-
11
- install: bundle install --without=benchmark
12
-
13
- rvm:
14
- - 2.0.0
15
- - 2.1
16
- - 2.2
17
- - 2.3
18
- - 2.4
19
- - 2.5
20
- - ruby-head
21
-
22
- matrix:
23
- allow_failures:
24
- - rvm: ruby-head
25
-
26
- notifications:
27
- email: false