greenmat 3.5.1.0 → 3.5.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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