UNPKG

5.44 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const fs_1 = require("fs");
4const async_1 = require("async");
5const build_1 = require("./build");
6const buster = require.main.require('./src/meta').config['cache-buster'];
7const nconf = require.main.require('nconf');
8const url = nconf.get('url');
9let metaCache = null;
10function clearCache() {
11 metaCache = null;
12}
13exports.clearCache = clearCache;
14const escapeRegExpChars = (text) => text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
15const getTable = (callback) => {
16 if (metaCache) {
17 callback(null, metaCache);
18 return;
19 }
20 async_1.parallel({
21 table: next => fs_1.readFile(build_1.tableFile, next),
22 aliases: next => fs_1.readFile(build_1.aliasesFile, next),
23 ascii: next => fs_1.readFile(build_1.asciiFile, next),
24 characters: next => fs_1.readFile(build_1.charactersFile, next),
25 }, (err, results) => {
26 if (err) {
27 callback(err);
28 return;
29 }
30 try {
31 const ascii = JSON.parse(results.ascii.toString());
32 const asciiPattern = Object.keys(ascii)
33 .sort((a, b) => b.length - a.length)
34 .map(escapeRegExpChars)
35 .join('|');
36 const characters = JSON.parse(results.characters.toString());
37 const charPattern = Object.keys(characters)
38 .sort((a, b) => b.length - a.length)
39 .map(escapeRegExpChars)
40 .join('|');
41 metaCache = {
42 ascii,
43 characters,
44 table: JSON.parse(results.table.toString()),
45 aliases: JSON.parse(results.aliases.toString()),
46 asciiPattern: new RegExp(`(?:^|\\s)(${asciiPattern})(?=\\s|$)`, 'g'),
47 charPattern: new RegExp(charPattern, 'g'),
48 };
49 }
50 catch (e) {
51 callback(e);
52 return;
53 }
54 callback(null, metaCache);
55 });
56};
57const outsideCode = /(^|<\/code>)([^<]*|<(?!code[^>]*>))*(<code[^>]*>|$)/g;
58const outsideElements = /(<[^>]*>)?([^<>]*)/g;
59const emojiPattern = /:([a-z\-.+0-9_]+):/g;
60exports.buildEmoji = (emoji, whole) => {
61 if (emoji.image) {
62 const route = `${url}/plugins/nodebb-plugin-emoji/emoji/${emoji.pack}`;
63 return `<img
64 src="${route}/${emoji.image}?${buster}"
65 class="not-responsive emoji emoji-${emoji.pack} emoji--${emoji.name}"
66 title="${whole}"
67 alt="${emoji.character}"
68 />`;
69 }
70 return `<span
71 class="emoji emoji-${emoji.pack} emoji--${emoji.name}"
72 title="${whole}"
73 ><span>${emoji.character}</span></span>`;
74};
75const replaceAscii = (str, { ascii, asciiPattern, table }) => {
76 return str.replace(asciiPattern, (full, text) => {
77 const emoji = ascii[text] && table[ascii[text]];
78 if (emoji) {
79 return full.replace(text, exports.buildEmoji(emoji, text));
80 }
81 return text;
82 });
83};
84const replaceNative = (str, { characters, charPattern }) => {
85 return str.replace(charPattern, (char) => `:${characters[char]}:`);
86};
87const options = {
88 ascii: false,
89 native: false,
90};
91function setOptions(newOptions) {
92 Object.assign(options, newOptions);
93}
94exports.setOptions = setOptions;
95const parse = (content, callback) => {
96 getTable((err, store) => {
97 if (err) {
98 callback(err);
99 return;
100 }
101 const { table, aliases } = store;
102 const parsed = content.replace(outsideCode, outsideCodeStr => outsideCodeStr.replace(outsideElements, (whole, inside, outside) => {
103 let output = outside;
104 if (options.native) {
105 // avoid parsing native inside HTML tags
106 // also avoid converting ascii characters
107 output = output.replace(/(<[^>]+>)|([^0-9a-zA-Z`~!@#$%^&*()\-=_+{}|[\]\\:";'<>?,./\s\n]+)/g, (full, tag, text) => {
108 if (text) {
109 return replaceNative(text, store);
110 }
111 return full;
112 });
113 }
114 output = output.replace(emojiPattern, (whole, text) => {
115 const name = text.toLowerCase();
116 const emoji = table[name] || table[aliases[name]];
117 if (emoji) {
118 return exports.buildEmoji(emoji, whole);
119 }
120 return whole;
121 });
122 if (options.ascii) {
123 // avoid parsing native inside HTML tags
124 output = output.replace(/(<[^>]+>)|([^<]+)/g, (full, tag, text) => {
125 if (text) {
126 return replaceAscii(text, store);
127 }
128 return full;
129 });
130 }
131 return (inside || '') + (output || '');
132 }));
133 callback(null, parsed);
134 });
135};
136function raw(content, callback) {
137 parse(content, callback);
138}
139exports.raw = raw;
140function post(data, callback) {
141 parse(data.postData.content, (err, content) => {
142 if (err) {
143 callback(err);
144 return;
145 }
146 data.postData.content = content;
147 callback(null, data);
148 });
149}
150exports.post = post;
151//# sourceMappingURL=parse.js.map
\No newline at end of file