qiita_marker 0.23.2.0 → 0.23.2.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.
@@ -0,0 +1,37 @@
1
+ #include "cmark-gfm.h"
2
+ #include "cmark_ctype.h"
3
+ #include "config.h"
4
+
5
+ static bool is_wordchar(char c) {
6
+ return cmark_isalnum(c) || c == '_' || c == '-';
7
+ }
8
+
9
+ bool is_part_of_mention(unsigned char *data, bufsize_t offset) {
10
+ int i;
11
+ int lookbehind_limit = (int)-offset;
12
+ char character;
13
+
14
+ for (i = 0; i >= lookbehind_limit; i--) {
15
+ character = data[i];
16
+
17
+ if (is_wordchar(character)) {
18
+ // Continue lookbehind.
19
+ } else if (character == '@') {
20
+ if (i == offset) {
21
+ // The "@" is at beginning of the text. (e.g. "@foo")
22
+ return true;
23
+ } else {
24
+ // Check if the previous character of the "@" is alphanumeric or not.
25
+ // " @foo" and "あ@foo" are mentions.
26
+ // "a@foo" is not a mention.
27
+ char prev_character = data[i - 1];
28
+ return !cmark_isalnum(prev_character);
29
+ }
30
+ } else {
31
+ // Found non-mention character, so this is not a mention.
32
+ return false;
33
+ }
34
+ }
35
+
36
+ return false;
37
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef QFM_MENTION_NO_EMPHASIS
2
+ #define QFM_MENTION_NO_EMPHASIS
3
+
4
+ #include "cmark-gfm.h"
5
+
6
+ bool is_part_of_mention(unsigned char *data, bufsize_t offset);
7
+
8
+ #endif
@@ -0,0 +1,291 @@
1
+ /* Generated by re2c 1.3 */
2
+
3
+ #include "qfm_scanners.h"
4
+ #include <stdlib.h>
5
+
6
+ bufsize_t _qfm_scan_at(bufsize_t (*scanner)(const unsigned char *),
7
+ unsigned char *ptr, int len, bufsize_t offset) {
8
+ bufsize_t res;
9
+
10
+ if (ptr == NULL || offset >= len) {
11
+ return 0;
12
+ } else {
13
+ unsigned char lim = ptr[len];
14
+
15
+ ptr[len] = '\0';
16
+ res = scanner(ptr + offset);
17
+ ptr[len] = lim;
18
+ }
19
+
20
+ return res;
21
+ }
22
+
23
+ // Scan an opening qfm_custom_block fence.
24
+ bufsize_t _scan_open_qfm_custom_block_fence(const unsigned char *p) {
25
+ const unsigned char *marker = NULL;
26
+ const unsigned char *start = p;
27
+
28
+ {
29
+ unsigned char yych;
30
+ static const unsigned char yybm[] = {
31
+ 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 128, 128, 0,
32
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
33
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
34
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
35
+ 128, 128, 64, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
36
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
37
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
38
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
39
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
40
+ 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49
+ 0, 0, 0, 0,
50
+ };
51
+ yych = *p;
52
+ if (yych == ':')
53
+ goto yy4;
54
+ ++p;
55
+ yy3 : { return 0; }
56
+ yy4:
57
+ yych = *(marker = ++p);
58
+ if (yych != ':')
59
+ goto yy3;
60
+ yych = *++p;
61
+ if (yybm[0 + yych] & 64) {
62
+ goto yy7;
63
+ }
64
+ yy6:
65
+ p = marker;
66
+ goto yy3;
67
+ yy7:
68
+ yych = *++p;
69
+ if (yybm[0 + yych] & 64) {
70
+ goto yy7;
71
+ }
72
+ if (yych <= 0xDF) {
73
+ if (yych <= '\f') {
74
+ if (yych <= 0x00)
75
+ goto yy6;
76
+ if (yych == '\n') {
77
+ marker = p;
78
+ goto yy11;
79
+ }
80
+ marker = p;
81
+ } else {
82
+ if (yych <= '\r') {
83
+ marker = p;
84
+ goto yy11;
85
+ }
86
+ if (yych <= 0x7F) {
87
+ marker = p;
88
+ goto yy9;
89
+ }
90
+ if (yych <= 0xC1)
91
+ goto yy6;
92
+ marker = p;
93
+ goto yy13;
94
+ }
95
+ } else {
96
+ if (yych <= 0xEF) {
97
+ if (yych <= 0xE0) {
98
+ marker = p;
99
+ goto yy14;
100
+ }
101
+ if (yych == 0xED) {
102
+ marker = p;
103
+ goto yy16;
104
+ }
105
+ marker = p;
106
+ goto yy15;
107
+ } else {
108
+ if (yych <= 0xF0) {
109
+ marker = p;
110
+ goto yy17;
111
+ }
112
+ if (yych <= 0xF3) {
113
+ marker = p;
114
+ goto yy18;
115
+ }
116
+ if (yych <= 0xF4) {
117
+ marker = p;
118
+ goto yy19;
119
+ }
120
+ goto yy6;
121
+ }
122
+ }
123
+ yy9:
124
+ yych = *++p;
125
+ if (yybm[0 + yych] & 128) {
126
+ goto yy9;
127
+ }
128
+ if (yych <= 0xEC) {
129
+ if (yych <= 0xC1) {
130
+ if (yych <= 0x00)
131
+ goto yy6;
132
+ if (yych >= 0x0E)
133
+ goto yy6;
134
+ } else {
135
+ if (yych <= 0xDF)
136
+ goto yy13;
137
+ if (yych <= 0xE0)
138
+ goto yy14;
139
+ goto yy15;
140
+ }
141
+ } else {
142
+ if (yych <= 0xF0) {
143
+ if (yych <= 0xED)
144
+ goto yy16;
145
+ if (yych <= 0xEF)
146
+ goto yy15;
147
+ goto yy17;
148
+ } else {
149
+ if (yych <= 0xF3)
150
+ goto yy18;
151
+ if (yych <= 0xF4)
152
+ goto yy19;
153
+ goto yy6;
154
+ }
155
+ }
156
+ yy11:
157
+ ++p;
158
+ p = marker;
159
+ { return (bufsize_t)(p - start); }
160
+ yy13:
161
+ yych = *++p;
162
+ if (yych <= 0x7F)
163
+ goto yy6;
164
+ if (yych <= 0xBF)
165
+ goto yy9;
166
+ goto yy6;
167
+ yy14:
168
+ yych = *++p;
169
+ if (yych <= 0x9F)
170
+ goto yy6;
171
+ if (yych <= 0xBF)
172
+ goto yy13;
173
+ goto yy6;
174
+ yy15:
175
+ yych = *++p;
176
+ if (yych <= 0x7F)
177
+ goto yy6;
178
+ if (yych <= 0xBF)
179
+ goto yy13;
180
+ goto yy6;
181
+ yy16:
182
+ yych = *++p;
183
+ if (yych <= 0x7F)
184
+ goto yy6;
185
+ if (yych <= 0x9F)
186
+ goto yy13;
187
+ goto yy6;
188
+ yy17:
189
+ yych = *++p;
190
+ if (yych <= 0x8F)
191
+ goto yy6;
192
+ if (yych <= 0xBF)
193
+ goto yy15;
194
+ goto yy6;
195
+ yy18:
196
+ yych = *++p;
197
+ if (yych <= 0x7F)
198
+ goto yy6;
199
+ if (yych <= 0xBF)
200
+ goto yy15;
201
+ goto yy6;
202
+ yy19:
203
+ yych = *++p;
204
+ if (yych <= 0x7F)
205
+ goto yy6;
206
+ if (yych <= 0x8F)
207
+ goto yy15;
208
+ goto yy6;
209
+ }
210
+ }
211
+
212
+ // Scan a closing qfm_custom_block fence with length at least len.
213
+ bufsize_t _scan_close_qfm_custom_block_fence(const unsigned char *p) {
214
+ const unsigned char *marker = NULL;
215
+ const unsigned char *start = p;
216
+
217
+ {
218
+ unsigned char yych;
219
+ static const unsigned char yybm[] = {
220
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
222
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0,
223
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
225
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
226
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
227
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
228
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
229
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
230
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
231
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
232
+ };
233
+ yych = *p;
234
+ if (yych == ':')
235
+ goto yy24;
236
+ ++p;
237
+ yy23 : { return 0; }
238
+ yy24:
239
+ yych = *(marker = ++p);
240
+ if (yych != ':')
241
+ goto yy23;
242
+ yych = *++p;
243
+ if (yybm[0 + yych] & 64) {
244
+ goto yy27;
245
+ }
246
+ yy26:
247
+ p = marker;
248
+ goto yy23;
249
+ yy27:
250
+ yych = *++p;
251
+ if (yybm[0 + yych] & 64) {
252
+ goto yy27;
253
+ }
254
+ if (yych <= '\f') {
255
+ if (yych <= 0x08)
256
+ goto yy26;
257
+ if (yych <= '\t') {
258
+ marker = p;
259
+ goto yy29;
260
+ }
261
+ if (yych <= '\n') {
262
+ marker = p;
263
+ goto yy31;
264
+ }
265
+ goto yy26;
266
+ } else {
267
+ if (yych <= '\r') {
268
+ marker = p;
269
+ goto yy31;
270
+ }
271
+ if (yych != ' ')
272
+ goto yy26;
273
+ marker = p;
274
+ }
275
+ yy29:
276
+ yych = *++p;
277
+ if (yybm[0 + yych] & 128) {
278
+ goto yy29;
279
+ }
280
+ if (yych <= 0x08)
281
+ goto yy26;
282
+ if (yych <= '\n')
283
+ goto yy31;
284
+ if (yych != '\r')
285
+ goto yy26;
286
+ yy31:
287
+ ++p;
288
+ p = marker;
289
+ { return (bufsize_t)(p - start); }
290
+ }
291
+ }
@@ -0,0 +1,20 @@
1
+ #include "chunk.h"
2
+ #include "cmark-gfm.h"
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+
8
+ bufsize_t _qfm_scan_at(bufsize_t (*scanner)(const unsigned char *),
9
+ unsigned char *ptr, int len, bufsize_t offset);
10
+ bufsize_t _scan_open_qfm_custom_block_fence(const unsigned char *p);
11
+ bufsize_t _scan_close_qfm_custom_block_fence(const unsigned char *p);
12
+
13
+ #define scan_open_qfm_custom_block_fence(c, l, n) \
14
+ _qfm_scan_at(&_scan_open_qfm_custom_block_fence, c, l, n)
15
+ #define scan_close_qfm_custom_block_fence(c, l, n) \
16
+ _qfm_scan_at(&_scan_close_qfm_custom_block_fence, c, l, n)
17
+
18
+ #ifdef __cplusplus
19
+ }
20
+ #endif
@@ -0,0 +1,50 @@
1
+ /*!re2c re2c:flags:no-debug-info = 1; */
2
+ /*!re2c re2c:indent:string = ' '; */
3
+
4
+ #include "qfm_scanners.h"
5
+ #include <stdlib.h>
6
+
7
+ bufsize_t _qfm_scan_at(bufsize_t (*scanner)(const unsigned char *),
8
+ unsigned char *ptr, int len, bufsize_t offset) {
9
+ bufsize_t res;
10
+
11
+ if (ptr == NULL || offset >= len) {
12
+ return 0;
13
+ } else {
14
+ unsigned char lim = ptr[len];
15
+
16
+ ptr[len] = '\0';
17
+ res = scanner(ptr + offset);
18
+ ptr[len] = lim;
19
+ }
20
+
21
+ return res;
22
+ }
23
+
24
+ /*!re2c
25
+ re2c:define:YYCTYPE = "unsigned char";
26
+ re2c:define:YYCURSOR = p;
27
+ re2c:define:YYMARKER = marker;
28
+ re2c:define:YYCTXMARKER = marker;
29
+ re2c:yyfill:enable = 0;
30
+ */
31
+
32
+ // Scan an opening qfm_custom_block fence.
33
+ bufsize_t _scan_open_qfm_custom_block_fence(const unsigned char *p) {
34
+ const unsigned char *marker = NULL;
35
+ const unsigned char *start = p;
36
+ /*!re2c
37
+ [:]{3,} / [^:\r\n\x00]*[\r\n] { return (bufsize_t)(p - start); }
38
+ * { return 0; }
39
+ */
40
+ }
41
+
42
+ // Scan a closing qfm_custom_block fence with length at least len.
43
+ bufsize_t _scan_close_qfm_custom_block_fence(const unsigned char *p) {
44
+ const unsigned char *marker = NULL;
45
+ const unsigned char *start = p;
46
+ /*!re2c
47
+ [:]{3,} / [ \t]*[\r\n] { return (bufsize_t)(p - start); }
48
+ * { return 0; }
49
+ */
50
+ }
@@ -13,7 +13,9 @@ module QiitaMarker
13
13
  SMART: (1 << 10),
