beancount 0.0.2 → 0.0.4
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/DateEntry.d.mts +22 -3
- package/build/src/classes/DateEntry.mjs +20 -1
- package/build/src/classes/Entry.d.mts +61 -2
- package/build/src/classes/Entry.mjs +60 -0
- package/build/src/classes/ParseResult.d.mts +45 -3
- package/build/src/classes/ParseResult.mjs +56 -4
- package/build/src/classes/Value.d.mts +39 -0
- package/build/src/classes/Value.mjs +34 -0
- package/build/src/classes/entryTypes/Balance.d.mts +19 -0
- package/build/src/classes/entryTypes/Balance.mjs +16 -0
- package/build/src/classes/entryTypes/Blankline.d.mts +16 -0
- package/build/src/classes/entryTypes/Blankline.mjs +16 -0
- package/build/src/classes/entryTypes/Close.d.mts +12 -0
- package/build/src/classes/entryTypes/Close.mjs +11 -0
- package/build/src/classes/entryTypes/Comment.d.mts +17 -0
- package/build/src/classes/entryTypes/Comment.mjs +17 -0
- package/build/src/classes/entryTypes/Commodity.d.mts +12 -0
- package/build/src/classes/entryTypes/Commodity.mjs +11 -0
- package/build/src/classes/entryTypes/Custom.d.mts +13 -0
- package/build/src/classes/entryTypes/Custom.mjs +11 -0
- package/build/src/classes/entryTypes/Document.d.mts +13 -0
- package/build/src/classes/entryTypes/Document.mjs +11 -0
- package/build/src/classes/entryTypes/Event.d.mts +13 -0
- package/build/src/classes/entryTypes/Event.mjs +11 -0
- package/build/src/classes/entryTypes/Include.d.mts +12 -0
- package/build/src/classes/entryTypes/Include.mjs +11 -0
- package/build/src/classes/entryTypes/Note.d.mts +13 -0
- package/build/src/classes/entryTypes/Note.mjs +11 -0
- package/build/src/classes/entryTypes/Open.d.mts +15 -0
- package/build/src/classes/entryTypes/Open.mjs +12 -0
- package/build/src/classes/entryTypes/Option.d.mts +13 -0
- package/build/src/classes/entryTypes/Option.mjs +11 -0
- package/build/src/classes/entryTypes/Pad.d.mts +13 -0
- package/build/src/classes/entryTypes/Pad.mjs +11 -0
- package/build/src/classes/entryTypes/Plugin.d.mts +13 -0
- package/build/src/classes/entryTypes/Plugin.mjs +11 -0
- package/build/src/classes/entryTypes/Poptag.d.mts +12 -0
- package/build/src/classes/entryTypes/Poptag.mjs +11 -0
- package/build/src/classes/entryTypes/Price.d.mts +18 -0
- package/build/src/classes/entryTypes/Price.mjs +15 -0
- package/build/src/classes/entryTypes/Pushtag.d.mts +12 -0
- package/build/src/classes/entryTypes/Pushtag.mjs +11 -0
- package/build/src/classes/entryTypes/Query.d.mts +13 -0
- package/build/src/classes/entryTypes/Query.mjs +11 -0
- package/build/src/classes/entryTypes/Transaction/Posting.d.mts +41 -0
- package/build/src/classes/entryTypes/Transaction/Posting.mjs +33 -0
- package/build/src/classes/entryTypes/Transaction/Tag.d.mts +19 -0
- package/build/src/classes/entryTypes/Transaction/Tag.mjs +17 -0
- package/build/src/classes/entryTypes/Transaction/index.d.mts +42 -1
- package/build/src/classes/entryTypes/Transaction/index.mjs +69 -5
- package/build/src/entryTypeToClass.d.mts +59 -0
- package/build/src/entryTypeToClass.mjs +37 -0
- package/build/src/genericParse.d.mts +39 -2
- package/build/src/genericParse.mjs +13 -0
- package/build/src/main.d.mts +58 -0
- package/build/src/main.mjs +55 -0
- package/build/src/parse.d.mts +76 -23
- package/build/src/parse.mjs +69 -22
- package/build/src/utils/countChar.d.mts +7 -0
- package/build/src/utils/countChar.mjs +7 -0
- package/build/src/utils/formatPrice.d.mts +7 -2
- package/build/src/utils/formatPrice.mjs +7 -2
- package/build/src/utils/parseMetadata.d.mts +12 -0
- package/build/src/utils/parseMetadata.mjs +8 -0
- package/build/src/utils/simpleParseLine.d.mts +7 -0
- package/build/src/utils/simpleParseLine.mjs +7 -0
- package/build/src/utils/stringAwareParseLine.d.mts +7 -0
- package/build/src/utils/stringAwareParseLine.mjs +7 -0
- package/build/src/utils/stringAwareSplitLine.d.mts +9 -0
- package/build/src/utils/stringAwareSplitLine.mjs +9 -0
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,24 +1,61 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BeancountEntryType } from './entryTypeToClass.mjs';
|
|
2
2
|
import { type Metadata } from './utils/parseMetadata.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* The basic result structure from generic parsing of a Beancount entry.
|
|
5
|
+
* Contains the entry type, header line content, and any properties like comments.
|
|
6
|
+
*/
|
|
3
7
|
export interface GenericParseResult {
|
|
4
|
-
type
|
|
8
|
+
/** The type of Beancount entry (e.g., 'open', 'close', 'balance') */
|
|
9
|
+
type: BeancountEntryType;
|
|
10
|
+
/** The main header content from the first line of the entry */
|
|
5
11
|
header: string;
|
|
12
|
+
/** Properties extracted from the entry */
|
|
6
13
|
props: {
|
|
14
|
+
/** Optional comment text following a semicolon */
|
|
7
15
|
comment?: string;
|
|
8
16
|
};
|
|
9
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Generic parse result for entries that include a date field.
|
|
20
|
+
* Extends the base result with date and metadata properties.
|
|
21
|
+
*/
|
|
10
22
|
export interface GenericParseResultWithDate extends GenericParseResult {
|
|
23
|
+
/** Extended properties including date and optional metadata */
|
|
11
24
|
props: GenericParseResult['props'] & {
|
|
25
|
+
/** The date string in YYYY-MM-DD format */
|
|
12
26
|
date: string;
|
|
27
|
+
/** Optional metadata key-value pairs */
|
|
13
28
|
metadata?: Metadata;
|
|
14
29
|
};
|
|
15
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Generic parse result specifically for transaction entries.
|
|
33
|
+
* Extends the dated result with transaction-specific fields like body lines and flags.
|
|
34
|
+
*/
|
|
16
35
|
export interface GenericParseResultTransaction extends Omit<GenericParseResultWithDate, 'metadata'> {
|
|
36
|
+
/** The body lines of the transaction (posting lines) */
|
|
17
37
|
body: string[];
|
|
38
|
+
/** Optional transaction flag character (e.g., '*', '!') */
|
|
18
39
|
flag?: string;
|
|
40
|
+
/** Extended properties including date and optional flag */
|
|
19
41
|
props: GenericParseResult['props'] & {
|
|
42
|
+
/** The date string in YYYY-MM-DD format */
|
|
20
43
|
date: string;
|
|
44
|
+
/** Optional transaction flag character */
|
|
21
45
|
flag?: string;
|
|
22
46
|
};
|
|
23
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Performs generic parsing on an unparsed entry to extract common fields.
|
|
50
|
+
*
|
|
51
|
+
* This function:
|
|
52
|
+
* - Detects if the entry has a date (YYYY-MM-DD format)
|
|
53
|
+
* - Identifies the entry type
|
|
54
|
+
* - Extracts header content and comments
|
|
55
|
+
* - Handles transaction-specific parsing (flags, body lines)
|
|
56
|
+
* - Parses metadata for dated entries
|
|
57
|
+
*
|
|
58
|
+
* @param unparsedEntry - Array of string tokens representing a single entry
|
|
59
|
+
* @returns A generic parse result object appropriate for the entry type
|
|
60
|
+
*/
|
|
24
61
|
export declare const genericParse: (unparsedEntry: string[]) => GenericParseResult | GenericParseResultTransaction | GenericParseResultWithDate;
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { parseMetadata } from './utils/parseMetadata.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Performs generic parsing on an unparsed entry to extract common fields.
|
|
4
|
+
*
|
|
5
|
+
* This function:
|
|
6
|
+
* - Detects if the entry has a date (YYYY-MM-DD format)
|
|
7
|
+
* - Identifies the entry type
|
|
8
|
+
* - Extracts header content and comments
|
|
9
|
+
* - Handles transaction-specific parsing (flags, body lines)
|
|
10
|
+
* - Parses metadata for dated entries
|
|
11
|
+
*
|
|
12
|
+
* @param unparsedEntry - Array of string tokens representing a single entry
|
|
13
|
+
* @returns A generic parse result object appropriate for the entry type
|
|
14
|
+
*/
|
|
2
15
|
export const genericParse = (unparsedEntry) => {
|
|
3
16
|
const [firstLine, ...rest] = unparsedEntry;
|
|
4
17
|
const splitFirstLine = firstLine.split(' ');
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* beancount - A parser and editor for Beancount accounting files with full type safety.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* The primary function you'll use is {@link parse}, which parses a complete Beancount file
|
|
6
|
+
* and returns a {@link ParseResult} containing all parsed entries.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { parse } from 'beancount'
|
|
11
|
+
*
|
|
12
|
+
* const beancountContent = `
|
|
13
|
+
* 2024-01-01 open Assets:Checking
|
|
14
|
+
* 2024-01-02 * "Grocery Store" "Weekly shopping"
|
|
15
|
+
* Assets:Checking -50.00 USD
|
|
16
|
+
* Expenses:Food 50.00 USD
|
|
17
|
+
* `
|
|
18
|
+
*
|
|
19
|
+
* const result = parse(beancountContent)
|
|
20
|
+
* console.log(result.entries) // Array of parsed Entry objects
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @module
|
|
24
|
+
*/
|
|
25
|
+
export { parse, parseEntry, splitStringIntoUnparsedEntries } from './parse.mjs';
|
|
26
|
+
export type { ParseOptions } from './parse.mjs';
|
|
27
|
+
export type { GenericParseResult, GenericParseResultWithDate, GenericParseResultTransaction, } from './genericParse.mjs';
|
|
28
|
+
export type { Metadata } from './utils/parseMetadata.mjs';
|
|
29
|
+
export { ParseResult, type ParseResultObj } from './classes/ParseResult.mjs';
|
|
30
|
+
export { Entry, assertEntryConstructor } from './classes/Entry.mjs';
|
|
31
|
+
export type { FormatOptions } from './classes/Entry.mjs';
|
|
32
|
+
export { DateEntry } from './classes/DateEntry.mjs';
|
|
33
|
+
export type { BeancountDateEntryType } from './classes/DateEntry.mjs';
|
|
34
|
+
export { Value } from './classes/Value.mjs';
|
|
35
|
+
export type { ValueType } from './classes/Value.mjs';
|
|
36
|
+
export { Balance } from './classes/entryTypes/Balance.mjs';
|
|
37
|
+
export { Blankline } from './classes/entryTypes/Blankline.mjs';
|
|
38
|
+
export { Close } from './classes/entryTypes/Close.mjs';
|
|
39
|
+
export { Comment } from './classes/entryTypes/Comment.mjs';
|
|
40
|
+
export { Commodity } from './classes/entryTypes/Commodity.mjs';
|
|
41
|
+
export { Custom } from './classes/entryTypes/Custom.mjs';
|
|
42
|
+
export { Document } from './classes/entryTypes/Document.mjs';
|
|
43
|
+
export { Event } from './classes/entryTypes/Event.mjs';
|
|
44
|
+
export { Include } from './classes/entryTypes/Include.mjs';
|
|
45
|
+
export { Note } from './classes/entryTypes/Note.mjs';
|
|
46
|
+
export { Open } from './classes/entryTypes/Open.mjs';
|
|
47
|
+
export { Option } from './classes/entryTypes/Option.mjs';
|
|
48
|
+
export { Pad } from './classes/entryTypes/Pad.mjs';
|
|
49
|
+
export { Plugin } from './classes/entryTypes/Plugin.mjs';
|
|
50
|
+
export { Poptag } from './classes/entryTypes/Poptag.mjs';
|
|
51
|
+
export { Price } from './classes/entryTypes/Price.mjs';
|
|
52
|
+
export { Pushtag } from './classes/entryTypes/Pushtag.mjs';
|
|
53
|
+
export { Query } from './classes/entryTypes/Query.mjs';
|
|
54
|
+
export { Transaction } from './classes/entryTypes/Transaction/index.mjs';
|
|
55
|
+
export { Posting } from './classes/entryTypes/Transaction/Posting.mjs';
|
|
56
|
+
export { Tag } from './classes/entryTypes/Transaction/Tag.mjs';
|
|
57
|
+
export type { BeancountEntryType, EntryType } from './entryTypeToClass.mjs';
|
|
58
|
+
export { beancountEntryToClass, entryTypeToClass } from './entryTypeToClass.mjs';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* beancount - A parser and editor for Beancount accounting files with full type safety.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* The primary function you'll use is {@link parse}, which parses a complete Beancount file
|
|
6
|
+
* and returns a {@link ParseResult} containing all parsed entries.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { parse } from 'beancount'
|
|
11
|
+
*
|
|
12
|
+
* const beancountContent = `
|
|
13
|
+
* 2024-01-01 open Assets:Checking
|
|
14
|
+
* 2024-01-02 * "Grocery Store" "Weekly shopping"
|
|
15
|
+
* Assets:Checking -50.00 USD
|
|
16
|
+
* Expenses:Food 50.00 USD
|
|
17
|
+
* `
|
|
18
|
+
*
|
|
19
|
+
* const result = parse(beancountContent)
|
|
20
|
+
* console.log(result.entries) // Array of parsed Entry objects
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @module
|
|
24
|
+
*/
|
|
25
|
+
// Primary parsing functionality
|
|
26
|
+
export { parse, parseEntry, splitStringIntoUnparsedEntries } from './parse.mjs';
|
|
27
|
+
// Core classes
|
|
28
|
+
export { ParseResult } from './classes/ParseResult.mjs';
|
|
29
|
+
export { Entry, assertEntryConstructor } from './classes/Entry.mjs';
|
|
30
|
+
export { DateEntry } from './classes/DateEntry.mjs';
|
|
31
|
+
export { Value } from './classes/Value.mjs';
|
|
32
|
+
// Entry type classes
|
|
33
|
+
export { Balance } from './classes/entryTypes/Balance.mjs';
|
|
34
|
+
export { Blankline } from './classes/entryTypes/Blankline.mjs';
|
|
35
|
+
export { Close } from './classes/entryTypes/Close.mjs';
|
|
36
|
+
export { Comment } from './classes/entryTypes/Comment.mjs';
|
|
37
|
+
export { Commodity } from './classes/entryTypes/Commodity.mjs';
|
|
38
|
+
export { Custom } from './classes/entryTypes/Custom.mjs';
|
|
39
|
+
export { Document } from './classes/entryTypes/Document.mjs';
|
|
40
|
+
export { Event } from './classes/entryTypes/Event.mjs';
|
|
41
|
+
export { Include } from './classes/entryTypes/Include.mjs';
|
|
42
|
+
export { Note } from './classes/entryTypes/Note.mjs';
|
|
43
|
+
export { Open } from './classes/entryTypes/Open.mjs';
|
|
44
|
+
export { Option } from './classes/entryTypes/Option.mjs';
|
|
45
|
+
export { Pad } from './classes/entryTypes/Pad.mjs';
|
|
46
|
+
export { Plugin } from './classes/entryTypes/Plugin.mjs';
|
|
47
|
+
export { Poptag } from './classes/entryTypes/Poptag.mjs';
|
|
48
|
+
export { Price } from './classes/entryTypes/Price.mjs';
|
|
49
|
+
export { Pushtag } from './classes/entryTypes/Pushtag.mjs';
|
|
50
|
+
export { Query } from './classes/entryTypes/Query.mjs';
|
|
51
|
+
export { Transaction } from './classes/entryTypes/Transaction/index.mjs';
|
|
52
|
+
// Transaction sub-components
|
|
53
|
+
export { Posting } from './classes/entryTypes/Transaction/Posting.mjs';
|
|
54
|
+
export { Tag } from './classes/entryTypes/Transaction/Tag.mjs';
|
|
55
|
+
export { beancountEntryToClass, entryTypeToClass } from './entryTypeToClass.mjs';
|
package/build/src/parse.d.mts
CHANGED
|
@@ -1,29 +1,82 @@
|
|
|
1
1
|
import { ParseResult } from './classes/ParseResult.mjs';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
plugin: typeof Plugin;
|
|
17
|
-
poptag: typeof Poptag;
|
|
18
|
-
price: typeof Price;
|
|
19
|
-
pushtag: typeof Pushtag;
|
|
20
|
-
query: typeof Query;
|
|
21
|
-
};
|
|
22
|
-
export type EntryType = keyof typeof entryTypes;
|
|
2
|
+
import { Comment, Blankline } from './classes/entryTypes/index.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* Splits a Beancount file string into an array of unparsed entry arrays.
|
|
5
|
+
* Each entry is represented as an array of strings (tokens).
|
|
6
|
+
*
|
|
7
|
+
* This function handles:
|
|
8
|
+
* - Splitting on blank lines between entries
|
|
9
|
+
* - Detecting new entries based on indentation
|
|
10
|
+
* - Preserving multi-line strings that span lines
|
|
11
|
+
*
|
|
12
|
+
* @param input - The complete Beancount file content as a string
|
|
13
|
+
* @returns An array where each element is an array of string tokens representing one entry
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
23
16
|
export declare const splitStringIntoUnparsedEntries: (input: string) => string[][];
|
|
24
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Parses a single unparsed entry into its corresponding Entry class instance.
|
|
19
|
+
*
|
|
20
|
+
* This function:
|
|
21
|
+
* - Performs generic parsing to determine entry type
|
|
22
|
+
* - Instantiates the appropriate Entry subclass
|
|
23
|
+
* - Handles special cases for comments and blank lines
|
|
24
|
+
*
|
|
25
|
+
* @param unparsedEntry - Array of string tokens representing a single entry
|
|
26
|
+
* @param skipBlanklines - If true, returns undefined for blank lines; if false, returns Blankline instances
|
|
27
|
+
* @returns An Entry instance, or undefined if the entry is blank and skipBlanklines is true
|
|
28
|
+
*/
|
|
29
|
+
export declare const parseEntry: (unparsedEntry: string[], skipBlanklines?: boolean) => import("./classes/entryTypes/index.mjs").Transaction | import("./classes/entryTypes/Balance.mjs").Balance | import("./classes/entryTypes/Close.mjs").Close | import("./classes/entryTypes/Commodity.mjs").Commodity | import("./classes/entryTypes/Custom.mjs").Custom | import("./classes/entryTypes/Document.mjs").Document | import("./classes/entryTypes/Event.mjs").Event | import("./classes/entryTypes/Include.mjs").Include | import("./classes/entryTypes/Note.mjs").Note | import("./classes/entryTypes/Open.mjs").Open | import("./classes/entryTypes/Option.mjs").Option | import("./classes/entryTypes/Pad.mjs").Pad | import("./classes/entryTypes/Plugin.mjs").Plugin | import("./classes/entryTypes/Poptag.mjs").Poptag | import("./classes/entryTypes/Price.mjs").Price | import("./classes/entryTypes/Pushtag.mjs").Pushtag | import("./classes/entryTypes/Query.mjs").Query | Comment | Blankline | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Options for configuring the parse function behavior.
|
|
32
|
+
*/
|
|
25
33
|
export interface ParseOptions {
|
|
34
|
+
/**
|
|
35
|
+
* If true, blank lines in the input are skipped and not included in the result.
|
|
36
|
+
* If false, blank lines are preserved as Blankline entries.
|
|
37
|
+
* Defaults to true.
|
|
38
|
+
*/
|
|
26
39
|
skipBlanklines?: boolean;
|
|
27
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Parses a complete Beancount file string into a ParseResult containing Entry objects.
|
|
43
|
+
*
|
|
44
|
+
* This is the main entry point for parsing Beancount files. It handles:
|
|
45
|
+
* - Splitting the input into individual entries
|
|
46
|
+
* - Parsing each entry into its appropriate type
|
|
47
|
+
* - Managing the tag stack for pushtag/poptag directives
|
|
48
|
+
* - Applying tags from the stack to transactions
|
|
49
|
+
*
|
|
50
|
+
* @remarks
|
|
51
|
+
* This is the primary function you'll use from this library. It takes a Beancount file
|
|
52
|
+
* as a string and returns a structured ParseResult object containing all parsed entries.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* Basic usage:
|
|
56
|
+
* ```typescript
|
|
57
|
+
* import { parse } from 'beancount'
|
|
58
|
+
*
|
|
59
|
+
* const content = `
|
|
60
|
+
* 2024-01-01 open Assets:Checking
|
|
61
|
+
* 2024-01-02 * "Payee" "Narration"
|
|
62
|
+
* Assets:Checking 100.00 USD
|
|
63
|
+
* Income:Salary -100.00 USD
|
|
64
|
+
* `
|
|
65
|
+
*
|
|
66
|
+
* const result = parse(content)
|
|
67
|
+
* // result.entries contains parsed Entry objects
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* With options:
|
|
72
|
+
* ```typescript
|
|
73
|
+
* // Preserve blank lines in output
|
|
74
|
+
* const result = parse(content, { skipBlanklines: false })
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @param input - The complete Beancount file content as a string
|
|
78
|
+
* @param options - Optional parsing configuration
|
|
79
|
+
* @param options.skipBlanklines - If true, skips blank lines; defaults to true
|
|
80
|
+
* @returns A ParseResult instance containing all parsed entries
|
|
81
|
+
*/
|
|
28
82
|
export declare const parse: (input: string, { skipBlanklines }?: ParseOptions) => ParseResult;
|
|
29
|
-
export {};
|
package/build/src/parse.mjs
CHANGED
|
@@ -1,29 +1,23 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
import { ParseResult } from './classes/ParseResult.mjs';
|
|
3
|
-
import {
|
|
3
|
+
import { Comment, Blankline } from './classes/entryTypes/index.mjs';
|
|
4
4
|
import { countChar } from './utils/countChar.mjs';
|
|
5
5
|
import { stringAwareSplitLine } from './utils/stringAwareSplitLine.mjs';
|
|
6
6
|
import { genericParse, } from './genericParse.mjs';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
plugin: Plugin,
|
|
22
|
-
poptag: Poptag,
|
|
23
|
-
price: Price,
|
|
24
|
-
pushtag: Pushtag,
|
|
25
|
-
query: Query,
|
|
26
|
-
};
|
|
7
|
+
import { beancountEntryToClass } from './entryTypeToClass.mjs';
|
|
8
|
+
/**
|
|
9
|
+
* Splits a Beancount file string into an array of unparsed entry arrays.
|
|
10
|
+
* Each entry is represented as an array of strings (tokens).
|
|
11
|
+
*
|
|
12
|
+
* This function handles:
|
|
13
|
+
* - Splitting on blank lines between entries
|
|
14
|
+
* - Detecting new entries based on indentation
|
|
15
|
+
* - Preserving multi-line strings that span lines
|
|
16
|
+
*
|
|
17
|
+
* @param input - The complete Beancount file content as a string
|
|
18
|
+
* @returns An array where each element is an array of string tokens representing one entry
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
27
21
|
export const splitStringIntoUnparsedEntries = (input) => {
|
|
28
22
|
const lines = input.split('\n');
|
|
29
23
|
// split up the file into entries
|
|
@@ -53,10 +47,22 @@ export const splitStringIntoUnparsedEntries = (input) => {
|
|
|
53
47
|
}, []);
|
|
54
48
|
return unparsedEntries.map((lines) => stringAwareSplitLine(lines.join('\n')));
|
|
55
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* Parses a single unparsed entry into its corresponding Entry class instance.
|
|
52
|
+
*
|
|
53
|
+
* This function:
|
|
54
|
+
* - Performs generic parsing to determine entry type
|
|
55
|
+
* - Instantiates the appropriate Entry subclass
|
|
56
|
+
* - Handles special cases for comments and blank lines
|
|
57
|
+
*
|
|
58
|
+
* @param unparsedEntry - Array of string tokens representing a single entry
|
|
59
|
+
* @param skipBlanklines - If true, returns undefined for blank lines; if false, returns Blankline instances
|
|
60
|
+
* @returns An Entry instance, or undefined if the entry is blank and skipBlanklines is true
|
|
61
|
+
*/
|
|
56
62
|
export const parseEntry = (unparsedEntry, skipBlanklines = true) => {
|
|
57
63
|
const genericParseResult = genericParse(unparsedEntry);
|
|
58
64
|
const { type } = genericParseResult;
|
|
59
|
-
const EntryClass =
|
|
65
|
+
const EntryClass = beancountEntryToClass[type];
|
|
60
66
|
if (EntryClass) {
|
|
61
67
|
return EntryClass.fromGenericParseResult(genericParseResult);
|
|
62
68
|
}
|
|
@@ -75,6 +81,47 @@ export const parseEntry = (unparsedEntry, skipBlanklines = true) => {
|
|
|
75
81
|
});
|
|
76
82
|
}
|
|
77
83
|
};
|
|
84
|
+
/**
|
|
85
|
+
* Parses a complete Beancount file string into a ParseResult containing Entry objects.
|
|
86
|
+
*
|
|
87
|
+
* This is the main entry point for parsing Beancount files. It handles:
|
|
88
|
+
* - Splitting the input into individual entries
|
|
89
|
+
* - Parsing each entry into its appropriate type
|
|
90
|
+
* - Managing the tag stack for pushtag/poptag directives
|
|
91
|
+
* - Applying tags from the stack to transactions
|
|
92
|
+
*
|
|
93
|
+
* @remarks
|
|
94
|
+
* This is the primary function you'll use from this library. It takes a Beancount file
|
|
95
|
+
* as a string and returns a structured ParseResult object containing all parsed entries.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* Basic usage:
|
|
99
|
+
* ```typescript
|
|
100
|
+
* import { parse } from 'beancount'
|
|
101
|
+
*
|
|
102
|
+
* const content = `
|
|
103
|
+
* 2024-01-01 open Assets:Checking
|
|
104
|
+
* 2024-01-02 * "Payee" "Narration"
|
|
105
|
+
* Assets:Checking 100.00 USD
|
|
106
|
+
* Income:Salary -100.00 USD
|
|
107
|
+
* `
|
|
108
|
+
*
|
|
109
|
+
* const result = parse(content)
|
|
110
|
+
* // result.entries contains parsed Entry objects
|
|
111
|
+
* ```
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* With options:
|
|
115
|
+
* ```typescript
|
|
116
|
+
* // Preserve blank lines in output
|
|
117
|
+
* const result = parse(content, { skipBlanklines: false })
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* @param input - The complete Beancount file content as a string
|
|
121
|
+
* @param options - Optional parsing configuration
|
|
122
|
+
* @param options.skipBlanklines - If true, skips blank lines; defaults to true
|
|
123
|
+
* @returns A ParseResult instance containing all parsed entries
|
|
124
|
+
*/
|
|
78
125
|
export const parse = (input, { skipBlanklines = true } = {}) => {
|
|
79
126
|
const unparsedEntries = splitStringIntoUnparsedEntries(input);
|
|
80
127
|
const parsedEntries = [];
|
|
@@ -1 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counts the number of occurrences of a character in a string.
|
|
3
|
+
*
|
|
4
|
+
* @param line - The string to search in
|
|
5
|
+
* @param charToCount - The character to count occurrences of
|
|
6
|
+
* @returns The number of times the character appears in the string
|
|
7
|
+
*/
|
|
1
8
|
export declare const countChar: (line: string, charToCount: string) => number;
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counts the number of occurrences of a character in a string.
|
|
3
|
+
*
|
|
4
|
+
* @param line - The string to search in
|
|
5
|
+
* @param charToCount - The character to count occurrences of
|
|
6
|
+
* @returns The number of times the character appears in the string
|
|
7
|
+
*/
|
|
1
8
|
export const countChar = (line, charToCount) => {
|
|
2
9
|
return line.split(charToCount).length - 1;
|
|
3
10
|
};
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Formats a price string from amount and
|
|
2
|
+
* Formats a price string from amount, currency, cost, and price annotation components.
|
|
3
3
|
* Returns undefined if either amount or currency is missing.
|
|
4
4
|
*
|
|
5
|
+
* Format: "amount currency [{cost}] [@ priceAmount priceCurrency]"
|
|
6
|
+
*
|
|
5
7
|
* @param amount - The amount portion of the price
|
|
6
8
|
* @param currency - The currency portion of the price
|
|
7
|
-
* @
|
|
9
|
+
* @param cost - Optional cost specification in curly braces
|
|
10
|
+
* @param priceAmount - Optional price annotation amount
|
|
11
|
+
* @param priceCurrency - Optional price annotation currency
|
|
12
|
+
* @returns Formatted price string or undefined if amount/currency are missing
|
|
8
13
|
*/
|
|
9
14
|
export declare const formatPrice: (amount: string | undefined, currency: string | undefined, cost?: string, priceAmount?: string, priceCurrency?: string) => string | undefined;
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Formats a price string from amount and
|
|
2
|
+
* Formats a price string from amount, currency, cost, and price annotation components.
|
|
3
3
|
* Returns undefined if either amount or currency is missing.
|
|
4
4
|
*
|
|
5
|
+
* Format: "amount currency [{cost}] [@ priceAmount priceCurrency]"
|
|
6
|
+
*
|
|
5
7
|
* @param amount - The amount portion of the price
|
|
6
8
|
* @param currency - The currency portion of the price
|
|
7
|
-
* @
|
|
9
|
+
* @param cost - Optional cost specification in curly braces
|
|
10
|
+
* @param priceAmount - Optional price annotation amount
|
|
11
|
+
* @param priceCurrency - Optional price annotation currency
|
|
12
|
+
* @returns Formatted price string or undefined if amount/currency are missing
|
|
8
13
|
*/
|
|
9
14
|
export const formatPrice = (amount, currency, cost, priceAmount, priceCurrency) => {
|
|
10
15
|
if (!amount || !currency) {
|
|
@@ -1,3 +1,15 @@
|
|
|
1
1
|
import { Value } from '../classes/Value.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Type representing metadata as a record of key-value pairs.
|
|
4
|
+
* Keys are strings, values are Value objects.
|
|
5
|
+
*/
|
|
2
6
|
export type Metadata = Record<string, Value>;
|
|
7
|
+
/**
|
|
8
|
+
* Parses metadata lines into a Metadata object.
|
|
9
|
+
* Each line should be in the format "key: value".
|
|
10
|
+
*
|
|
11
|
+
* @param rest - Array of metadata line strings to parse
|
|
12
|
+
* @returns A Metadata object with parsed key-value pairs, or undefined if no lines provided
|
|
13
|
+
* @throws {Error} If any line cannot be parsed as metadata
|
|
14
|
+
*/
|
|
3
15
|
export declare const parseMetadata: (rest: string[]) => Metadata | undefined;
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { Value } from '../classes/Value.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Parses metadata lines into a Metadata object.
|
|
4
|
+
* Each line should be in the format "key: value".
|
|
5
|
+
*
|
|
6
|
+
* @param rest - Array of metadata line strings to parse
|
|
7
|
+
* @returns A Metadata object with parsed key-value pairs, or undefined if no lines provided
|
|
8
|
+
* @throws {Error} If any line cannot be parsed as metadata
|
|
9
|
+
*/
|
|
2
10
|
export const parseMetadata = (rest) => {
|
|
3
11
|
if (rest.length === 0) {
|
|
4
12
|
return undefined;
|
|
@@ -1 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a line by splitting on spaces and filtering out empty strings.
|
|
3
|
+
* Does not handle quoted strings - use stringAwareParseLine for that.
|
|
4
|
+
*
|
|
5
|
+
* @param line - The line string to parse
|
|
6
|
+
* @returns Array of non-empty tokens split by spaces
|
|
7
|
+
*/
|
|
1
8
|
export declare const simpleParseLine: (line: string) => string[];
|
|
@@ -1 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a line by splitting on spaces and filtering out empty strings.
|
|
3
|
+
* Does not handle quoted strings - use stringAwareParseLine for that.
|
|
4
|
+
*
|
|
5
|
+
* @param line - The line string to parse
|
|
6
|
+
* @returns Array of non-empty tokens split by spaces
|
|
7
|
+
*/
|
|
1
8
|
export const simpleParseLine = (line) => line.split(' ').filter((e) => e !== '');
|
|
@@ -1 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a line by splitting on spaces while respecting quoted strings.
|
|
3
|
+
* Spaces inside quoted strings are preserved as part of the string content.
|
|
4
|
+
*
|
|
5
|
+
* @param line - The line string to parse
|
|
6
|
+
* @returns Array of tokens split by spaces (excluding spaces within quotes)
|
|
7
|
+
*/
|
|
1
8
|
export declare const stringAwareParseLine: (line: string) => string[];
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a line by splitting on spaces while respecting quoted strings.
|
|
3
|
+
* Spaces inside quoted strings are preserved as part of the string content.
|
|
4
|
+
*
|
|
5
|
+
* @param line - The line string to parse
|
|
6
|
+
* @returns Array of tokens split by spaces (excluding spaces within quotes)
|
|
7
|
+
*/
|
|
1
8
|
export const stringAwareParseLine = (line) => {
|
|
2
9
|
const result = [];
|
|
3
10
|
let current = '';
|
|
@@ -1 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a string by newlines while respecting quoted strings.
|
|
3
|
+
* Newlines inside quoted strings are preserved as part of the string content.
|
|
4
|
+
* Handles escape sequences within quotes.
|
|
5
|
+
*
|
|
6
|
+
* @param input - The input string to split
|
|
7
|
+
* @returns Array of strings split by newlines (excluding newlines within quotes)
|
|
8
|
+
* @throws {Error} If there is an unclosed quote in the input
|
|
9
|
+
*/
|
|
1
10
|
export declare const stringAwareSplitLine: (input: string) => string[];
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a string by newlines while respecting quoted strings.
|
|
3
|
+
* Newlines inside quoted strings are preserved as part of the string content.
|
|
4
|
+
* Handles escape sequences within quotes.
|
|
5
|
+
*
|
|
6
|
+
* @param input - The input string to split
|
|
7
|
+
* @returns Array of strings split by newlines (excluding newlines within quotes)
|
|
8
|
+
* @throws {Error} If there is an unclosed quote in the input
|
|
9
|
+
*/
|
|
1
10
|
export const stringAwareSplitLine = (input) => {
|
|
2
11
|
const result = [];
|
|
3
12
|
let current = '';
|