Skip to content

Commit

Permalink
feat(literalMidWordAsterisks): add option for mid word asterisks
Browse files Browse the repository at this point in the history
Implements feature similar to ignoring midword underscores but with asterisks. The main use case is ignoring cursing.
  • Loading branch information
brecke authored and tivie committed Apr 5, 2017
1 parent f1eab2a commit 5bec8f9
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 10 deletions.
12 changes: 12 additions & 0 deletions README.md
Expand Up @@ -253,6 +253,18 @@ var defaultOptions = showdown.getDefaultOptions();
```html
<p>some text with__underscores__in middle</p>
```
* **literalMidWordAsterisks**: (boolean) [default false] Turning this on will stop showdown from interpreting asterisks in the middle of words as `<em>` and `<strong>` and instead treat them as literal asterisks.
Example:
```md
some text with**underscores**in middle
```
will be parsed as
```html
<p>some text with**underscores**in middle</p>
```
* **strikethrough**: (boolean) [default false] Enable support for strikethrough syntax.
`~~strikethrough~~` as `<del>strikethrough</del>`
Expand Down
5 changes: 5 additions & 0 deletions src/options.js
Expand Up @@ -51,6 +51,11 @@ function getDefaultOpts (simple) {
describe: 'Parse midword underscores as literal underscores',
type: 'boolean'
},
literalMidWordAsterisks: {
defaultValue: false,
describe: 'Parse midword asterisks as literal asterisks',
type: 'boolean'
},
strikethrough: {
defaultValue: false,
describe: 'Turn on/off strikethrough support',
Expand Down
33 changes: 23 additions & 10 deletions src/subParsers/italicsAndBold.js
Expand Up @@ -39,16 +39,29 @@ showdown.subParser('italicsAndBold', function (text, options, globals) {
}

// Now parse asterisks
text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) {
return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
});
text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) {
return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
});
text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) {
// !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it)
return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
});
if (options.literalMidWordAsterisks) {
text = text.trim().replace(/(?:^| +)\*{3}(\S[\s\S]*?)\*{3}(?: +|$)/g, function (wm, txt) {
return parseInside (txt, ' <strong><em>', '</em></strong> ');
});
text = text.trim().replace(/(?:^| +)\*{2}(\S[\s\S]*?)\*{2}(?: +|$)/g, function (wm, txt) {
return parseInside (txt, ' <strong>', '</strong> ');
});
text = text.trim().replace(/(?:^| +)\*{1}(\S[\s\S]*?)\*{1}(?: +|$)/g, function (wm, txt) {
return parseInside (txt, ' <em>', '</em>' + (wm.slice(-1) === ' ' ? ' ' : ''));
});
} else {
text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) {
return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
});
text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) {
return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
});
text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) {
// !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it)
return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
});
}


text = globals.converter._dispatch('italicsAndBold.after', text, options, globals);
return text;
Expand Down
24 changes: 24 additions & 0 deletions test/features/enable-literalMidWordAsterisks.html
@@ -0,0 +1,24 @@
<p>this is a sentence*with*mid asterisks</p>
<p>this is a sentence**with**two mid asterisks</p>
<p>this is a sentence***with***three mid asterisks</p>
<p>this is a sentence with just*one asterisk</p>
<p>this is a sentence with just**one asterisk</p>
<p>this is a sentence with just***one asterisk</p>
<p>this is double**asterisk**mid word</p>
<p>this has just**one double asterisk</p>
<p>this has just***one triple asterisk</p>
<p>this <em>should be parsed</em> as emphasis</p>
<p>this <strong>should be parsed</strong> as bold</p>
<p>this <strong><em>should be parsed</em></strong> as bold and emphasis</p>
<p>emphasis at <em>end of sentence</em></p>
<p>bold at <strong>end of sentence</strong></p>
<p>bold and emphasis at <strong><em>end of sentence</em></strong></p>
<p><em>emphasis at</em> line start</p>
<p><strong>bold at</strong> line start</p>
<p><strong><em>bold and emphasis at</em></strong> line start</p>
<p>multi <em>line emphasis
yeah it is</em> yeah</p>
<p>multi <strong>line emphasis
yeah it is</strong> yeah</p>
<p>multi <strong><em>line emphasis
yeah it is</em></strong> yeah</p>
46 changes: 46 additions & 0 deletions test/features/enable-literalMidWordAsterisks.md
@@ -0,0 +1,46 @@
this is a sentence*with*mid asterisks

this is a sentence**with**two mid asterisks

this is a sentence***with***three mid asterisks

this is a sentence with just*one asterisk

this is a sentence with just**one asterisk

this is a sentence with just***one asterisk

this is double**asterisk**mid word

this has just**one double asterisk

this has just***one triple asterisk

this *should be parsed* as emphasis

this **should be parsed** as bold

this ***should be parsed*** as bold and emphasis

emphasis at *end of sentence*

bold at **end of sentence**

bold and emphasis at ***end of sentence***

*emphasis at* line start

**bold at** line start

***bold and emphasis at*** line start

multi *line emphasis
yeah it is* yeah


multi **line emphasis
yeah it is** yeah


multi ***line emphasis
yeah it is*** yeah
4 changes: 4 additions & 0 deletions test/node/testsuite.features.js
Expand Up @@ -62,6 +62,8 @@ describe('makeHtml() features testsuite', function () {
converter = new showdown.Converter({encodeEmails: false, simplifiedAutoLink: true});
} else if (testsuite[i].name === '#331.allow-escaping-of-tilde') {
converter = new showdown.Converter({strikethrough: true});
} else if (testsuite[i].name === 'enable-literalMidWordAsterisks') {
converter = new showdown.Converter({literalMidWordAsterisks: true});
} else if (testsuite[i].name === 'prefixHeaderId-simple') {
converter = new showdown.Converter({prefixHeaderId: true});
} else if (testsuite[i].name === 'prefixHeaderId-string') {
Expand Down Expand Up @@ -104,6 +106,8 @@ describe('makeHtml() features testsuite', function () {
converter = new showdown.Converter({simplifiedAutoLink: true, strikethrough: true});
} else if (suite[i].name === 'disallow-underscores') {
converter = new showdown.Converter({literalMidWordUnderscores: true, simplifiedAutoLink: true});
} else if (suite[i].name === 'disallow-asterisks') {
converter = new showdown.Converter({literalMidWordAsterisks: true, simplifiedAutoLink: true});
} else {
converter = new showdown.Converter({simplifiedAutoLink: true});
}
Expand Down

0 comments on commit 5bec8f9

Please sign in to comment.