14
14
  LIBERAL_HTML_TAG: (1 << 12),
15
15
  FOOTNOTES: (1 << 13),
16
- STRIKETHROUGH_DOUBLE_TILDE: (1 << 14)
16
+ STRIKETHROUGH_DOUBLE_TILDE: (1 << 14),
17
+ MENTION_NO_EMPHASIS: (1 << 26),
18
+ AUTOLINK_CLASS_NAME: (1 << 27)
17
19
  }.freeze,
18
20
  render: {
19
21
  DEFAULT: 0,
@@ -28,7 +30,10 @@ module QiitaMarker
28
30
  FOOTNOTES: (1 << 13),
29
31
  STRIKETHROUGH_DOUBLE_TILDE: (1 << 14),
30
32
  TABLE_PREFER_STYLE_ATTRIBUTES: (1 << 15),
31
- FULL_INFO_STRING: (1 << 16)
33
+ FULL_INFO_STRING: (1 << 16),
34
+ CODE_DATA_METADATA: (1 << 25),
35
+ MENTION_NO_EMPHASIS: (1 << 26),
36
+ AUTOLINK_CLASS_NAME: (1 << 27)
32
37
  }.freeze,
33
38
  format: %i[html xml commonmark plaintext].freeze
34
39
  }.freeze
