UNPKG

3.83 kBJavaScriptView Raw
1/*
2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15'use strict';
16
17var ParseException = require('@accordproject/concerto-cto').ParseException;
18var TemplateException = require('./templateexception');
19
20/**
21 * Minimum length of expected token
22 * @param {object} expected the expected token
23 * @return {number} the minimum length
24 */
25function maxOfExpected(expected) {
26 return Math.max.apply(null, expected.map(x => x.length));
27}
28
29/**
30 * Clean up expected tokens
31 * @param {object} expected the expected token
32 * @return {object} nicer looking expected tokens
33 */
34function cleanExpected(expected) {
35 return expected.map(x => new RegExp(/'[^']*'/).test(x) ? x.substr(1, x.length - 2) : x);
36}
37
38/**
39 * Throw a parse exception
40 * @param {string} markdown a markdown string
41 * @param {object} result the parsing failure
42 * @param {string} [fileName] - the fileName for the markdown (optional)
43 */
44function _throwParseException(markdown, result, fileName) {
45 // File location
46 var fileLocation = {};
47 var shortMessage;
48 var longMessage;
49 if (typeof result !== 'string') {
50 // Short message
51 shortMessage = "Parse error at line ".concat(result.index.line, " column ").concat(result.index.column);
52
53 // Location
54 var start = result.index;
55 var end = Object.assign({}, start);
56 end.offset = end.offset + 1;
57 end.column = end.column + 1;
58 fileLocation.start = start;
59 fileLocation.end = end;
60 var lines = markdown.split('\n');
61 var expected = result.expected;
62 var underline = line => {
63 var maxLength = line.length - (start.column - 1);
64 var maxExpected = maxOfExpected(cleanExpected(expected));
65 return '^'.repeat(maxLength < maxExpected ? maxLength : maxExpected);
66 };
67 var line = lines[start.line - 1];
68 var snippet = line + '\n' + ' '.repeat(start.column - 1) + underline(line);
69 var isEOF = x => {
70 if (x[0] && x[0] === 'EOF') {
71 return true;
72 } else {
73 return false;
74 }
75 };
76
77 // Long message
78 var expectedMessage = 'Expected: ' + (isEOF(expected) ? 'End of text' : expected.join(' or '));
79 longMessage = shortMessage + '\n' + snippet + '\n' + expectedMessage;
80 } else {
81 shortMessage = result;
82 longMessage = shortMessage;
83 fileLocation.start = {
84 offset: -1,
85 column: -1
86 };
87 fileLocation.end = {
88 offset: -1,
89 column: -1
90 };
91 }
92 throw new ParseException(shortMessage, fileLocation, fileName, longMessage, 'markdown-template');
93}
94
95/**
96 * Throw a template exception for the element
97 * @param {string} message - the error message
98 * @param {object} element the AST
99 * @throws {TemplateException}
100 */
101function _throwTemplateExceptionForElement(message, element) {
102 var fileName = 'text/grammar.tem.md';
103 //let column = element.fieldName.col;
104 //let line = element.fieldName.line;
105 var column = -1;
106 var line = -1;
107 var token = element && element.value ? element.value : ' ';
108 var endColumn = column + token.length;
109 var fileLocation = {
110 start: {
111 line,
112 column
113 },
114 end: {
115 line,
116 endColumn //XXX
117 }
118 };
119
120 throw new TemplateException(message, fileLocation, fileName, null, 'markdown-template');
121}
122module.exports._throwTemplateExceptionForElement = _throwTemplateExceptionForElement;
123module.exports._throwParseException = _throwParseException;
\No newline at end of file