UNPKG

8.98 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
7var prism = require('./prism.js');
8var theme = _interopDefault(require('../themes/duotoneDark'));
9var react = require('react');
10var react__default = _interopDefault(react);
11
12var defaultProps = {
13 // $FlowFixMe
14 Prism: prism,
15 theme: theme
16};
17
18function _defineProperty(obj, key, value) {
19 if (key in obj) {
20 Object.defineProperty(obj, key, {
21 value: value,
22 enumerable: true,
23 configurable: true,
24 writable: true
25 });
26 } else {
27 obj[key] = value;
28 }
29
30 return obj;
31}
32
33function _extends() {
34 _extends = Object.assign || function (target) {
35 for (var i = 1; i < arguments.length; i++) {
36 var source = arguments[i];
37
38 for (var key in source) {
39 if (Object.prototype.hasOwnProperty.call(source, key)) {
40 target[key] = source[key];
41 }
42 }
43 }
44
45 return target;
46 };
47
48 return _extends.apply(this, arguments);
49}
50
51var newlineRe = /\r\n|\r|\n/; // Empty lines need to contain a single empty token, denoted with { empty: true }
52
53var normalizeEmptyLines = function (line) {
54 if (line.length === 0) {
55 line.push({
56 types: ["plain"],
57 content: "",
58 empty: true
59 });
60 } else if (line.length === 1 && line[0].content === "") {
61 line[0].empty = true;
62 }
63};
64
65var appendTypes = function (types, add) {
66 var typesSize = types.length;
67
68 if (typesSize > 0 && types[typesSize - 1] === add) {
69 return types;
70 }
71
72 return types.concat(add);
73}; // Takes an array of Prism's tokens and groups them by line, turning plain
74// strings into tokens as well. Tokens can become recursive in some cases,
75// which means that their types are concatenated. Plain-string tokens however
76// are always of type "plain".
77// This is not recursive to avoid exceeding the call-stack limit, since it's unclear
78// how nested Prism's tokens can become
79
80
81var normalizeTokens = function (tokens) {
82 var typeArrStack = [[]];
83 var tokenArrStack = [tokens];
84 var tokenArrIndexStack = [0];
85 var tokenArrSizeStack = [tokens.length];
86 var i = 0;
87 var stackIndex = 0;
88 var currentLine = [];
89 var acc = [currentLine];
90
91 while (stackIndex > -1) {
92 while ((i = tokenArrIndexStack[stackIndex]++) < tokenArrSizeStack[stackIndex]) {
93 var content = void 0;
94 var types = typeArrStack[stackIndex];
95 var tokenArr = tokenArrStack[stackIndex];
96 var token = tokenArr[i]; // Determine content and append type to types if necessary
97
98 if (typeof token === "string") {
99 types = stackIndex > 0 ? types : ["plain"];
100 content = token;
101 } else {
102 types = appendTypes(types, token.type);
103
104 if (token.alias) {
105 types = appendTypes(types, token.alias);
106 }
107
108 content = token.content;
109 } // If token.content is an array, increase the stack depth and repeat this while-loop
110
111
112 if (typeof content !== "string") {
113 stackIndex++;
114 typeArrStack.push(types);
115 tokenArrStack.push(content);
116 tokenArrIndexStack.push(0);
117 tokenArrSizeStack.push(content.length);
118 continue;
119 } // Split by newlines
120
121
122 var splitByNewlines = content.split(newlineRe);
123 var newlineCount = splitByNewlines.length;
124 currentLine.push({
125 types: types,
126 content: splitByNewlines[0]
127 }); // Create a new line for each string on a new line
128
129 for (var i$1 = 1; i$1 < newlineCount; i$1++) {
130 normalizeEmptyLines(currentLine);
131 acc.push(currentLine = []);
132 currentLine.push({
133 types: types,
134 content: splitByNewlines[i$1]
135 });
136 }
137 } // Decreate the stack depth
138
139
140 stackIndex--;
141 typeArrStack.pop();
142 tokenArrStack.pop();
143 tokenArrIndexStack.pop();
144 tokenArrSizeStack.pop();
145 }
146
147 normalizeEmptyLines(currentLine);
148 return acc;
149};
150
151var themeToDict = function (theme, language) {
152 var plain = theme.plain; // $FlowFixMe
153
154 var base = Object.create(null);
155 var themeDict = theme.styles.reduce(function (acc, themeEntry) {
156 var languages = themeEntry.languages;
157 var style = themeEntry.style;
158
159 if (languages && !languages.includes(language)) {
160 return acc;
161 }
162
163 themeEntry.types.forEach(function (type) {
164 // $FlowFixMe
165 var accStyle = _extends({}, acc[type], style);
166
167 acc[type] = accStyle;
168 });
169 return acc;
170 }, base); // $FlowFixMe
171
172 themeDict.root = plain; // $FlowFixMe
173
174 themeDict.plain = _extends({}, plain, {
175 backgroundColor: null
176 });
177 return themeDict;
178};
179
180function objectWithoutProperties(obj, exclude) {
181 var target = {};
182
183 for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k) && exclude.indexOf(k) === -1) target[k] = obj[k];
184
185 return target;
186}
187
188var Highlight =
189/*@__PURE__*/
190function (Component) {
191 function Highlight() {
192 var this$1 = this;
193 var args = [],
194 len = arguments.length;
195
196 while (len--) args[len] = arguments[len];
197
198 Component.apply(this, args);
199
200 _defineProperty(this, "getThemeDict", function (props) {
201 if (this$1.themeDict !== undefined && props.theme === this$1.prevTheme && props.language === this$1.prevLanguage) {
202 return this$1.themeDict;
203 }
204
205 this$1.prevTheme = props.theme;
206 this$1.prevLanguage = props.language;
207 var themeDict = props.theme ? themeToDict(props.theme, props.language) : undefined;
208 return this$1.themeDict = themeDict;
209 });
210
211 _defineProperty(this, "getLineProps", function (ref) {
212 var key = ref.key;
213 var className = ref.className;
214 var style = ref.style;
215 var rest$1 = objectWithoutProperties(ref, ["key", "className", "style", "line"]);
216 var rest = rest$1;
217
218 var output = _extends({}, rest, {
219 className: "token-line",
220 style: undefined,
221 key: undefined
222 });
223
224 var themeDict = this$1.getThemeDict(this$1.props);
225
226 if (themeDict !== undefined) {
227 output.style = themeDict.plain;
228 }
229
230 if (style !== undefined) {
231 output.style = output.style !== undefined ? _extends({}, output.style, style) : style;
232 }
233
234 if (key !== undefined) {
235 output.key = key;
236 }
237
238 if (className) {
239 output.className += " " + className;
240 }
241
242 return output;
243 });
244
245 _defineProperty(this, "getStyleForToken", function (ref) {
246 var types = ref.types;
247 var empty = ref.empty;
248 var typesSize = types.length;
249 var themeDict = this$1.getThemeDict(this$1.props);
250
251 if (themeDict === undefined) {
252 return undefined;
253 } else if (typesSize === 1 && types[0] === "plain") {
254 return empty ? {
255 display: "inline-block"
256 } : undefined;
257 } else if (typesSize === 1 && !empty) {
258 return themeDict[types[0]];
259 }
260
261 var baseStyle = empty ? {
262 display: "inline-block"
263 } : {}; // $FlowFixMe
264
265 var typeStyles = types.map(function (type) {
266 return themeDict[type];
267 });
268 return Object.assign.apply(Object, [baseStyle].concat(typeStyles));
269 });
270
271 _defineProperty(this, "getTokenProps", function (ref) {
272 var key = ref.key;
273 var className = ref.className;
274 var style = ref.style;
275 var token = ref.token;
276 var rest$1 = objectWithoutProperties(ref, ["key", "className", "style", "token"]);
277 var rest = rest$1;
278
279 var output = _extends({}, rest, {
280 className: "token " + token.types.join(" "),
281 children: token.content,
282 style: this$1.getStyleForToken(token),
283 key: undefined
284 });
285
286 if (style !== undefined) {
287 output.style = output.style !== undefined ? _extends({}, output.style, style) : style;
288 }
289
290 if (key !== undefined) {
291 output.key = key;
292 }
293
294 if (className) {
295 output.className += " " + className;
296 }
297
298 return output;
299 });
300 }
301
302 if (Component) Highlight.__proto__ = Component;
303 Highlight.prototype = Object.create(Component && Component.prototype);
304 Highlight.prototype.constructor = Highlight;
305
306 Highlight.prototype.render = function render() {
307 var ref = this.props;
308 var Prism = ref.Prism;
309 var language = ref.language;
310 var code = ref.code;
311 var children = ref.children;
312 var themeDict = this.getThemeDict(this.props);
313 var grammar = Prism.languages[language];
314 var mixedTokens = grammar !== undefined ? Prism.tokenize(code, grammar, language) : [code];
315 var tokens = normalizeTokens(mixedTokens);
316 return children({
317 tokens: tokens,
318 className: "prism-code language-" + language,
319 style: themeDict !== undefined ? themeDict.root : {},
320 getLineProps: this.getLineProps,
321 getTokenProps: this.getTokenProps
322 });
323 };
324
325 return Highlight;
326}(react.Component);
327
328exports.Prism = prism;
329exports.default = Highlight;
330exports.defaultProps = defaultProps;