-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathparser.js
75 lines (63 loc) · 2.3 KB
/
parser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
"use strict";
const spawnSync = require("child_process").spawnSync;
function formatTextWithElmFormat(text) {
const executionResult = spawnSync("elm-format", ["--stdin"], {
input: text
});
const error = executionResult.stderr.toString();
if (error) {
throw new Error(error);
}
return executionResult;
}
/*
* Simply passing text to elm-format is not enough because of two problems:
*
* 1. If the code chunk contains no symbol assignments, elm-format fails.
* 2. `module Main exposing (..)` is always added if no module has been defined,
* which is not wanted in markdown code blocks.
*
* Both problems are related to https://github.com/avh4/elm-format/issues/65.
* Until this upstream issue is fixed, two custom patches are applied:
*
* 1. A temporary dummy statement is appended to text before sending it to elm-format.
* 2. If elm-format's result defines a module while the source does not,
* module definition is trimmed while working with a markdown code block.
*
* Please submit an issue to https://github.com/gicentre/prettier-plugin-elm/issues
* if there are any problems caused by the patches.
*/
const dummyStatement = "\ndummyPrettierPluginElmSymbol = identity";
const dummyStatementRegExp = /\s*dummyPrettierPluginElmSymbol =\s+identity\n$/;
const autogeneratedModuleDefinitionRegExp = /\s*module\s+Main\s+exposing\s+\(\s*\.\.\s*\)\s*/;
function parse(text, parsers, opts) {
// patch 1 (step 1/2)
const textToSend = `${text}${dummyStatement}`;
// extract formatted text from elm-format
const executionResult = formatTextWithElmFormat(textToSend);
let formattedText = executionResult.stdout.toString();
// path 1 (step 2/2)
formattedText = formattedText.replace(dummyStatementRegExp, "\n");
// patch 2
if (
opts.parentParser === "markdown" &&
autogeneratedModuleDefinitionRegExp.test(formattedText) &&
!autogeneratedModuleDefinitionRegExp.test(text)
) {
formattedText = formattedText.replace(
autogeneratedModuleDefinitionRegExp,
""
);
}
// return an AST with a single node that contain all the formatted elm code;
// no further splitting into smaller tokens is made
return {
ast_type: "elm-format",
body: formattedText,
comments: [],
end: text.length,
source: text,
start: 0
};
}
module.exports = parse;