diff options
| author | Asko Nõmm <asko@nmm.ee> | 2025-01-25 22:12:30 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-25 22:12:30 +0200 |
| commit | 160cb5a7c2a733ee9c1eaa69008148ba9c21125d (patch) | |
| tree | 7d5649d027444443e4aedda7293627d37d956d00 | |
| parent | 7f3a7e9770623743fde1cc9fde8aea7d476a5700 (diff) | |
| parent | d8d3118a9bdfe822292d1f4d28d2879aaa1ae86f (diff) | |
Merge pull request #3 from askonomm/2-if-the-content-starts-and-ends-with-----add-content-item-frontmatter
Implement FrontMatter parsing.
| -rw-r--r-- | .github/workflows/node.js.yml | 2 | ||||
| -rw-r--r-- | README.md | 19 | ||||
| -rw-r--r-- | package-lock.json | 28 | ||||
| -rw-r--r-- | package.json | 6 | ||||
| -rw-r--r-- | src/flatmatter.test.ts | 16 | ||||
| -rw-r--r-- | src/flatmatter.ts | 27 | ||||
| -rw-r--r-- | src/serializers/to_json.test.ts | 4 | ||||
| -rw-r--r-- | src/serializers/to_json.ts | 4 | ||||
| -rw-r--r-- | src/serializers/to_object.ts | 4 | ||||
| -rw-r--r-- | tsconfig.json | 2 |
10 files changed, 85 insertions, 27 deletions
diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 8cc0d23..47a1275 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: - node-version: [18.x, 19.x, 20.x, 21.x, 22.x] + node-version: [18.x, 19.x, 20.x, 21.x, 22.x, 23.x] steps: - uses: actions/checkout@v4 @@ -20,6 +20,25 @@ FlatMatter also supports functions, allowing you to build your own data DSL, and forward slash `/` character, meaning that the result of the left operation will be passed as the first argument of the next function, and so on, to produce an end result. +Additionally, FlatMatter also parses FrontMatter content, meaning that a FlatMatter file like this: + +```yaml +--- +title: "Hello, World!" +--- + +Content goes here. +``` + +Would result in this data being created: + +```json +{ + "title": "Hello, World!", + "content": "Content goes here." +} +``` + ## Install ```shell diff --git a/package-lock.json b/package-lock.json index 7bf2cbe..61c0397 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,15 @@ { "name": "flatmatter", - "version": "1.0.1", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "flatmatter", - "version": "1.0.1", + "version": "1.1.0", "license": "MIT", "devDependencies": { + "@types/node": "^22.10.10", "@vitest/coverage-istanbul": "^2.1.8", "@vitest/coverage-v8": "^2.1.8", "@vitest/ui": "^2.1.8", @@ -1086,6 +1087,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/node": { + "version": "22.10.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.10.tgz", + "integrity": "sha512-X47y/mPNzxviAGY5TcYPtYL8JsY3kAq2n8fMmKoRCxq/c4v4pyGNCzM2R6+M5/umG4ZfHuT+sgqDYqWc9rJ6ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, "node_modules/@vitest/coverage-istanbul": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-2.1.8.tgz", @@ -2715,9 +2726,9 @@ "license": "Apache-2.0" }, "node_modules/tsup": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.3.5.tgz", - "integrity": "sha512-Tunf6r6m6tnZsG9GYWndg0z8dEV7fD733VBFzFJ5Vcm1FtlXB8xBD/rtrBi2a3YKEV7hHtxiZtW5EAVADoe1pA==", + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.3.6.tgz", + "integrity": "sha512-XkVtlDV/58S9Ye0JxUUTcrQk4S+EqlOHKzg6Roa62rdjL1nGWNUstG0xgI4vanHdfIpjP448J8vlN0oK6XOJ5g==", "dev": true, "license": "MIT", "dependencies": { @@ -2780,6 +2791,13 @@ "node": ">=14.17" } }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "node_modules/update-browserslist-db": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", diff --git a/package.json b/package.json index 0dd0a5a..bbcc863 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flatmatter", - "version": "1.0.1", + "version": "1.1.0", "description": "A data serialization language, and library, with support for functions.", "author": "Asko Nõmm <asko@nmm.ee> (https://nmm.ee)", "main": "dist/index.js", @@ -26,12 +26,16 @@ "test": "vitest", "coverage": "vitest run --coverage" }, + "engines": { + "node": ">=18" + }, "devDependencies": { "@vitest/coverage-istanbul": "^2.1.8", "@vitest/coverage-v8": "^2.1.8", "@vitest/ui": "^2.1.8", "tsup": "^8.3.5", "typescript": "^5.7.3", + "@types/node": "^22.10.10", "vite": "^5.4.11", "vitest": "^2.1.8" } diff --git a/src/flatmatter.test.ts b/src/flatmatter.test.ts index 4c349aa..bbe26d9 100644 --- a/src/flatmatter.test.ts +++ b/src/flatmatter.test.ts @@ -1,16 +1,22 @@ -import FlatMatter from "./flatmatter"; +import FlatMatter from "./flatmatter.ts"; import {assert} from "vitest"; +import ToObject from "./serializers/to_object.ts"; test('Line has no value separator', () => { - expect(() => new FlatMatter('test')) - .toThrowError("Line on index 0 doesn't have a value separator."); + assert.throws(() => new FlatMatter('test'), "Line on index 0 doesn't have a value separator."); }) test('Line can only have one value separator', () => { - expect(() => new FlatMatter('test: this: that')) - .toThrowError("Line on index 0 has multiple value separators.") + assert.throws(() => new FlatMatter('test: this: that'), 'Line on index 0 has multiple value separators.') }) test('String values can have colon characters', () => { assert.doesNotThrow(() => new FlatMatter('test: "this : that"'), Error) +}) + +test('FrontMatter creates a new content entry', () => { + const fm = new FlatMatter(`---\nthis: true\n---\n\nMarkdown goes here.\n\nAnd here.`); + const result = fm.serialize(new ToObject()); + + assert.deepEqual(result, {"this": true, "content": "Markdown goes here.\n\nAnd here."}); })
\ No newline at end of file diff --git a/src/flatmatter.ts b/src/flatmatter.ts index 3bf8704..8ffee6f 100644 --- a/src/flatmatter.ts +++ b/src/flatmatter.ts @@ -1,9 +1,6 @@ +import { EOL } from "node:os"; import {trimChar} from "./utils.ts"; -export type Matter = { - [key: string]: Matter | unknown; -}; - export type ParsedValue = { value: unknown; computeActions: ComputeAction[]; @@ -15,7 +12,7 @@ export type ComputeAction = { }; export interface Serializer { - serialize(parsedConfig: Matter): unknown; + serialize(parsedConfig: Record<string, unknown>): unknown; } export interface FlatMatterFn { @@ -26,7 +23,7 @@ export interface FlatMatterFn { export default class FlatMatter { private content: string; - private parsedConfig: Matter = {}; + private parsedConfig: Record<string, unknown> = {}; private functions: FlatMatterFn[]; constructor(content: string, functions: FlatMatterFn[] = []) { @@ -37,9 +34,23 @@ export default class FlatMatter { private parse(): void { const lines = this.content.split(/\r?\n/); + let frontMatterBreakCount = 0; for (let i = 0; i < lines.length; i++) { - this.parseLine(i, lines[i]); + if (lines[i].trim() === "---" && frontMatterBreakCount < 2) { + frontMatterBreakCount++; + continue; + } + + + // FlatMatter ends, Markdown begins + if (frontMatterBreakCount < 2) { + this.parseLine(i, lines[i]); + continue; + } + + this.parsedConfig.content = lines.slice(i).join(EOL).trim(); + break; } } @@ -60,7 +71,7 @@ export default class FlatMatter { const config = keys.reduceRight((acc, key) => { return {[key]: acc}; - }, this.computeValue(parsedValue)) as Matter; + }, this.computeValue(parsedValue)) as Record<string, unknown>; this.parsedConfig = {...this.parsedConfig, ...config}; } diff --git a/src/serializers/to_json.test.ts b/src/serializers/to_json.test.ts index 01f73e0..22f7ba8 100644 --- a/src/serializers/to_json.test.ts +++ b/src/serializers/to_json.test.ts @@ -1,5 +1,5 @@ -import FlatMatter from "../flatmatter"; -import ToJson from "./to_json"; +import FlatMatter from "../flatmatter.ts"; +import ToJson from "./to_json.ts"; test("Single-level configuration", () => { const fm = new FlatMatter( diff --git a/src/serializers/to_json.ts b/src/serializers/to_json.ts index f915a88..76148db 100644 --- a/src/serializers/to_json.ts +++ b/src/serializers/to_json.ts @@ -1,7 +1,7 @@ -import type { Matter, Serializer } from "../flatmatter.ts"; +import type { Serializer } from "../flatmatter.ts"; export default class ToJson implements Serializer { - serialize(parsedConfig: Matter): string { + serialize(parsedConfig: Record<string, unknown>): string { return JSON.stringify(parsedConfig); } } diff --git a/src/serializers/to_object.ts b/src/serializers/to_object.ts index 1b07144..a7161cc 100644 --- a/src/serializers/to_object.ts +++ b/src/serializers/to_object.ts @@ -1,7 +1,7 @@ -import type { Matter, Serializer } from "../flatmatter.ts"; +import type {Serializer} from "../flatmatter.ts"; export default class ToObject implements Serializer { - serialize(parsedConfig: Matter): Matter { + serialize(parsedConfig: Record<string, unknown>): Record<string, unknown> { return parsedConfig; } } diff --git a/tsconfig.json b/tsconfig.json index f71ca1d..9f40b03 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,7 @@ "compilerOptions": { "module": "esnext", "target": "esnext", - "moduleResolution": "node", + "moduleResolution": "nodenext", "allowImportingTsExtensions": true, "declaration": true, "skipLibCheck": true, |
