UNPKG

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