├── .gitignore
├── README.md
├── package.json
├── src
├── index.jsx
├── index.less
├── less
│ └── prism.less
├── lib
│ ├── documentation.md
│ ├── normalize.less
│ ├── render-utils.js
│ └── theme-info.js
└── static
│ ├── index.html
│ ├── test-page.html
│ └── vendor
│ ├── less.min.js
│ ├── prism.js
│ └── react.min.js
├── tests
└── index.jsx
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | npm-debug.log*
2 | node_modules/
3 | .DS_Store
4 | www/
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Syntax highlighting theme generator
2 |
3 | A tool to generate syntax highlighting themes from .less source.
4 |
5 | ## Development
6 |
7 | ```
8 | npm install
9 | npm start
10 | ```
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "syntax-highlighting-theme-generator",
3 | "version": "0.0.1",
4 | "description": "A theme generator for javascript syntax highlighters",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "npm-run-all build:**",
8 | "start": "npm run build && npm-run-all --parallel server watch:**",
9 | "prebuild": "rimraf www && mkdirp www",
10 | "prestart": "npm run prebuild",
11 | "build:static": "cpx \"src/static/**/*\" www",
12 | "watch:static": "npm run build:static -- -w",
13 | "build:js": "webpack -p",
14 | "watch:js": "webpack -d --watch",
15 | "build:css": "npm run watch:css -- --no-watch",
16 | "watch:css": "autoless --autoprefix \"last 2 versions\" --source-map src www",
17 | "server": "live-server www --port=8888"
18 | },
19 | "author": "k88hudson",
20 | "license": "MPL-2.0",
21 | "dependencies": {
22 | "lodash.throttle": "3.0.4",
23 | "react": "0.13.3",
24 | "react-markdocs": "https://github.com/k88hudson/react-markdocs.git#811c16cc2b28f840bfdb6702501fbd462b11011a"
25 | },
26 | "engines": {
27 | "npm": ">=2.0.0"
28 | },
29 | "devDependencies": {
30 | "autoless": "^0.1.7",
31 | "babel-core": "^5.2.17",
32 | "babel-loader": "^5.0.0",
33 | "cpx": "^1.1.6",
34 | "inject-loader": "^2.0.1",
35 | "json-loader": "^0.5.2",
36 | "jsx-loader": "^0.13.2",
37 | "live-server": "^0.7.1",
38 | "mkdirp": "^0.5.0",
39 | "mocha": "^2.2.5",
40 | "npm-run-all": "^1.2.4",
41 | "rimraf": "^2.3.3",
42 | "should": "^7.0.4",
43 | "webpack": "^1.9.4"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/index.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react/addons');
2 | var Prism = require('prism');
3 | var less = require('less');
4 | var {Markdown} = require('react-markdocs');
5 | var throttle = require('lodash.throttle');
6 |
7 | var themeInfo = require('./lib/theme-info');
8 | var {renderStyles} = require('./lib/render-utils');
9 |
10 | // How many edits until we shake the button?
11 | var SHAKE_COUNT = 10;
12 |
13 | var ColorInput = React.createClass({
14 | render: function () {
15 | return (
16 |
17 |
18 |
19 |
20 |
@{this.props.label}
21 |
22 |
23 |
);
24 | }
25 | });
26 |
27 | var App = React.createClass({
28 | mixins: [React.addons.LinkedStateMixin],
29 | getInitialState: function () {
30 | return {
31 | colors: themeInfo.colors,
32 | css: '',
33 | updateCount: 0
34 | };
35 | },
36 | componentDidMount: function () {
37 |
38 | this.updateColors = throttle(() => {
39 | renderStyles(this.state.colors, (css) => {
40 | var updateCount = this.state.updateCount;
41 |
42 | // Scroll to examples on first user update
43 | if (updateCount === 1) this.scrollToExample();
44 |
45 | // Shake
46 | if (updateCount % SHAKE_COUNT === 0) {
47 | this.setState({shakeOn: true});
48 | setTimeout(() => this.setState({shakeOn: false}), 1000);
49 | }
50 |
51 | this.setState({css, updateCount: updateCount + 1});
52 | });
53 | }, 500);
54 |
55 | this.updateColors();
56 |
57 | },
58 | scrollToExample: function () {
59 | var previewEl = this.refs.preview.getDOMNode();
60 | var egTop = document.getElementById('examples').offsetTop;
61 | if (previewEl.scrollTop < egTop) previewEl.scrollTop = egTop - 30;
62 | },
63 | updateSwatch: function (color) {
64 | return (e) => {
65 | var colors = this.state.colors;
66 | colors[color] = e.target.value;
67 | this.setState({colors});
68 | this.updateColors();
69 | };
70 | },
71 | nicerType: function (html) {
72 | return html;
73 | },
74 | downloadURL: function () {
75 | return 'data:application/octet-stream;charset=utf-8,' + encodeURIComponent(this.state.css);
76 | },
77 | render: function () {
78 | return (
79 |
80 |
81 |
82 | {Object.keys(themeInfo.sections).map(group => {
83 | return (
84 |
{group}
85 | {Object.keys(themeInfo.sections[group]).map(color => {
86 | return ();
91 | })}
92 | );
93 | })}
94 |
95 |
96 |
97 |
111 |
);
112 | }
113 | });
114 |
115 | React.render(, document.getElementById('app'));
116 |
--------------------------------------------------------------------------------
/src/index.less:
--------------------------------------------------------------------------------
1 | @bodyColor: #545252;
2 | @btnColor: #69A0FC;
3 | @sidebarBg: #282A36;
4 | @sidebarWidth: 520px;
5 |
6 | @import './lib/normalize';
7 | @import './less/prism';
8 |
9 | * {
10 | box-sizing: border-box;
11 | }
12 |
13 | html,
14 | body,
15 | #app {
16 | height: 100%;
17 | }
18 |
19 | body {
20 | font-family: Merriweather, sans-serif;
21 | color: @bodyColor;
22 | line-height: 1.8;
23 | }
24 |
25 | .cf() {
26 | &:before,
27 | &:after {
28 | content: " ";
29 | display: table;
30 | }
31 |
32 | &:after {
33 | clear: both;
34 | }
35 | }
36 |
37 | *[hidden] {
38 | display: none !important;
39 | }
40 |
41 |
42 | button,
43 | .btn {
44 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
45 | border: none;
46 | padding: 10px 20px;
47 | background: @btnColor;
48 | color: white;
49 | border-radius: 3px;
50 | font-size: inherit;
51 | text-decoration: none;
52 | display: inline-block;
53 | box-shadow: 0px 2px 0px darken(@btnColor, 10%);
54 | &:hover {
55 | background: lighten(@btnColor, 5%);
56 | }
57 | }
58 |
59 | :not(pre) > code {
60 | background: @inlineCodeBackground;
61 | color: @inlineCodeColor;
62 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
63 | font-size: 0.8em;
64 | padding: .1em .3em;
65 | border-radius: .3em;
66 | }
67 |
68 | a {
69 | background: #FFFAEB;
70 | border-bottom: 1px solid #FFCD36;
71 | text-decoration: none;
72 | color: black;
73 | padding: 5px 0;
74 | &:hover {
75 | background: #FFE69C;
76 | }
77 | }
78 |
79 |
80 | /*********************************************************
81 | * Color demo
82 | */
83 |
84 | .container {
85 | height: 100%;
86 | display: flex;
87 | pre[class*=language-] {
88 | width: 100%;
89 | overflow: hidden;
90 | margin: 0;
91 | }
92 | pre[class*=language-]+pre[class*=language-]{
93 | margin-top: 20px;
94 | }
95 | > div {
96 | height: 100%;
97 | overflow-y: auto;
98 | }
99 | > .preview {
100 | flex-grow: 1;
101 | }
102 | }
103 |
104 | /*********************************************************
105 | * Download
106 | */
107 |
108 | .download {
109 | position: fixed;
110 | bottom: -70px;
111 | height: 68px;
112 | left: @sidebarWidth;
113 | right: 0;
114 | z-index: 1000;
115 | padding: 10px;
116 | display: flex;
117 | align-items: center;
118 | justify-content: flex-end;
119 | background: fade(white, 75%);
120 | transition: all 0.2s ease-in-out;
121 |
122 | &.download-on {
123 | bottom: 0;
124 | }
125 | }
126 |
127 | // Thanks @flukeout!
128 | .shake {
129 | -webkit-animation: shake .1s 5;
130 | -moz-animation: shake .1s 5;
131 | }
132 | @-webkit-keyframes shake {
133 | 0% { -webkit-transform: translateX(0); }
134 | 25% { -webkit-transform: translateX(-5px); }
135 | 50% { -webkit-transform: translateX(0); }
136 | 75% { -webkit-transform: translateX(5px); }
137 | }
138 | @keyframes shake {
139 | 0% { transform: translateX(0); }
140 | 25% { transform: translateX(-5px); }
141 | 50% { transform: translateX(0); }
142 | 75% { transform: translateX(5px); }
143 | }
144 |
145 |
146 | /*********************************************************
147 | * Sidebar
148 | */
149 |
150 | .sidebar {
151 | position: relative;
152 | width: @sidebarWidth;
153 | flex-shrink: 0;
154 | line-height: 1.5;
155 | background: @sidebarBg;
156 | height: 100%;
157 | overflow: hidden;
158 |
159 | .color-wrapper {
160 | height: 100%;
161 | padding: 20px 30px 40px;
162 | overflow-x: hidden;
163 | overflow-y: scroll;
164 | }
165 |
166 | h3 {
167 | color: fade(white, 80%);
168 | font-weight: 400;
169 | }
170 |
171 | input {
172 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
173 | font-size: inherit;
174 | border: none;
175 | background: darken(@sidebarBg, 3%);
176 | color: white;
177 | border-radius: 3px;
178 | margin-top: 5px;
179 | padding: 10px;
180 | transition: all 0.2s ease-in-out;
181 | &:focus {
182 | outline: none;
183 | background: white;
184 | color: @sidebarBg;
185 | }
186 | }
187 |
188 | code {
189 | background: none;
190 | padding: 0;
191 | color: fade(white, 80%);
192 | }
193 | }
194 |
195 | .form-group {
196 | .cf;
197 | margin-right: -5%;
198 | }
199 | .color {
200 | float: left;
201 | width: 45%;
202 | margin-right: 5%;
203 | margin-bottom: 30px;
204 | input {
205 | width: 100%;
206 | }
207 | .title {
208 | white-space: nowrap;
209 | overflow: hidden;
210 | text-overflow: ellipsis;
211 | }
212 | }
213 |
214 | .color-demo {
215 | input {
216 | opacity: 0;
217 | position: absolute;
218 | top: 0;
219 | left: 0;
220 | width: 100%;
221 | height: 100%;
222 | }
223 | border-radius: 3px;
224 | position: relative;
225 | height: 30px;
226 | width: 30px;
227 | display: inline-block;
228 | vertical-align: middle;
229 | margin-right: 10px;
230 | }
231 |
232 |
233 | /*********************************************************
234 | * Preview
235 | */
236 |
237 | .preview {
238 | position: relative;
239 | padding: 40px 30px 60px 80px;
240 | h1, h2, h3, h4, p {
241 | max-width: 600px;
242 | margin-top: 20px 0;
243 | }
244 |
245 | h1, h2 {
246 | line-height: 1.3;
247 | }
248 |
249 | h2 {
250 | margin-top: 60px;
251 | font-size: 28px;
252 | }
253 |
254 | h3 {
255 | font-weight: normal;
256 | color: #999;
257 | }
258 |
259 | p {
260 | line-height: 1.9;
261 | }
262 |
263 | }
264 |
--------------------------------------------------------------------------------
/src/less/prism.less:
--------------------------------------------------------------------------------
1 | /* http://k88hudson.github.io/react-markdocs */
2 | /**
3 | * @author k88hudson
4 | *
5 | * Based on prism.js default theme for JavaScript, CSS and HTML
6 | * Based on dabblet (http://dabblet.com)
7 | * @author Lea Verou
8 | */
9 |
10 | @fontSize: 13px;
11 | @textShadow: none;
12 | @fontFamily: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
13 | @lineHeight: 1.5;
14 | @tabSize: 4;
15 | @paddingTop: 1em;
16 |
17 | @blockBackground: #F8F5EC;
18 | @baseColor: #5C6E74;
19 |
20 | @commentColor: #93A1A1; //
21 | @punctuationColor: #999; //
22 | @propertyColor: #905;
23 | @selectorColor: #690;
24 | @operatorColor: #a67f59;
25 | @operatorBg: hsla(0, 0%, 100%, .5);
26 | @variableColor: #e90;
27 | @functionColor: #DD4A68;
28 | @keywordColor: #07a;
29 | @selectedColor: #b3d4fc;
30 |
31 | @inlineCodeColor: #DB4C69;
32 | @inlineCodeBackground: #F9F2F4;
33 |
34 | @highlightBackground: #F7EBC6;
35 | @highlightAccent: #F7D87C;
36 |
37 |
38 | /*********************************************************
39 | * General
40 | */
41 |
42 | pre[class*="language-"],
43 | code[class*="language-"] {
44 | color: @baseColor;
45 | font-size: @fontSize;
46 | text-shadow: @textShadow;
47 | font-family: @fontFamily;
48 | direction: ltr;
49 | text-align: left;
50 | white-space: pre;
51 | word-spacing: normal;
52 | word-break: normal;
53 | line-height: @lineHeight;
54 |
55 | -moz-tab-size: @tabSize;
56 | -o-tab-size: @tabSize;
57 | tab-size: @tabSize;
58 |
59 | -webkit-hyphens: none;
60 | -moz-hyphens: none;
61 | -ms-hyphens: none;
62 | hyphens: none;
63 |
64 | &::selection,
65 | &::mozselection {
66 | text-shadow: none;
67 | background: @selectedColor;
68 | }
69 |
70 | @media print {
71 | text-shadow: none;
72 | }
73 |
74 | }
75 |
76 | // Blocks
77 | pre[class*="language-"] {
78 | padding: @paddingTop;
79 | margin: .5em 0;
80 | overflow: auto;
81 |
82 | background: @blockBackground;
83 | }
84 |
85 | // Inline code
86 | :not(pre) > code[class*="language-"] {
87 | padding: .1em .3em;
88 | border-radius: .3em;
89 | color: @inlineCodeColor;
90 | background: @inlineCodeBackground;
91 | }
92 |
93 | /*********************************************************
94 | * Tokens
95 | */
96 |
97 | .namespace {
98 | opacity: .7;
99 | }
100 |
101 | .token.comment,
102 | .token.prolog,
103 | .token.doctype,
104 | .token.cdata {
105 | color: @commentColor;
106 | }
107 |
108 | .token.punctuation {
109 | color: @punctuationColor;
110 | }
111 |
112 | .token.property,
113 | .token.tag,
114 | .token.boolean,
115 | .token.number,
116 | .token.constant,
117 | .token.symbol,
118 | .token.deleted {
119 | color: @propertyColor;
120 | }
121 |
122 | .token.selector,
123 | .token.attr-name,
124 | .token.string,
125 | .token.char,
126 | .token.builtin,
127 | .token.inserted {
128 | color: @selectorColor;
129 | }
130 |
131 | .token.operator,
132 | .token.entity,
133 | .token.url,
134 | .language-css .token.string,
135 | .style .token.string {
136 | color: @operatorColor;
137 | background: @operatorBg;
138 | }
139 |
140 | .token.atrule,
141 | .token.attr-value,
142 | .token.keyword {
143 | color: @keywordColor;
144 | }
145 |
146 | .token.function {
147 | color: @functionColor;
148 | }
149 |
150 | .token.regex,
151 | .token.important,
152 | .token.variable {
153 | color: @variableColor;
154 | }
155 |
156 | .token.important,
157 | .token.bold {
158 | font-weight: bold;
159 | }
160 | .token.italic {
161 | font-style: italic;
162 | }
163 |
164 | .token.entity {
165 | cursor: help;
166 | }
167 |
168 | /*********************************************************
169 | * Line highlighting
170 | */
171 |
172 | pre[data-line] {
173 | position: relative;
174 | }
175 |
176 | pre[class*="language-"] > code[class*="language-"] {
177 | position: relative;
178 | z-index: 1;
179 | }
180 |
181 | .line-highlight {
182 | position: absolute;
183 | left: 0;
184 | right: 0;
185 | padding: inherit 0;
186 | margin-top: @paddingTop;
187 |
188 | background: @highlightBackground;
189 | box-shadow: inset 5px 0 0 @highlightAccent;
190 |
191 | z-index: 0;
192 |
193 | pointer-events: none;
194 |
195 | line-height: inherit;
196 | white-space: pre;
197 | }
198 |
--------------------------------------------------------------------------------
/src/lib/documentation.md:
--------------------------------------------------------------------------------
1 | # Introducing the Syntax
Highlighting Theme Generator
2 |
3 | ### Forget trying to memorize class names and visualise hex colors. Writing a custom theme for your favourite syntax highlighter doesn't have to be hard!
4 |
5 |
6 | Just edit the values on the left and press the **Download CSS** button when you're done. You can also view the [source .less file](https://github.com/k88hudson/react-markdocs/blob/master/src/markdocs.less) if you're into that too.
7 |
8 | *Currently this tool only supports syntax highlighting for [Prism.js](http://prismjs.com), but I'm planning to add more in the near future.*
9 |
10 | ## Examples
11 |
12 | ### Inline code
13 |
14 | This is some inline code
in a paragraph.
15 |
16 | ### React JSX with line highlighting
17 |
18 | ```jsx{2}
19 | var ProfileLink = React.createClass({
20 | render: function() {
21 | return (
22 |
23 | {this.props.username}
24 |
25 | );
26 | }
27 | });
28 | ```
29 |
30 | ### Javascript
31 |
32 | ```javascript
33 | import {x, y} as p from 'point';
34 | const ANSWER = 42;
35 |
36 | class Car extends Vehicle {
37 | constructor(speed, cost) {
38 | super(speed);
39 |
40 | var c = Symbol('cost');
41 | this[c] = cost;
42 |
43 | this.intro = `This is a car runs at
44 | ${speed}.`;
45 | }
46 | }
47 |
48 | for (let num of [1, 2, 3]) {
49 | console.log(num + 0b111110111);
50 | }
51 |
52 | function $initHighlight(block, flags) {
53 | try {
54 | if (block.className.search(/\bno\-highlight\b/) != -1)
55 | return processBlock(block.function, true, 0x0F) + ' class=""';
56 | } catch (e) {
57 | /* handle exception */
58 | var e4x =
59 | ;
61 | }
62 | for (var i = 0 / 2; i < classes.length; i++) {
63 | // "0 / 2" should not be parsed as regexp
64 | if (checkCondition(classes[i]) === undefined)
65 | return /\d+[\s/]/g;
66 | }
67 | console.log(Array.every(classes, Boolean));
68 | }
69 |
70 | export $initHighlight;
71 | ```
72 |
73 | ### HTML
74 |
75 | ```markup
76 |
77 |
78 |
79 |
80 | Hello world
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | ```
92 |
93 | ### CSS
94 |
95 | ```css
96 | /*********************************************************
97 | * General
98 | */
99 | pre[class*="language-"],
100 | code {
101 | color: #5c6e74;
102 | font-size: 13px;
103 | text-shadow: none;
104 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
105 | direction: ltr;
106 | text-align: left;
107 | white-space: pre;
108 | word-spacing: normal;
109 | word-break: normal;
110 | line-height: 1.5;
111 | tab-size: 4;
112 | hyphens: none;
113 | }
114 | pre[class*="language-"]::selection,
115 | code::selection {
116 | text-shadow: none;
117 | background: #b3d4fc;
118 | }
119 | @media print {
120 | pre[class*="language-"],
121 | code {
122 | text-shadow: none;
123 | }
124 | }
125 | pre[class*="language-"] {
126 | padding: 1em;
127 | margin: .5em 0;
128 | overflow: auto;
129 | background: #f8f5ec;
130 | }
131 | :not(pre) > code {
132 | padding: .1em .3em;
133 | border-radius: .3em;
134 | color: #db4c69;
135 | background: #f9f2f4;
136 | }
137 | ```
138 |
--------------------------------------------------------------------------------
/src/lib/normalize.less:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2 |
3 | /**
4 | * 1. Set default font family to sans-serif.
5 | * 2. Prevent iOS text size adjust after orientation change, without disabling
6 | * user zoom.
7 | */
8 |
9 | html {
10 | font-family: sans-serif; /* 1 */
11 | -ms-text-size-adjust: 100%; /* 2 */
12 | -webkit-text-size-adjust: 100%; /* 2 */
13 | }
14 |
15 | /**
16 | * Remove default margin.
17 | */
18 |
19 | body {
20 | margin: 0;
21 | }
22 |
23 | /* HTML5 display definitions
24 | ========================================================================== */
25 |
26 | /**
27 | * Correct `block` display not defined for any HTML5 element in IE 8/9.
28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11
29 | * and Firefox.
30 | * Correct `block` display not defined for `main` in IE 11.
31 | */
32 |
33 | article,
34 | aside,
35 | details,
36 | figcaption,
37 | figure,
38 | footer,
39 | header,
40 | hgroup,
41 | main,
42 | menu,
43 | nav,
44 | section,
45 | summary {
46 | display: block;
47 | }
48 |
49 | /**
50 | * 1. Correct `inline-block` display not defined in IE 8/9.
51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
52 | */
53 |
54 | audio,
55 | canvas,
56 | progress,
57 | video {
58 | display: inline-block; /* 1 */
59 | vertical-align: baseline; /* 2 */
60 | }
61 |
62 | /**
63 | * Prevent modern browsers from displaying `audio` without controls.
64 | * Remove excess height in iOS 5 devices.
65 | */
66 |
67 | audio:not([controls]) {
68 | display: none;
69 | height: 0;
70 | }
71 |
72 | /**
73 | * Address `[hidden]` styling not present in IE 8/9/10.
74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
75 | */
76 |
77 | [hidden],
78 | template {
79 | display: none !important;
80 | }
81 |
82 | /* Links
83 | ========================================================================== */
84 |
85 | /**
86 | * Remove the gray background color from active links in IE 10.
87 | */
88 |
89 | a {
90 | background-color: transparent;
91 | }
92 |
93 | /**
94 | * Improve readability when focused and also mouse hovered in all browsers.
95 | */
96 |
97 | a:active,
98 | a:hover {
99 | outline: 0;
100 | }
101 |
102 | /* Text-level semantics
103 | ========================================================================== */
104 |
105 | /**
106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
107 | */
108 |
109 | abbr[title] {
110 | border-bottom: 1px dotted;
111 | }
112 |
113 | /**
114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
115 | */
116 |
117 | b,
118 | strong {
119 | font-weight: bold;
120 | }
121 |
122 | /**
123 | * Address styling not present in Safari and Chrome.
124 | */
125 |
126 | dfn {
127 | font-style: italic;
128 | }
129 |
130 | /**
131 | * Address variable `h1` font-size and margin within `section` and `article`
132 | * contexts in Firefox 4+, Safari, and Chrome.
133 | */
134 |
135 | h1 {
136 | font-size: 2em;
137 | margin: 0.67em 0;
138 | }
139 |
140 | /**
141 | * Address styling not present in IE 8/9.
142 | */
143 |
144 | mark {
145 | background: #ff0;
146 | color: #000;
147 | }
148 |
149 | /**
150 | * Address inconsistent and variable font size in all browsers.
151 | */
152 |
153 | small {
154 | font-size: 80%;
155 | }
156 |
157 | /**
158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
159 | */
160 |
161 | sub,
162 | sup {
163 | font-size: 75%;
164 | line-height: 0;
165 | position: relative;
166 | vertical-align: baseline;
167 | }
168 |
169 | sup {
170 | top: -0.5em;
171 | }
172 |
173 | sub {
174 | bottom: -0.25em;
175 | }
176 |
177 | /* Embedded content
178 | ========================================================================== */
179 |
180 | /**
181 | * Remove border when inside `a` element in IE 8/9/10.
182 | */
183 |
184 | img {
185 | border: 0;
186 | }
187 |
188 | /**
189 | * Correct overflow not hidden in IE 9/10/11.
190 | */
191 |
192 | svg:not(:root) {
193 | overflow: hidden;
194 | }
195 |
196 | /* Grouping content
197 | ========================================================================== */
198 |
199 | /**
200 | * Address margin not present in IE 8/9 and Safari.
201 | */
202 |
203 | figure {
204 | margin: 1em 40px;
205 | }
206 |
207 | /**
208 | * Address differences between Firefox and other browsers.
209 | */
210 |
211 | hr {
212 | -moz-box-sizing: content-box;
213 | box-sizing: content-box;
214 | height: 0;
215 | }
216 |
217 | /**
218 | * Contain overflow in all browsers.
219 | */
220 |
221 | pre {
222 | overflow: auto;
223 | }
224 |
225 | /**
226 | * Address odd `em`-unit font size rendering in all browsers.
227 | */
228 |
229 | code,
230 | kbd,
231 | pre,
232 | samp {
233 | font-family: monospace, monospace;
234 | font-size: 1em;
235 | }
236 |
237 | /* Forms
238 | ========================================================================== */
239 |
240 | /**
241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited
242 | * styling of `select`, unless a `border` property is set.
243 | */
244 |
245 | /**
246 | * 1. Correct color not being inherited.
247 | * Known issue: affects color of disabled elements.
248 | * 2. Correct font properties not being inherited.
249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
250 | */
251 |
252 | button,
253 | input,
254 | optgroup,
255 | select,
256 | textarea {
257 | color: inherit; /* 1 */
258 | font: inherit; /* 2 */
259 | margin: 0; /* 3 */
260 | outline: 0;
261 | }
262 |
263 | /**
264 | * Address `overflow` set to `hidden` in IE 8/9/10/11.
265 | */
266 |
267 | button {
268 | overflow: visible;
269 | }
270 |
271 | /**
272 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
273 | * All other form control elements do not inherit `text-transform` values.
274 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
275 | * Correct `select` style inheritance in Firefox.
276 | */
277 |
278 | button,
279 | select {
280 | text-transform: none;
281 | }
282 |
283 | /**
284 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
285 | * and `video` controls.
286 | * 2. Correct inability to style clickable `input` types in iOS.
287 | * 3. Improve usability and consistency of cursor style between image-type
288 | * `input` and others.
289 | */
290 |
291 | button,
292 | html input[type="button"], /* 1 */
293 | input[type="reset"],
294 | input[type="submit"] {
295 | -webkit-appearance: button; /* 2 */
296 | cursor: pointer; /* 3 */
297 | }
298 |
299 | /**
300 | * Re-set default cursor for disabled elements.
301 | */
302 |
303 | button[disabled],
304 | html input[disabled] {
305 | cursor: default;
306 | }
307 |
308 | /**
309 | * Remove inner padding and border in Firefox 4+.
310 | */
311 |
312 | button::-moz-focus-inner,
313 | input::-moz-focus-inner {
314 | border: 0;
315 | padding: 0;
316 | }
317 |
318 | /**
319 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in
320 | * the UA stylesheet.
321 | */
322 |
323 | input {
324 | line-height: normal;
325 | }
326 |
327 | /**
328 | * It's recommended that you don't attempt to style these elements.
329 | * Firefox's implementation doesn't respect box-sizing, padding, or width.
330 | *
331 | * 1. Address box sizing set to `content-box` in IE 8/9/10.
332 | * 2. Remove excess padding in IE 8/9/10.
333 | */
334 |
335 | input[type="checkbox"],
336 | input[type="radio"] {
337 | box-sizing: border-box; /* 1 */
338 | padding: 0; /* 2 */
339 | }
340 |
341 | /**
342 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain
343 | * `font-size` values of the `input`, it causes the cursor style of the
344 | * decrement button to change from `default` to `text`.
345 | */
346 |
347 | input[type="number"]::-webkit-inner-spin-button,
348 | input[type="number"]::-webkit-outer-spin-button {
349 | height: auto;
350 | }
351 |
352 | /**
353 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
354 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
355 | * (include `-moz` to future-proof).
356 | */
357 |
358 | input[type="search"] {
359 | -webkit-appearance: textfield; /* 1 */
360 | -moz-box-sizing: content-box;
361 | -webkit-box-sizing: content-box; /* 2 */
362 | box-sizing: content-box;
363 | }
364 |
365 | /**
366 | * Remove inner padding and search cancel button in Safari and Chrome on OS X.
367 | * Safari (but not Chrome) clips the cancel button when the search input has
368 | * padding (and `textfield` appearance).
369 | */
370 |
371 | input[type="search"]::-webkit-search-cancel-button,
372 | input[type="search"]::-webkit-search-decoration {
373 | -webkit-appearance: none;
374 | }
375 |
376 | /**
377 | * Define consistent border, margin, and padding.
378 | */
379 |
380 | fieldset {
381 | border: 1px solid #c0c0c0;
382 | margin: 0 2px;
383 | padding: 0.35em 0.625em 0.75em;
384 | }
385 |
386 | /**
387 | * 1. Correct `color` not being inherited in IE 8/9/10/11.
388 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
389 | */
390 |
391 | legend {
392 | border: 0; /* 1 */
393 | padding: 0; /* 2 */
394 | }
395 |
396 | /**
397 | * Remove default vertical scrollbar in IE 8/9/10/11.
398 | */
399 |
400 | textarea {
401 | overflow: auto;
402 | }
403 |
404 | /**
405 | * Don't inherit the `font-weight` (applied by a rule above).
406 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
407 | */
408 |
409 | optgroup {
410 | font-weight: bold;
411 | }
412 |
413 | /* Tables
414 | ========================================================================== */
415 |
416 | /**
417 | * Remove most spacing between table cells.
418 | */
419 |
420 | table {
421 | border-collapse: collapse;
422 | border-spacing: 0;
423 | }
424 |
425 | td,
426 | th {
427 | padding: 0;
428 | }
429 |
--------------------------------------------------------------------------------
/src/lib/render-utils.js:
--------------------------------------------------------------------------------
1 | var themeInfo = require('./theme-info');
2 | var headerString = '/* Generated with http://k88hudson.github.io/syntax-highlighting-theme-generator/www */\n';
3 | var lessString = headerString + require('raw!../less/prism.less');
4 |
5 | var renderUtils = {
6 |
7 | createColorVariableString(colors) {
8 | return themeInfo.colorNames.map(color => {
9 | return `@${color}: ${colors[color]};`;
10 | }).join('\n');
11 | },
12 |
13 | renderStyles(colors, callback) {
14 | var str = lessString;
15 | str = str + '\n\n' + renderUtils.createColorVariableString(colors);
16 |
17 | window.less.render(str)
18 | .then(function (output) {
19 | callback(output.css);
20 | }, function (err) {
21 | console.log(err);
22 | });
23 | }
24 | };
25 |
26 | module.exports = renderUtils;
27 |
--------------------------------------------------------------------------------
/src/lib/theme-info.js:
--------------------------------------------------------------------------------
1 | var sections = {
2 | 'Inline Code': {
3 | inlineCodeColor: '#DB4C69',
4 | inlineCodeBackground: '#F9F2F4'
5 | },
6 | 'Code Blocks': {
7 | blockBackground: '#F8F5EC',
8 | baseColor: '#5C6E74',
9 | selectedColor: '#b3d4fc'
10 | },
11 | 'Line Highlights': {
12 | highlightBackground: '#F7EBC6',
13 | highlightAccent: '#F7D87C'
14 | },
15 | 'Tokens': {
16 | commentColor: '#93A1A1',
17 | punctuationColor: '#999999',
18 | propertyColor: '#990055',
19 | selectorColor: '#669900',
20 | operatorColor: '#a67f59',
21 | operatorBg: '#FFFFFF',
22 | variableColor: '#ee9900',
23 | functionColor: '#DD4A68',
24 | keywordColor: '#0077aa'
25 | }
26 | };
27 |
28 | var colorNames = [];
29 | var colors = {};
30 |
31 | Object.keys(sections).forEach(key => {
32 | var group = sections[key];
33 | Object.keys(group).forEach(color => {
34 | colorNames.push(color);
35 | colors[color] = group[color];
36 | });
37 | });
38 |
39 | module.exports = {
40 | sections,
41 | colors,
42 | colorNames
43 | };
44 |
--------------------------------------------------------------------------------
/src/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Prism theme generator
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/static/test-page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Prism test
6 |
7 |
8 |
9 |
10 |
11 |
12 | import {x, y} as p from 'point';
13 | const ANSWER = 42;
14 |
15 | class Car extends Vehicle {
16 | constructor(speed, cost) {
17 | super(speed);
18 |
19 | var c = Symbol('cost');
20 | this[c] = cost;
21 |
22 | this.intro = `This is a car runs at
23 | ${speed}.`;
24 | }
25 | }
26 |
27 | for (let num of [1, 2, 3]) {
28 | console.log(num + 0b111110111);
29 | }
30 |
31 | function $initHighlight(block, flags) {
32 | try {
33 | if (block.className.search(/\bno\-highlight\b/) != -1)
34 | return processBlock(block.function, true, 0x0F) + ' class=""';
35 | } catch (e) {
36 | /* handle exception */
37 | var e4x =
38 | ;
40 | }
41 | for (var i = 0 / 2; i < classes.length; i++) {
42 | // "0 / 2" should not be parsed as regexp
43 | if (checkCondition(classes[i]) === undefined)
44 | return /\d+[\s/]/g;
45 | }
46 | console.log(Array.every(classes, Boolean));
47 | }
48 |
49 | export $initHighlight;
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/static/vendor/prism.js:
--------------------------------------------------------------------------------
1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+jsx&plugins=line-highlight */
2 | var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=_self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof a)){u.lastIndex=0;var m=u.exec(d);if(m){c&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),N=[p,1];b&&N.push(b);var O=new a(l,g?t.tokenize(m,g):m,h);N.push(O),w&&N.push(w),Array.prototype.splice.apply(r,N)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}t.hooks.run("wrap",i);var o="";for(var s in i.attributes)o+=s+'="'+(i.attributes[s]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+o+">"+i.content+""+i.tag+">"},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;_self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),_self.close()},!1),_self.Prism):_self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);;
3 | Prism.languages.markup={comment://,prolog:/<\?[\w\W]+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[^\s>\/]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(t){"entity"===t.type&&(t.attributes.title=t.content.replace(/&/,"&"))});;
4 | Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:/("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/