@@ -94,6 +94,10 @@ module QiitaMarker
94
94
  out("<pre#{sourcepos(node)}")
95
95
  out(' lang="', node.fence_info.split(/\s+/)[0], '"') if node.fence_info && !node.fence_info.empty?
96
96
  out('><code>')
97
+ elsif option_enabled?(:CODE_DATA_METADATA)
98
+ out("<pre#{sourcepos(node)}><code")
99
+ out(' data-metadata="', node.fence_info, '"') if node.fence_info && !node.fence_info.empty?
100
+ out('>')
97
101
  else
98
102
  out("<pre#{sourcepos(node)}><code")
99
103
  if node.fence_info && !node.fence_info.empty?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module QiitaMarker
4
- VERSION = '0.23.2.0'
4
+ VERSION = '0.23.2.3'
5
5
  end
data/qiita_marker.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.version = QiitaMarker::VERSION
10
10
  s.summary = 'Qiita Marker is a Ruby library for Markdown processing, based on CommonMarker.'
11
11
  s.description = 'A Ruby library that is the core module of the Qiita-specified markdown processor.'
12
- s.authors = ['Increments Inc.']
12
+ s.authors = ['Qiita Inc.']
13
13
  s.homepage = 'https://github.com/increments/qiita_marker'
14
14
  s.license = 'MIT'
