Skip to content

Commit

Permalink
JSX: Add partial support for plain text between tags
Browse files Browse the repository at this point in the history
  • Loading branch information
Golmote committed Feb 21, 2018
1 parent 7a9dbe0 commit 7305739
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 8 deletions.
48 changes: 45 additions & 3 deletions components/prism-jsx.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,35 @@

var javascript = Prism.util.clone(Prism.languages.javascript);

var buildTagPattern = function (backrefNum, onlyOpeningTag) {
return '<' +
// Optional / for closing tags
(onlyOpeningTag ? '' : '\\/?') +
// Tag name
'[\\w.:-]+\\s*' +
'(?:\\s+(?:' +
// Attribute name
'[\\w.:-]+(?:=(?:' +
// Quoted attribute value
'("|\')(?:\\\\[\\s\\S]|(?!\\' + backrefNum + ')[^\\\\])*\\' + backrefNum +
'|' +
// Unquoted attribute value
'[^\\s\'">=]+' +
'|' +
// Interpolation
'(?:\\{\\{?[^}]*\\}?\\})' +
'))?' +
'|' +
// Spread attributes
'\\{\\.{3}[a-z_$][\\w$]*(?:\\.[a-z_$][\\w$]*)*\\}' +
'))*' +
// Optional slash for self-closing tags
(onlyOpeningTag ? '' : '\\s*\\/?') +
'>';
};

Prism.languages.jsx = Prism.languages.extend('markup', javascript);
Prism.languages.jsx.tag.pattern= /<\/?[\w.:-]+\s*(?:\s+(?:[\w.:-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+|(?:\{\{?[^}]*\}?\})))?|\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}))*\s*\/?>/i;
Prism.languages.jsx.tag.pattern= new RegExp(buildTagPattern(1), 'i');

Prism.languages.jsx.tag.inside['attr-value'].pattern = /=(?!\{)(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">]+)/i;

Expand All @@ -21,14 +48,29 @@ var jsxExpression = Prism.util.clone(Prism.languages.jsx);

delete jsxExpression.punctuation;

Prism.languages.insertBefore('jsx', 'tag', {
'plain-text': {
pattern: new RegExp('(' + buildTagPattern(2, true) + ')[\\s\\S]*?(?=' + buildTagPattern(3) + ')', 'i'),
lookbehind: true,
inside: {
'script': {
// Allow for one level of nesting
pattern: /\{(?:\{[^}]*\}|[^}])+\}/i,
inside: jsxExpression,
'alias': 'language-javascript'
}
}
}
});

jsxExpression = Prism.languages.insertBefore('jsx', 'operator', {
'punctuation': /=(?={)|[{}[\];(),.:]/
'punctuation': /=(?={)|[{}[\];(),.:]/
}, { jsx: jsxExpression });

Prism.languages.insertBefore('inside', 'attr-value',{
'script': {
// Allow for one level of nesting
pattern: /=(\{(?:\{[^}]*\}|[^}])+\})/i,
pattern: /=\{(?:\{[^}]*\}|[^}])+\}/i,
inside: jsxExpression,
'alias': 'language-javascript'
}
Expand Down
2 changes: 1 addition & 1 deletion components/prism-jsx.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

67 changes: 67 additions & 0 deletions tests/languages/jsx/issue1294.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
export default () => (
<div>
<h1>Hi! I'm building a fake Gatsby site as part of a tutorial!</h1>
<p>
What do I like to do? Lots of course but definitely enjoy building
websites.
</p>
</div>
);

----------------------------------------------------

[
["keyword", "export"],
["keyword", "default"],
["punctuation", "("], ["punctuation", ")"], ["operator", "=>"], ["punctuation", "("],
["tag", [
["tag", [
["punctuation", "<"],
"div"
]],
["punctuation", ">"]
]],
["plain-text", []],
["tag", [
["tag", [
["punctuation", "<"],
"h1"
]],
["punctuation", ">"]
]],
["plain-text", ["Hi! I'm building a fake Gatsby site as part of a tutorial!"]],
["tag", [
["tag", [
["punctuation", "</"],
"h1"
]],
["punctuation", ">"]
]],
["tag", [
["tag", [
["punctuation", "<"],
"p"
]],
["punctuation", ">"]
]],
["plain-text", ["\r\n\t\t\tWhat do I like to do? Lots of course but definitely enjoy building\r\n\t\t\twebsites.\r\n\t\t"]],
["tag", [
["tag", [
["punctuation", "</"],
"p"
]],
["punctuation", ">"]
]],
["tag", [
["tag", [
["punctuation", "</"],
"div"
]],
["punctuation", ">"]
]],
["punctuation", ")"], ["punctuation", ";"]
]

----------------------------------------------------

See #1294.
55 changes: 55 additions & 0 deletions tests/languages/jsx/plain-text_feature.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<div>do return function</div>
<p>
this is not highlighted!
{this.props.name}
</p>

----------------------------------------------------

[
["tag", [
["tag", [
["punctuation", "<"],
"div"
]],
["punctuation", ">"]
]],
["plain-text", ["do return function"]],
["tag", [
["tag", [
["punctuation", "</"],
"div"
]],
["punctuation", ">"]
]],
["tag", [
["tag", [
["punctuation", "<"],
"p"
]],
["punctuation", ">"]
]],
["plain-text", [
"\r\n\tthis is not highlighted!\r\n\t",
["script", [
["punctuation", "{"],
["keyword", "this"],
["punctuation", "."],
"props",
["punctuation", "."],
"name",
["punctuation", "}"]
]]
]],
["tag", [
["tag", [
["punctuation", "</"],
"p"
]],
["punctuation", ">"]
]]
]

----------------------------------------------------

Checks for plain text between tags.
7 changes: 3 additions & 4 deletions tests/languages/tsx/tag_feature.test
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var myDivElement = <div className="foo" />;
var myElement = <MyComponent someProperty={true} />;
<div {...foo}>
<div {...foo}/>
class Test extends Component {
render() {
return <p onClick={this.clickHandler}>Hello world.</p>;
Expand Down Expand Up @@ -58,7 +58,7 @@ class Test extends Component {
["attr-value", "foo"],
["punctuation", "}"]
]],
["punctuation", ">"]
["punctuation", "/>"]
]],

["keyword", "class"],
Expand Down Expand Up @@ -87,8 +87,7 @@ class Test extends Component {
]],
["punctuation", ">"]
]],
"Hello world",
["punctuation", "."],
["plain-text", ["Hello world."]],
["tag", [
["tag", [
["punctuation", "</"],
Expand Down

0 comments on commit 7305739

Please sign in to comment.