UNPKG

4.78 kBJavaScriptView Raw
1'use strict';
2
3var uniq = require('lodash.uniq');
4
5var parsersDb = {
6 '.bash': { parserName: 'coffeeParser' },
7 '.c': { parserName: 'defaultParser' },
8 '.cjsx': { parserName: 'coffeeParser' },
9 '.coffee': { parserName: 'coffeeParser' },
10 '.cpp': { parserName: 'defaultParser' },
11 '.cs': { parserName: 'defaultParser' },
12 '.cson': { parserName: 'coffeeParser' },
13 '.css': { parserName: 'defaultParser' },
14 '.ejs': { parserName: 'ejsParser' },
15 '.erb': { parserName: 'ejsParser' },
16 '.erl': { parserName: 'erlangParser' },
17 '.es': { parserName: 'defaultParser' },
18 '.es6': { parserName: 'defaultParser' },
19 '.go': { parserName: 'defaultParser' },
20 '.h': { parserName: 'defaultParser' },
21 '.haml': { parserName: 'hamlParser' },
22 '.handlebars': { parserName: 'hbsParser' },
23 '.hbs': { parserName: 'hbsParser' },
24 '.hgn': { parserName: 'hbsParser' },
25 '.hogan': { parserName: 'hbsParser' },
26 '.hrl': { parserName: 'erlangParser' },
27 '.hs': { parserName: 'haskellParser' },
28 '.htm': { parserName: 'twigParser' },
29 '.html': { parserName: 'twigParser' },
30 '.jade': { parserName: 'jadeParser' },
31 '.js': { parserName: 'defaultParser' },
32 '.jsx': { parserName: 'defaultParser' },
33 '.less': { parserName: 'defaultParser' },
34 '.mustache': { parserName: 'hbsParser' },
35 '.pas': { parserName: 'pascalParser' },
36 '.php': { parserName: 'defaultParser', includedFiles: ['.html', '.js', '.css'] },
37 '.pl': { parserName: 'coffeeParser' },
38 '.pm': { parserName: 'coffeeParser' },
39 '.pug': { parserName: 'jadeParser' },
40 '.py': { parserName: 'pythonParser' },
41 '.rb': { parserName: 'coffeeParser' },
42 '.sass': { parserName: 'defaultParser' },
43 '.scss': { parserName: 'defaultParser' },
44 '.sh': { parserName: 'coffeeParser' },
45 '.ss': { parserName: 'ssParser' },
46 '.styl': { parserName: 'defaultParser' },
47 '.ts': { parserName: 'defaultParser' },
48 '.twig': { parserName: 'twigParser' },
49 '.zsh': { parserName: 'coffeeParser' },
50};
51
52// Support for associating an extension with a parser
53function associateExtWithParser(parsers) {
54 var keys = Object.keys(parsers);
55 if (keys.length === 0) {
56 return;
57 }
58 keys.forEach(function(ext) {
59 if (ext.length <= 1 || ext[0] !== '.') {
60 throw new Error('Cannot register extension: invalid extension ' + ext);
61 }
62 var parser = parsers[ext];
63 if (!parser || !parser.parserName) {
64 throw new Error('Cannot register extension: parser name missing.');
65 }
66 });
67
68 // Add any additional parsers.
69 Object.assign(parsersDb, parsers);
70}
71
72function isExtSupported(ext) {
73 return Boolean(parsersDb[ext]);
74}
75
76function parse(options) {
77 var ext = options.ext;
78 var content = options.content;
79 var fileName = options.fileName;
80 var customTags = options.customTags;
81 var withInlineFiles = options.withInlineFiles || false;
82 var associateParser = options.associateParser || {};
83
84 // Associate extensions with bundled parsers
85 associateExtWithParser(associateParser);
86
87 if (!isExtSupported(ext)) {
88 throw new Error('extension ' + ext + ' is not supported.');
89 }
90 if (customTags && !Array.isArray(customTags)) {
91 throw new TypeError('`customTags` must be an array');
92 }
93 var parseOptions = {
94 customTags: customTags
95 };
96 var originalParser = parsersDb[ext];
97 var parsers = [originalParser.parserName];
98
99 var includedFiles = originalParser.includedFiles || [];
100 if (withInlineFiles) {
101 includedFiles.forEach(function (ext) {
102 parsers.push(parsersDb[ext].parserName);
103 });
104 parsers = uniq(parsers);
105 }
106
107 var parsed = parsers
108 .map(function (parser) {
109 var parserFactory = require('./parsers/' + parser);
110 return parserFactory(parseOptions)(content, fileName);
111 })
112 .reduce(function (items, item) {
113 // flatten
114 return items.concat(item);
115 }, [])
116 .sort(function (item1, item2) {
117 return item1.line - item2.line;
118 });
119
120 return uniq(parsed, true, function (item) {
121 return {
122 line: item.line,
123 kind: item.kind,
124 text: item.text
125 };
126 });
127}
128
129/* legacy parse method, kept for backwards compatibility */
130function parseLegacy(ext, content, fileName, customTags, withInlineFiles) {
131 return parse({
132 ext: ext,
133 content: content,
134 fileName: fileName,
135 customTags: customTags,
136 withInlineFiles: withInlineFiles
137 });
138}
139
140exports.associateExtWithParser = associateExtWithParser;
141exports.isExtSupported = isExtSupported;
142exports.parse = parse;
143exports.parseLegacy = parseLegacy;