15
15
 
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('test_helper')
4
+
5
+ describe 'TestQfmAutolinkClassName' do
6
+ let(:options) { %i[AUTOLINK_CLASS_NAME] }
7
+ let(:extensions) { %i[autolink] }
8
+ let(:text) do
9
+ <<~MD
10
+ https://example.com
11
+ <https://example.com>
12
+ [Example](https://example.com)
13
+ test@example.com
14
+ MD
15
+ end
16
+ let(:doc) { QiitaMarker.render_doc(text, options, extensions) }
17
+ let(:expected) do
18
+ <<~HTML
19
+ <p><a href="https://example.com" class="autolink">https://example.com</a>
20
+ <a href="https://example.com">https://example.com</a>
21
+ <a href="https://example.com">Example</a>
22
+ <a href="mailto:test@example.com" class="autolink">test@example.com</a></p>
23
+ HTML
24
+ end
25
+ let(:rendered_html) { doc.to_html(options, extensions) }
26
+
27
+ it "appends class name to extension's autolinks" do
28
+ assert_equal(expected, rendered_html)
29
+ end
30
+
31
+ describe 'without AUTOLINK_CLASS_NAME option' do
32
+ let(:options) { %i[DEFAULT] }
33
+ let(:expected) do
34
+ <<~HTML
35
+ <p><a href="https://example.com">https://example.com</a>
36
+ <a href="https://example.com">https://example.com</a>
37
+ <a href="https://example.com">Example</a>
38
+ <a href="mailto:test@example.com">test@example.com</a></p>
39
+ HTML
40
+ end
41
+
42
+ it "does not append class name to extension's autolink" do
43
+ assert_equal(expected, rendered_html)
44
+ end
45
+ end
46
+
47
+ describe 'without autolink extension' do
48
+ let(:extensions) { %i[] }
49
+ let(:expected) do
50
+ <<~HTML
51
+ <p>https://example.com
52
+ <a href="https://example.com">https://example.com</a>
53
+ <a href="https://example.com">Example</a>
54
+ test@example.com</p>
55
+ HTML
56
+ end
57
+
58
+ it 'does not append class name' do
59
+ assert_equal(expected, rendered_html)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('test_helper')
4
+
5
+ class TestQfmCodeDataMetadata < Minitest::Test
6
+ def test_to_html
7
+ text = <<~MD
8
+ ```ruby:example main.rb
9
+ puts :foo
10
+ ```
11
+ MD
12
+ doc = render_doc(text)
13
+ expected = <<~HTML
14
+ <pre><code data-metadata="ruby:example main.rb">puts :foo
15
+ </code></pre>
16
+ HTML
17
+
18
+ assert_equal(expected, doc.to_html(:CODE_DATA_METADATA))
19
+ assert_equal(expected, QiitaMarker::HtmlRenderer.new(options: :CODE_DATA_METADATA).render(doc))
20
+ end
21
+
22
+ def test_with_character_reference
23
+ text = <<~MD
24
+ ```ruby:example&#x20;main.rb
25
+ puts :foo
26
+ ```
27
+ MD
28
+ doc = render_doc(text)
29
+ expected = <<~HTML
30
+ <pre><code data-metadata="ruby:example main.rb">puts :foo
31
+ </code></pre>
32
+ HTML
33
+
34
+ assert_equal(expected, doc.to_html(:CODE_DATA_METADATA))
35
+ assert_equal(expected, QiitaMarker::HtmlRenderer.new(options: :CODE_DATA_METADATA).render(doc))
36
+ end
37
+
38
+ def render_doc(markdown)
39
+ QiitaMarker.render_doc(markdown, :DEFAULT, [])
40
+ end
41
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('test_helper')
4
+
5
+ class TestQfmCustomBlock < Minitest::Test
6
+ def setup
7
+ text = <<~MD
8
+ :::foo bar
9
+ message
10
+
11
+ - list1
12
+ - list2
13
+
14
+ ```ruby
15
+ puts 'hello'
16
+ ```
17
+
18
+ <div>html block</div>
19
+ :::
20
+ MD
21
+ @doc = QiitaMarker.render_doc(text, %i[UNSAFE], %i[custom_block])
22
+ @expected = <<~HTML
23
+ <div data-type="customblock" data-metadata="foo bar">
24
+ <p>message</p>
25
+ <ul>
26
+ <li>list1</li>
27
+ <li>list2</li>
28
+ </ul>
29
+ <pre><code class="language-ruby">puts 'hello'
30
+ </code></pre>
31
+ <div>html block</div>
32
+ </div>
33
+ HTML
34
+ end
35
+
36
+ def test_to_html
37
+ assert_equal(@expected, @doc.to_html(%i[UNSAFE], %i[custom_block]))
38
+ end
39
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class TestQfmMentionNoEmphasis < Minitest::Test
6
+ describe 'with mention_no_emphasis option' do
7
+ [
8
+ ['@_username_', false],
9
+ ['@__username__', false],
10
+ ['@___username___', false],
11
+ ['@user__name__', false],
12
+ ['@some__user__name__', false],
13
+ [' @_username_', false],
14
+ ['あ@_username_', false],
15
+ ['A@_username_', true],
16
+ ['@*username*', true],
17
+ ['_foo_', true],
18
+ ['_', false],
19
+ ['_foo @username_', false],
20
+ ['__foo @username__', false],
21
+ ['___foo @username___', false]
22
+ ].each do |text, emphasize|
23
+ describe "with text #{text.inspect}" do
24
+ if emphasize
25
+ it 'emphasizes the text' do
26
+ QiitaMarker.render_html(text, :MENTION_NO_EMPHASIS).tap do |out|
27
+ assert_match(/(<em>|<strong>)/, out.chomp)
28
+ end
29
+ end
30
+ else
31
+ it 'does not emphasize the text' do
32
+ QiitaMarker.render_html(text, :MENTION_NO_EMPHASIS).tap do |out|
33
+ assert_match "<p>#{text.strip}</p>", out.chomp
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ describe 'without mention_no_emphasis option' do
42
+ describe 'with text "@_username_"' do
43
+ text = '@_username_'
44
+ it 'emphasizes the text' do
45
+ QiitaMarker.render_html(text, :DEFAULT, %i[]).tap do |out|
46
+ assert_match(/<em>/, out.chomp)
47
+ end
48
+ end
49
+ end
50
+
51
+ describe 'with text "_foo @username_"' do
52
+ text = '_foo @username_'
53
+ it 'emphasizes the text' do
54
+ QiitaMarker.render_html(text, :DEFAULT, %i[]).tap do |out|
55
+ assert_match(/<em>/, out.chomp)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end