Skip to content
This repository was archived by the owner on Nov 28, 2022. It is now read-only.

Commit b70a72a

Browse files
author
Dom Harrington
committed
Add readme-syntax-highlighter package and use in ApiExplorer
1 parent f770940 commit b70a72a

File tree

18 files changed

+4254
-5
lines changed

18 files changed

+4254
-5
lines changed

packages/api-explorer-ui/__tests__/lib/generate-code-snippets.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ test('should generate a HTML snippet for each lang', () => {
1313

1414
Object.keys(snippets).forEach((lang) => {
1515
expect(typeof snippets[lang]).toBe('string');
16-
// expect(snippets[lang]).toEqual(expect.stringMatching(/cm-s-tomorrow-night/));
16+
expect(snippets[lang]).toEqual(expect.stringMatching(/cm-s-tomorrow-night/));
1717
});
1818
});

packages/api-explorer-ui/src/CodeSample.jsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ function CodeSample({ oas, setLanguage, path, method }) {
3434
<li key={lang}>
3535
<a
3636
role="link"
37+
href="#"
3738
className={`hub-lang-switch-${lang}`}
3839
onClick={setLanguage.bind(null, lang)}
3940
>{lang}</a>
@@ -73,9 +74,11 @@ function CodeSample({ oas, setLanguage, path, method }) {
7374
<i className="icon icon-sync icon-spin" ng-show="codeLoading" />
7475
{
7576
Object.keys(snippets).map(lang => (
76-
<pre key={lang} className={`tomorrow-night hub-lang hub-lang-${lang}`}>
77-
{snippets[lang]}
78-
</pre>
77+
<pre
78+
key={lang}
79+
className={`tomorrow-night hub-lang hub-lang-${lang}`}
80+
dangerouslySetInnerHTML={{ __html: snippets[lang] }}
81+
/>
7982
))
8083
}
8184
</div>

packages/api-explorer-ui/src/lib/generate-code-snippets.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const HTTPSnippet = require('httpsnippet');
22
const generateHar = require('./oas-to-har');
3+
const syntaxHighlighter = require('readme-syntax-highlighter');
34

45
const supportedLanguages = {
56
node: {
@@ -64,8 +65,9 @@ module.exports = (oas, path, method, languages) => {
6465
const snippet = new HTTPSnippet(har);
6566

6667
return languages.reduce((snippets, lang) => {
68+
const language = supportedLanguages[lang];
6769
return Object.assign(snippets, {
68-
[lang]: snippet.convert(...supportedLanguages[lang].httpsnippet),
70+
[lang]: syntaxHighlighter(snippet.convert(...language.httpsnippet), language.highlight),
6971
});
7072
}, {});
7173
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
root = true
2+
3+
# Unix-style newlines with a newline ending every file
4+
[*]
5+
end_of_line = lf
6+
insert_final_newline = true
7+
8+
[*js]
9+
charset = utf-8
10+
indent_style = space
11+
trim_trailing_whitespace = true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
**/node_modules
2+
coverage
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "airbnb-base",
3+
"rules": {
4+
5+
}
6+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
coverage
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"threshold": 30,
3+
"identifiers": true,
4+
"ignore": "test",
5+
"reporter": "default",
6+
"suppress": 100
7+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
language: node_js
2+
sudo: false
3+
node_js:
4+
- 6.0
5+
- 8.0
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Copyright (c) 2017, Dom Harrington <dom@harrington-mail.com>
2+
3+
Permission to use, copy, modify, and/or distribute this software for any purpose
4+
with or without fee is hereby granted, provided that the above copyright notice
5+
and this permission notice appear in all copies.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
9+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
11+
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
12+
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
13+
THIS SOFTWARE.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# readme-syntax-highlighter
2+
3+
Syntax highlighter used on ReadMe.io
4+
5+
[![build status](https://secure.travis-ci.org/readme/readme-syntax-highlighter.svg)](http://travis-ci.org/readme/readme-syntax-highlighter)
6+
[![dependency status](https://david-dm.org/readme/readme-syntax-highlighter.svg)](https://david-dm.org/readme/readme-syntax-highlighter)
7+
8+
## Installation
9+
10+
```
11+
npm install --save readme-syntax-highlighter
12+
```
13+
14+
## Usage
15+
16+
## Credits
17+
[Dom Harrington](https://github.com/readme/)
18+
19+
## License
20+
21+
ISC
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const CodeMirror = require('codemirror');
2+
require('codemirror/addon/runmode/runmode');
3+
require('codemirror/mode/meta.js');
4+
5+
require('codemirror/mode/shell/shell');
6+
require('codemirror/mode/javascript/javascript');
7+
require('codemirror/mode/ruby/ruby');
8+
require('codemirror/mode/python/python');
9+
10+
function esc(str) {
11+
return str.replace(/[<&]/g, ch => (ch === '&' ? '&amp;' : '&lt;'));
12+
}
13+
14+
module.exports = (code, lang) => {
15+
let output = '';
16+
17+
// if (!CodeMirror.modes[lang]) {
18+
// require(`codemirror/mode/${lang}/${lang}.js`);
19+
// }
20+
21+
let curStyle = null;
22+
let accum = '';
23+
function flush() {
24+
accum = esc(accum);
25+
if (curStyle) {
26+
output += `<span class="${curStyle.replace(/(^|\s+)/g, '$1cm-')}">${accum}</span>`;
27+
} else {
28+
output += accum;
29+
}
30+
}
31+
32+
CodeMirror.runMode(code, lang, (text, style) => {
33+
if (style !== curStyle) {
34+
flush();
35+
curStyle = style;
36+
accum = text;
37+
} else {
38+
accum += text;
39+
}
40+
});
41+
flush();
42+
43+
return output;
44+
};

packages/readme-syntax-highlighter/example.js

Whitespace-only changes.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
const codemirror = require('./codemirror');
2+
3+
function sanitizeCode(code) {
4+
const entityMap = {
5+
'&': '&amp;',
6+
'<': '&lt;',
7+
'>': '&gt;',
8+
'"': '&quot;',
9+
"'": '&#39;',
10+
'/': '&#x2F;',
11+
};
12+
13+
return String(code).replace(/[&<>"'/]/g, s => entityMap[s]);
14+
}
15+
16+
module.exports = (code, lang/* , dark */) => {
17+
if (lang === 'text') {
18+
return sanitizeCode(code);
19+
}
20+
21+
const theme = 'cm-s-tomorrow-night';
22+
// let theme = 'cm-s-neo';
23+
// if (dark) {
24+
// theme = 'cm-s-tomorrow-night';
25+
// }
26+
27+
// const modes = {
28+
// html: 'htmlmixed',
29+
// json: ['javascript', 'application/ld+json'],
30+
// text: ['null', 'text/plain'],
31+
// markdown: 'gfm',
32+
// stylus: 'scss',
33+
// bash: 'shell',
34+
// mysql: 'sql',
35+
// sql: ['sql', 'text/x-sql'],
36+
// curl: 'shell',
37+
// asp: 'clike',
38+
// csharp: ['clike', 'text/x-csharp'],
39+
// cplusplus: ['clike', 'text/x-c++src'],
40+
// c: 'clike',
41+
// java: ['clike', 'text/x-java'],
42+
// scala: ['clike', 'text/x-scala'],
43+
// objectivec: ['clike', 'text/x-objectivec'],
44+
// liquid: 'htmlmixed',
45+
// scss: 'css',
46+
// };
47+
48+
// let mode = lang;
49+
50+
// if (mode in modes) {
51+
// mode = modes[mode];
52+
// lang = mode;
53+
// if (_.isArray(mode)) {
54+
// lang = mode[0];
55+
// mode = mode[1];
56+
// }
57+
// }
58+
59+
// let highlighted = ;
60+
61+
// // Kind of a hack, but no other way to sanitize angular code
62+
// // Can't use ng-non-bindable because of jwt variables
63+
// highlighted = highlighted.replace(/{{/g, '&#123;<span></span>&#123;');
64+
// highlighted = highlighted.replace(/}}/g, '&#125;<span></span>&#125;');
65+
66+
return `<span class="${theme}">${codemirror(code, lang)}</span>`;
67+
};

0 commit comments

Comments
 (0)