beancount 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/src/classes/Node.mjs +7 -7
- package/build/src/classes/nodes/Blankline.mjs +2 -6
- package/build/src/classes/nodes/Transaction/Posting.mjs +1 -1
- package/build/src/genericParse.d.mts +8 -2
- package/build/src/genericParse.mjs +19 -20
- package/build/src/main.d.mts +1 -1
- package/build/src/parse.mjs +1 -1
- package/build/src/utils/SourceLocation.d.mts +27 -4
- package/build/src/utils/splitStringIntoSourceFragments.d.ts +1 -1
- package/build/src/utils/splitStringIntoSourceFragments.js +63 -11
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/build/src/classes/DateEntry.d.mts +0 -47
- package/build/src/classes/DateEntry.mjs +0 -60
- package/build/src/classes/Entry.d.mts +0 -92
- package/build/src/classes/Entry.mjs +0 -107
- package/build/src/classes/entryTypes/Balance.d.mts +0 -32
- package/build/src/classes/entryTypes/Balance.mjs +0 -50
- package/build/src/classes/entryTypes/Blankline.d.mts +0 -24
- package/build/src/classes/entryTypes/Blankline.mjs +0 -38
- package/build/src/classes/entryTypes/Close.d.mts +0 -20
- package/build/src/classes/entryTypes/Close.mjs +0 -31
- package/build/src/classes/entryTypes/Comment.d.mts +0 -25
- package/build/src/classes/entryTypes/Comment.mjs +0 -42
- package/build/src/classes/entryTypes/Commodity.d.mts +0 -20
- package/build/src/classes/entryTypes/Commodity.mjs +0 -31
- package/build/src/classes/entryTypes/Custom.d.mts +0 -23
- package/build/src/classes/entryTypes/Custom.mjs +0 -38
- package/build/src/classes/entryTypes/Document.d.mts +0 -22
- package/build/src/classes/entryTypes/Document.mjs +0 -34
- package/build/src/classes/entryTypes/Event.d.mts +0 -23
- package/build/src/classes/entryTypes/Event.mjs +0 -34
- package/build/src/classes/entryTypes/Include.d.mts +0 -20
- package/build/src/classes/entryTypes/Include.mjs +0 -31
- package/build/src/classes/entryTypes/Note.d.mts +0 -22
- package/build/src/classes/entryTypes/Note.mjs +0 -34
- package/build/src/classes/entryTypes/Open.d.mts +0 -27
- package/build/src/classes/entryTypes/Open.mjs +0 -66
- package/build/src/classes/entryTypes/Option.d.mts +0 -23
- package/build/src/classes/entryTypes/Option.mjs +0 -32
- package/build/src/classes/entryTypes/Pad.d.mts +0 -22
- package/build/src/classes/entryTypes/Pad.mjs +0 -33
- package/build/src/classes/entryTypes/Plugin.d.mts +0 -22
- package/build/src/classes/entryTypes/Plugin.mjs +0 -36
- package/build/src/classes/entryTypes/Poptag.d.mts +0 -21
- package/build/src/classes/entryTypes/Poptag.mjs +0 -34
- package/build/src/classes/entryTypes/Price.d.mts +0 -32
- package/build/src/classes/entryTypes/Price.mjs +0 -57
- package/build/src/classes/entryTypes/Pushtag.d.mts +0 -21
- package/build/src/classes/entryTypes/Pushtag.mjs +0 -34
- package/build/src/classes/entryTypes/Query.d.mts +0 -22
- package/build/src/classes/entryTypes/Query.mjs +0 -34
- package/build/src/classes/entryTypes/Transaction/Posting.d.mts +0 -59
- package/build/src/classes/entryTypes/Transaction/Posting.mjs +0 -97
- package/build/src/classes/entryTypes/Transaction/Tag.d.mts +0 -28
- package/build/src/classes/entryTypes/Transaction/Tag.mjs +0 -28
- package/build/src/classes/entryTypes/Transaction/index.d.mts +0 -70
- package/build/src/classes/entryTypes/Transaction/index.mjs +0 -193
- package/build/src/classes/entryTypes/index.d.mts +0 -19
- package/build/src/classes/entryTypes/index.mjs +0 -19
- package/build/src/entryTypeToClass.d.mts +0 -73
- package/build/src/entryTypeToClass.mjs +0 -37
- package/build/src/entryTypes.d.mts +0 -10
- package/build/src/entryTypes.mjs +0 -29
- package/build/src/utils/splitStringIntoUnparsedEntries.d.ts +0 -14
- package/build/src/utils/splitStringIntoUnparsedEntries.js +0 -48
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { genericParse } from '../genericParse.mjs';
|
|
2
|
-
import { stringAwareSplitLine } from '../utils/stringAwareSplitLine.mjs';
|
|
3
2
|
import { assignWithTrimmedStrings } from '../utils/assignWithTrimmedStrings.mjs';
|
|
4
3
|
import { defaultFormatOptions } from './ParseResult.mjs';
|
|
4
|
+
import { splitStringIntoSourceFragments } from '../utils/splitStringIntoSourceFragments.js';
|
|
5
5
|
/**
|
|
6
6
|
* Abstract base class for all nodes.
|
|
7
7
|
*
|
|
@@ -27,8 +27,11 @@ export class Node {
|
|
|
27
27
|
* @returns A new instance of the Node subclass
|
|
28
28
|
*/
|
|
29
29
|
static fromString(input) {
|
|
30
|
-
const sourceFragment =
|
|
31
|
-
|
|
30
|
+
const sourceFragment = splitStringIntoSourceFragments(input);
|
|
31
|
+
if (sourceFragment.length !== 1) {
|
|
32
|
+
throw new Error('Wrong directive count, expected 1');
|
|
33
|
+
}
|
|
34
|
+
const genericParseResult = genericParse(sourceFragment[0]);
|
|
32
35
|
const result = this.fromGenericParseResult(genericParseResult);
|
|
33
36
|
if (result.type !== genericParseResult.type) {
|
|
34
37
|
console.warn('Parse result type is not equal to requested object type, make sure the correct class is initiated');
|
|
@@ -70,7 +73,6 @@ export class Node {
|
|
|
70
73
|
* @param _formatOptions - Formatting options (unused in base implementation)
|
|
71
74
|
* @returns The formatted string representation of this node
|
|
72
75
|
*/
|
|
73
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
74
76
|
toFormattedString(_formatOptions = defaultFormatOptions) {
|
|
75
77
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
76
78
|
return this.toString();
|
|
@@ -103,6 +105,4 @@ export class Node {
|
|
|
103
105
|
* @param _ctor - The constructor to validate (unused at runtime)
|
|
104
106
|
* @internal
|
|
105
107
|
*/
|
|
106
|
-
export function assertNodeConstructor(
|
|
107
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
108
|
-
_ctor) { }
|
|
108
|
+
export function assertNodeConstructor(_ctor) { }
|
|
@@ -13,9 +13,7 @@ export class Blankline extends Node {
|
|
|
13
13
|
* @param _genericParseResult - Unused, blank lines have no content
|
|
14
14
|
* @returns A new Blankline instance
|
|
15
15
|
*/
|
|
16
|
-
static fromGenericParseResult(
|
|
17
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
18
|
-
_genericParseResult) {
|
|
16
|
+
static fromGenericParseResult(_genericParseResult) {
|
|
19
17
|
return new Blankline({});
|
|
20
18
|
}
|
|
21
19
|
/** @inheritdoc */
|
|
@@ -27,9 +25,7 @@ export class Blankline extends Node {
|
|
|
27
25
|
* @param _input - Unused, blank lines have no content
|
|
28
26
|
* @returns A new Blankline instance
|
|
29
27
|
*/
|
|
30
|
-
static fromString(
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
32
|
-
_input) {
|
|
28
|
+
static fromString(_input) {
|
|
33
29
|
return this.fromGenericParseResult({});
|
|
34
30
|
}
|
|
35
31
|
}
|
|
@@ -48,7 +48,7 @@ export class Posting {
|
|
|
48
48
|
const accountPattern = `([^ ]*)`;
|
|
49
49
|
const amountPattern = `([^A-Z;]*)`;
|
|
50
50
|
const costPattern = `{(.*)}`;
|
|
51
|
-
const pricePattern = `+(@|@@) +(?:(
|
|
51
|
+
const pricePattern = `+(@|@@) +(?:([^A-Z;]+) ${currencyPattern})`;
|
|
52
52
|
const amountCurrenyCostPattern = `${amountPattern}(?: +${currencyPattern})?(?: +${costPattern})?(?: ${pricePattern})?`;
|
|
53
53
|
const commentPattern = `( *;.*)?`;
|
|
54
54
|
const pattern = `^(?:${flagPattern})?${accountPattern}(?: +${amountCurrenyCostPattern})?${commentPattern}$`;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BeancountDirectiveNodeType, SyntheticNodeType } from './nodeTypeToClass.mjs';
|
|
2
2
|
import { type Metadata } from './utils/parseMetadata.mjs';
|
|
3
|
+
import { type SourceFragmentWithLocation } from './utils/SourceLocation.mjs';
|
|
3
4
|
/**
|
|
4
5
|
* The basic result structure from generic parsing of a Beancount directive.
|
|
5
6
|
* Contains the directive type, header line content, and any properties like comments.
|
|
@@ -57,6 +58,11 @@ export interface GenericParseResultTransaction extends Omit<GenericParseResultWi
|
|
|
57
58
|
flag?: string;
|
|
58
59
|
};
|
|
59
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Regex pattern to identify Beancount directives
|
|
63
|
+
* Generated from {@link NON_DATED_DIRECTIVE_TYPES} and {@link DATED_DIRECTIVE_TYPES} to ensure validation of directive types.
|
|
64
|
+
*/
|
|
65
|
+
export declare const beanCountDirectiveRegex: RegExp;
|
|
60
66
|
/**
|
|
61
67
|
* Performs generic parsing on a source fragment to extract common fields.
|
|
62
68
|
*
|
|
@@ -67,7 +73,7 @@ export interface GenericParseResultTransaction extends Omit<GenericParseResultWi
|
|
|
67
73
|
* - Handles transaction-specific parsing (flags, body lines)
|
|
68
74
|
* - Parses metadata for dated directives
|
|
69
75
|
*
|
|
70
|
-
* @param sourceFragment -
|
|
76
|
+
* @param sourceFragment - A single source fragment
|
|
71
77
|
* @returns A generic parse result object appropriate for the node type
|
|
72
78
|
*/
|
|
73
|
-
export declare const genericParse: (sourceFragment:
|
|
79
|
+
export declare const genericParse: (sourceFragment: SourceFragmentWithLocation) => GenericParseResult | GenericParseResultTransaction | GenericParseResultWithDate | GenericParseResultSyntheticNode;
|
|
@@ -28,16 +28,16 @@ function compileDirectivePattern() {
|
|
|
28
28
|
'txn',
|
|
29
29
|
'[^ ]' /* flag */,
|
|
30
30
|
].join('|');
|
|
31
|
-
const datePattern =
|
|
32
|
-
const datedDirectivesPattern = `${datePattern} +(
|
|
33
|
-
const pattern = `^(
|
|
31
|
+
const datePattern = `(?<date>\\d{4}-\\d{2}-\\d{2})`;
|
|
32
|
+
const datedDirectivesPattern = `${datePattern} +(?<dated_directive>${datedDirectivesTypePattern})`;
|
|
33
|
+
const pattern = `^(?<non_dated_directive>${nonDatedDirectivesPattern})|(?:^${datedDirectivesPattern}) `;
|
|
34
34
|
return new RegExp(pattern);
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
|
-
* Regex pattern to identify Beancount directives
|
|
37
|
+
* Regex pattern to identify Beancount directives
|
|
38
38
|
* Generated from {@link NON_DATED_DIRECTIVE_TYPES} and {@link DATED_DIRECTIVE_TYPES} to ensure validation of directive types.
|
|
39
39
|
*/
|
|
40
|
-
const beanCountDirectiveRegex = compileDirectivePattern();
|
|
40
|
+
export const beanCountDirectiveRegex = compileDirectivePattern();
|
|
41
41
|
/**
|
|
42
42
|
* Performs generic parsing on a source fragment to extract common fields.
|
|
43
43
|
*
|
|
@@ -48,26 +48,27 @@ const beanCountDirectiveRegex = compileDirectivePattern();
|
|
|
48
48
|
* - Handles transaction-specific parsing (flags, body lines)
|
|
49
49
|
* - Parses metadata for dated directives
|
|
50
50
|
*
|
|
51
|
-
* @param sourceFragment -
|
|
51
|
+
* @param sourceFragment - A single source fragment
|
|
52
52
|
* @returns A generic parse result object appropriate for the node type
|
|
53
53
|
*/
|
|
54
54
|
export const genericParse = (sourceFragment) => {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
const { fragment, directiveInfo } = sourceFragment;
|
|
56
|
+
const [firstLine, ...rest] = fragment;
|
|
57
|
+
if (!directiveInfo) {
|
|
58
|
+
// not a valid beancount directive, return it as a comment or a newline
|
|
59
|
+
if (firstLine.trim() === '') {
|
|
60
|
+
return { type: 'blankline', header: '', props: {}, synthetic: true };
|
|
61
|
+
}
|
|
61
62
|
return {
|
|
62
63
|
type: 'comment',
|
|
63
|
-
header:
|
|
64
|
+
header: fragment.join('\n'),
|
|
64
65
|
props: {},
|
|
65
66
|
synthetic: true,
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
69
|
const splitFirstLine = firstLine.split(' ');
|
|
69
|
-
if (
|
|
70
|
-
let type =
|
|
70
|
+
if (directiveInfo.date) {
|
|
71
|
+
let type = directiveInfo.directive;
|
|
71
72
|
let flag;
|
|
72
73
|
if (type.length === 1) {
|
|
73
74
|
flag = type;
|
|
@@ -79,27 +80,25 @@ export const genericParse = (sourceFragment) => {
|
|
|
79
80
|
type = 'transaction';
|
|
80
81
|
}
|
|
81
82
|
if (type === 'transaction') {
|
|
82
|
-
const date = splitFirstLine[0].trim();
|
|
83
83
|
const [header, ...comment] = splitFirstLine.slice(2).join(' ').split(';');
|
|
84
84
|
return {
|
|
85
85
|
type,
|
|
86
86
|
header: header.trim(),
|
|
87
87
|
body: rest.map((r) => r.trim()),
|
|
88
88
|
props: {
|
|
89
|
-
date,
|
|
89
|
+
date: directiveInfo.date,
|
|
90
90
|
flag,
|
|
91
91
|
comment: comment.length > 0 ? comment.join(';').trim() : undefined,
|
|
92
92
|
},
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
|
-
const date = splitFirstLine[0].trim();
|
|
96
95
|
const metadata = parseMetadata(rest);
|
|
97
96
|
const [header, ...comment] = splitFirstLine.slice(2).join(' ').split(';');
|
|
98
97
|
return {
|
|
99
98
|
type,
|
|
100
99
|
header: header.trim(),
|
|
101
100
|
props: {
|
|
102
|
-
date,
|
|
101
|
+
date: directiveInfo.date,
|
|
103
102
|
metadata,
|
|
104
103
|
comment: comment.length > 0 ? comment.join(';').trim() : undefined,
|
|
105
104
|
},
|
|
@@ -107,7 +106,7 @@ export const genericParse = (sourceFragment) => {
|
|
|
107
106
|
}
|
|
108
107
|
const [header, ...comment] = splitFirstLine.slice(1).join(' ').split(';');
|
|
109
108
|
return {
|
|
110
|
-
type:
|
|
109
|
+
type: directiveInfo.directive,
|
|
111
110
|
header: header.trim(),
|
|
112
111
|
props: {
|
|
113
112
|
metadata: parseMetadata(rest),
|
package/build/src/main.d.mts
CHANGED
|
@@ -27,7 +27,7 @@ export { deserializeNode, deserializeNodeFromString, deserializeNodes, deseriali
|
|
|
27
27
|
export { parseFile, type ParseFileOptions, type FileSystemHelpers, } from './parseFile.mjs';
|
|
28
28
|
export type { GenericParseResult, GenericParseResultWithDate, GenericParseResultTransaction, } from './genericParse.mjs';
|
|
29
29
|
export type { Metadata } from './utils/parseMetadata.mjs';
|
|
30
|
-
export { BeancountParseError, type SourceLocation, type SourceFragmentWithLocation, } from './utils/SourceLocation.mjs';
|
|
30
|
+
export { BeancountParseError, type DirectiveInfo, type SourceLocation, type SourceFragmentWithLocation, type SourceFragmentWithLocationDirective, type SourceFragmentWithLocationNonDirective, } from './utils/SourceLocation.mjs';
|
|
31
31
|
export { ParseResult, type ParseResultObj, type FormatOptions, type CalculateCurrencyColumnOptions, } from './classes/ParseResult.mjs';
|
|
32
32
|
export { Node, assertNodeConstructor } from './classes/Node.mjs';
|
|
33
33
|
export { DatedNode } from './classes/DatedNode.mjs';
|
package/build/src/parse.mjs
CHANGED
|
@@ -19,7 +19,7 @@ export const parseSourceFragment = (fragmentWithLocation) => {
|
|
|
19
19
|
const { fragment, location } = fragmentWithLocation;
|
|
20
20
|
let nodeType;
|
|
21
21
|
try {
|
|
22
|
-
const genericParseResult = genericParse(
|
|
22
|
+
const genericParseResult = genericParse(fragmentWithLocation);
|
|
23
23
|
const { type } = genericParseResult;
|
|
24
24
|
nodeType = type;
|
|
25
25
|
if (genericParseResult.synthetic) {
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Information about a parsed directive
|
|
3
|
+
*/
|
|
4
|
+
export interface DirectiveInfo {
|
|
5
|
+
date?: string;
|
|
6
|
+
directive: string;
|
|
7
|
+
}
|
|
1
8
|
/**
|
|
2
9
|
* Location information for a fragment of source code
|
|
3
10
|
*/
|
|
@@ -9,15 +16,30 @@ export interface SourceLocation {
|
|
|
9
16
|
/** Optional file path */
|
|
10
17
|
filePath?: string;
|
|
11
18
|
}
|
|
12
|
-
|
|
13
|
-
* A source fragment with associated location metadata
|
|
14
|
-
*/
|
|
15
|
-
export interface SourceFragmentWithLocation {
|
|
19
|
+
interface SourceFragmentWithLocationBase {
|
|
16
20
|
/** The lines of source code */
|
|
17
21
|
fragment: string[];
|
|
18
22
|
/** Location information */
|
|
19
23
|
location: SourceLocation;
|
|
20
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* A source fragment identified as a directive
|
|
27
|
+
*/
|
|
28
|
+
export interface SourceFragmentWithLocationDirective extends SourceFragmentWithLocationBase {
|
|
29
|
+
isDirective: true;
|
|
30
|
+
directiveInfo: DirectiveInfo;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A source fragment that is not a directive (e.g. a comment)
|
|
34
|
+
*/
|
|
35
|
+
export interface SourceFragmentWithLocationNonDirective extends SourceFragmentWithLocationBase {
|
|
36
|
+
isDirective: false;
|
|
37
|
+
directiveInfo: undefined;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A source fragment with associated location metadata
|
|
41
|
+
*/
|
|
42
|
+
export type SourceFragmentWithLocation = SourceFragmentWithLocationDirective | SourceFragmentWithLocationNonDirective;
|
|
21
43
|
/**
|
|
22
44
|
* Custom error class for beancount parsing errors with location context
|
|
23
45
|
*/
|
|
@@ -70,3 +92,4 @@ export declare class BeancountParseError extends Error {
|
|
|
70
92
|
*/
|
|
71
93
|
toString(): string;
|
|
72
94
|
}
|
|
95
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type SourceFragmentWithLocation } from './SourceLocation.mjs';
|
|
2
2
|
/**
|
|
3
3
|
* Splits a Beancount file string into an array of source fragments.
|
|
4
4
|
* Each fragment is represented as an array of strings with location metadata.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { countChar } from './countChar.mjs';
|
|
2
|
+
import { beanCountDirectiveRegex } from '../genericParse.mjs';
|
|
2
3
|
import { stringAwareSplitLine } from './stringAwareSplitLine.mjs';
|
|
4
|
+
import { BeancountParseError, } from './SourceLocation.mjs';
|
|
3
5
|
/**
|
|
4
6
|
* Splits a Beancount file string into an array of source fragments.
|
|
5
7
|
* Each fragment is represented as an array of strings with location metadata.
|
|
@@ -31,29 +33,79 @@ export const splitStringIntoSourceFragments = (source) => {
|
|
|
31
33
|
inFragment = false;
|
|
32
34
|
}
|
|
33
35
|
if (!inFragment) {
|
|
34
|
-
acc.push({ lines: [], startLine: lineNumber });
|
|
35
36
|
inFragment = true;
|
|
37
|
+
const fragmentInfo = beanCountDirectiveRegex.exec(line);
|
|
38
|
+
if (!fragmentInfo) {
|
|
39
|
+
acc.push({
|
|
40
|
+
lines: [],
|
|
41
|
+
startLine: lineNumber,
|
|
42
|
+
isDirective: false,
|
|
43
|
+
directiveInfo: undefined,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
acc.push({
|
|
48
|
+
lines: [],
|
|
49
|
+
startLine: lineNumber,
|
|
50
|
+
isDirective: true,
|
|
51
|
+
directiveInfo: {
|
|
52
|
+
date: fragmentInfo.groups.date,
|
|
53
|
+
directive: fragmentInfo.groups.dated_directive ??
|
|
54
|
+
fragmentInfo.groups.non_dated_directive,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
36
58
|
}
|
|
37
59
|
}
|
|
38
|
-
acc[acc.length - 1]
|
|
60
|
+
const currentFragment = acc[acc.length - 1];
|
|
61
|
+
currentFragment.lines.push(line);
|
|
39
62
|
// After a blank line, ensure next line starts a new fragment
|
|
40
63
|
if (!inString && line.trim() === '') {
|
|
41
64
|
inFragment = false;
|
|
42
65
|
}
|
|
43
66
|
// odd number of ", we're in an unclosed string
|
|
44
|
-
if (countChar(line, '"') % 2 === 1) {
|
|
67
|
+
if (currentFragment.isDirective && countChar(line, '"') % 2 === 1) {
|
|
45
68
|
inString = !inString;
|
|
46
69
|
}
|
|
47
70
|
return acc;
|
|
48
71
|
}, []);
|
|
49
|
-
return fragmentsWithLines.map(({ lines, startLine }) => {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
location: {
|
|
54
|
-
startLine,
|
|
55
|
-
endLine: startLine + lines.length - 1,
|
|
56
|
-
},
|
|
72
|
+
return fragmentsWithLines.map(({ lines, startLine, isDirective, directiveInfo }) => {
|
|
73
|
+
const location = {
|
|
74
|
+
startLine,
|
|
75
|
+
endLine: startLine + lines.length - 1,
|
|
57
76
|
};
|
|
77
|
+
// Comment fragments (non-directives) may contain unbalanced quotes,
|
|
78
|
+
// so skip string-aware splitting for them.
|
|
79
|
+
if (!isDirective) {
|
|
80
|
+
return {
|
|
81
|
+
fragment: lines,
|
|
82
|
+
location,
|
|
83
|
+
isDirective: false,
|
|
84
|
+
directiveInfo: undefined,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const splitLines = stringAwareSplitLine(lines.join('\n'));
|
|
89
|
+
return {
|
|
90
|
+
fragment: splitLines,
|
|
91
|
+
location,
|
|
92
|
+
isDirective: true,
|
|
93
|
+
directiveInfo,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
// Cap sourceContent to avoid huge error output when an unclosed quote
|
|
98
|
+
// causes all remaining lines to be absorbed into a single fragment.
|
|
99
|
+
const contextLines = lines.slice(0, 3);
|
|
100
|
+
throw new BeancountParseError({
|
|
101
|
+
message: error instanceof Error ? error.message : String(error),
|
|
102
|
+
location: {
|
|
103
|
+
startLine,
|
|
104
|
+
endLine: startLine + contextLines.length - 1,
|
|
105
|
+
},
|
|
106
|
+
sourceContent: contextLines,
|
|
107
|
+
cause: error instanceof Error ? error : undefined,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
58
110
|
});
|
|
59
111
|
};
|