@linkeddatanotes/md2rdf 0.0.0-stage → 0.0.5
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/LICENSE +21 -0
- package/README.md +151 -3
- package/build/src/Md2Rdf.d.ts +394 -0
- package/build/src/Md2Rdf.js +789 -0
- package/build/src/Md2Rdf.js.map +1 -0
- package/build/src/commonNamespaces.ttl +80 -0
- package/build/src/index.d.ts +1 -0
- package/build/src/index.js +11 -0
- package/build/src/index.js.map +1 -0
- package/package.json +56 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Linked Data Notes, Leo "Leobard" Sauermann
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,151 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# md2rdf
|
|
2
|
+
|
|
3
|
+
Reads a Markdown string, detects linked data, and returns the linked data as array of `Quad` compatible with [RDF.js](http://rdf.js.org/).
|
|
4
|
+
|
|
5
|
+
`md2rdf` follows the conventions defined in [LinkedDataNotes](https://www.linkeddatanotes.org):
|
|
6
|
+
- RDF in `turtle` code fences is parsed
|
|
7
|
+
- using [N3.js](https://github.com/rdfjs/n3.js)
|
|
8
|
+
- section headings are interpreted
|
|
9
|
+
- date and time prefixes result in `schema:temporalCoverage`
|
|
10
|
+
- `this:` in a `turtle` fence is interpreted as an URI reference to the current section
|
|
11
|
+
- common namespaces are part of this package and available at `commonNamespaces()`, it is recommended to pass them as `options.namespaces`.
|
|
12
|
+
|
|
13
|
+
The returned `rdfjs Stream<Quad>` can be passed to `quadstore.import()`.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
`npm install @linkeddatanotes/md2rdf`
|
|
18
|
+
|
|
19
|
+
## Parsing markdown files
|
|
20
|
+
|
|
21
|
+
Load the markdown, pass it to Md2Rdf.
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Md2Rdf and dependencies
|
|
25
|
+
import {Md2Rdf, commonNamespaces} from '@linkeddatanotes/md2rdf';
|
|
26
|
+
import {DataFactory as N3DataFactory, Writer} from 'n3';
|
|
27
|
+
|
|
28
|
+
// options for Md2Rdf
|
|
29
|
+
const options = {
|
|
30
|
+
factory: N3DataFactory,
|
|
31
|
+
// defines common namespaces such as schema
|
|
32
|
+
namespaces: commonNamespaces(),
|
|
33
|
+
// contains a date
|
|
34
|
+
baseIRI: 'file://2015-12-12_ParisAgreement.md',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// a sample markdown including LinkedDataNotes
|
|
38
|
+
// - a heading with time, in combination with the baseIRI this defines the schema:temporalCoverage
|
|
39
|
+
// - a turtle code fence using tildes as the multiline typescript string is using backticks
|
|
40
|
+
const exampleMarkdown = `
|
|
41
|
+
# 2015-12-12 Saturday at COP 21
|
|
42
|
+
The COP21 conference at Le Bourget was extended by one day, Saturday the 12th.
|
|
43
|
+
On this day, the Paris Agreement was adopted.
|
|
44
|
+
|
|
45
|
+
~~~turtle
|
|
46
|
+
this: a schema:PublicEvent;
|
|
47
|
+
schema:organizer <http://www.wikidata.org/entity/Q104150918>.
|
|
48
|
+
~~~
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
// create the instance of Md2Rdf
|
|
52
|
+
const md2rdf = new Md2Rdf(options);
|
|
53
|
+
|
|
54
|
+
// transform Markdown to RDF
|
|
55
|
+
const quads = md2rdf.parseString(exampleMarkdown);
|
|
56
|
+
|
|
57
|
+
// print the RDF as turtle
|
|
58
|
+
let s = '# Md2Rdf for ' + options.baseIRI + '\n';
|
|
59
|
+
const writer = new Writer();
|
|
60
|
+
writer.addQuads(quads);
|
|
61
|
+
writer.end((error, result) => s += result);
|
|
62
|
+
console.log(s);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Read the tests for more examples.
|
|
66
|
+
|
|
67
|
+
This library is used by [LinkedDataNotes](https://www.linkeddatanotes.org) and `obsidian-linkeddatanotes`.
|
|
68
|
+
See more example code there.
|
|
69
|
+
|
|
70
|
+
## License
|
|
71
|
+
|
|
72
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
73
|
+
|
|
74
|
+
This uses
|
|
75
|
+
- [solid-namespace](https://github.com/solid/solid-namespace/blob/master/index.js) which is MIT licensed.
|
|
76
|
+
|
|
77
|
+
## Design decisions
|
|
78
|
+
|
|
79
|
+
### String input
|
|
80
|
+
Currently, input is passed as `string`. This is enough for the first use in Obsidian [Vaul.cachedRead()](https://docs.obsidian.md/Reference/TypeScript+API/Vault/cachedRead).
|
|
81
|
+
|
|
82
|
+
Reading from a `Stream` would be a welcome addition. Note that N3 Parser is not returning a generator but calling a passed callback function, so a streaming API may require an intermediate queue or a "/zero-queue backpressure bridge/".
|
|
83
|
+
|
|
84
|
+
### Markdown sections
|
|
85
|
+
Markdown sections that resulted in RDF are marked using the [`md2rdf` vocabulary](https://www.linkeddatanotes.org/ns/md2rdf/) and `rdfs`.
|
|
86
|
+
|
|
87
|
+
Above `exampleMarkdown` results in:
|
|
88
|
+
|
|
89
|
+
```turtle
|
|
90
|
+
PREFIX md2rdf: <https://www.linkeddatanotes.org/ns/md2rdf/>
|
|
91
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
92
|
+
PREFIX schema: <https://schema.org/>
|
|
93
|
+
|
|
94
|
+
<file://2015-12-12_ParisAgreement.md#2015-12-12-Saturday-at-COP-21> a schema:PublicEvent, md2rdf:Section;
|
|
95
|
+
rdfs:label "2015-12-12 Saturday at COP 21";
|
|
96
|
+
md2rdf:headingLevel "1";
|
|
97
|
+
schema:temporalCoverage "2015-12-12";
|
|
98
|
+
schema:organizer <http://www.wikidata.org/entity/Q104150918>.
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Namespaces
|
|
102
|
+
Namespaces are passed as string via `Md2RdfParserOptions.namespaces`. This is simple and works.
|
|
103
|
+
|
|
104
|
+
It comes with the caveat that parsing the namespaces for each turtle code fence wastes CPU.
|
|
105
|
+
It would be better to parse them once.
|
|
106
|
+
N3.Parser does not support passing of pre-parsed Namespaces. This could be improved by extending N3.Parser or by using N3 internals: quadCallback, inputstream, injecting parser._prefixes[prefix]=value.
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
## Development
|
|
110
|
+
This project follows [gts](https://github.com/google/gts) to avoid bikeshedding.
|
|
111
|
+
|
|
112
|
+
### Testing
|
|
113
|
+
This project uses [mocha](https://github.com/mochajs). [assert](https://github.com/browserify/commonjs-assert) is used as the [assert syntax](https://nodejs.org/api/assert.html) uses simple js constructs.
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
npm run test
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Publishing a release
|
|
120
|
+
|
|
121
|
+
After we did fantastic stuff and all our tests are ok, time to publish.
|
|
122
|
+
|
|
123
|
+
Packaging and publishing a release currently works like this:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
# at this point: git must be clean, on main
|
|
127
|
+
git status
|
|
128
|
+
|
|
129
|
+
# confirm the release looks good
|
|
130
|
+
npm pack --dry-run
|
|
131
|
+
|
|
132
|
+
# builds, tests, bumps, tags, pushes
|
|
133
|
+
npm version patch
|
|
134
|
+
|
|
135
|
+
# publish
|
|
136
|
+
npm login
|
|
137
|
+
npm publish
|
|
138
|
+
|
|
139
|
+
# after release: main becomes prepatch. This bumps, tags, pushes.
|
|
140
|
+
npm version prepatch
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Part of LinkedDataNotes
|
|
144
|
+
This project is part of [LinkedDataNotes](https://www.linkeddatanotes.org). LinkedDataNotes is a minimalistic convention to use linked data within markdown notes.
|
|
145
|
+
|
|
146
|
+
## Contribute
|
|
147
|
+
**md2rdf** is open for contributions. File an issue, create a pull request.
|
|
148
|
+
|
|
149
|
+
Get in touch via getintouch@linkeddatanotes.org.
|
|
150
|
+
|
|
151
|
+
Md2Rdf was started by Leo "Leobard" Sauermann on 2021-02-10.
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
import type { ParserOptions } from 'n3';
|
|
2
|
+
import Parser from 'n3/lib/N3Parser';
|
|
3
|
+
import { DataFactory, Quad, NamedNode } from '@rdfjs/types';
|
|
4
|
+
/**
|
|
5
|
+
* Md2RdfParserOptions to configure Md2Rdf.
|
|
6
|
+
*
|
|
7
|
+
* They are passed on to the N3 Parser.
|
|
8
|
+
*/
|
|
9
|
+
export interface Md2RdfParserOptions extends ParserOptions {
|
|
10
|
+
/**
|
|
11
|
+
* The file IRI of the currently parsed Markdown file.
|
|
12
|
+
* inherited from ParserOptions, described here explicitly to clarify use.
|
|
13
|
+
*/
|
|
14
|
+
baseIRI: string;
|
|
15
|
+
/**
|
|
16
|
+
* RDF DataFactory to create nodes.
|
|
17
|
+
*/
|
|
18
|
+
factory: DataFactory;
|
|
19
|
+
/**
|
|
20
|
+
* namespaces set here will be prefixed to every `turtle` block before parsing.
|
|
21
|
+
* Namespaces defined within a block will override.
|
|
22
|
+
* Hint: md2rdf ships common namespaces. Load them with commonNamespaces() and pass them in.
|
|
23
|
+
* Format: turtle string
|
|
24
|
+
*/
|
|
25
|
+
namespaces?: string | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Set the onError handler to get information about errors and warnings and to stop the parser when you find necessary.
|
|
28
|
+
* Leave the onError handler empty to let the parser skip all errors and warnings and return as many quads as possible.
|
|
29
|
+
*
|
|
30
|
+
* Implementations of the error handler
|
|
31
|
+
* - may read the passed errors and warnings and notify the user, write them to a log, or to a quadstore
|
|
32
|
+
* - may stop the parser by throwing the error back at the parser
|
|
33
|
+
*
|
|
34
|
+
* @param error a ParseError with a message and more details
|
|
35
|
+
* @throws {ParseError} throws the passed error back to the caller to signal that the parsing should stop now. Swallows it to continue.
|
|
36
|
+
*/
|
|
37
|
+
onError?: (error: ParseError) => void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* ParseError is passed in the onError() handler of Md2RdfParserOptions.
|
|
41
|
+
* Implementations of the Md2RdfParserOptions.onError() handler should read the ParseError parameter
|
|
42
|
+
* for logging and deciding whether to continue.
|
|
43
|
+
*/
|
|
44
|
+
export declare class ParseError extends Error {
|
|
45
|
+
/**
|
|
46
|
+
* file IRI of the currently parsed Markdown file.
|
|
47
|
+
*/
|
|
48
|
+
baseIRI: string;
|
|
49
|
+
/**
|
|
50
|
+
* severity level
|
|
51
|
+
*
|
|
52
|
+
* error - data cannot be parsed
|
|
53
|
+
* warning - data is parsed but result may be unexpected
|
|
54
|
+
*/
|
|
55
|
+
severity: 'error' | 'warning';
|
|
56
|
+
/**
|
|
57
|
+
* Line number within the currently parsed Markdown file.
|
|
58
|
+
*/
|
|
59
|
+
line?: number;
|
|
60
|
+
/**
|
|
61
|
+
* create a ParseError.
|
|
62
|
+
* Helper function
|
|
63
|
+
* @param cause Underlying error or message.
|
|
64
|
+
* @param options Options to pass the baseIRI of the currently parsed Markdown file.
|
|
65
|
+
* @param line Line number within the currently parsed Markdown file.
|
|
66
|
+
* @param severity Severity level 'error' or 'warning' inspired by methods of `console.`.
|
|
67
|
+
* If severity is not passed, assume 'error' unless the cause Error name ends with string 'Warning'.
|
|
68
|
+
* @returns
|
|
69
|
+
*/
|
|
70
|
+
constructor(cause: unknown, options: Md2RdfParserOptions, line?: number, severity?: 'error' | 'warning');
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* HomonymHeadingWarning is a possible cause in ParseError.
|
|
74
|
+
* Example:
|
|
75
|
+
* Heading "MyHeading" used for different sections containing a turtle block with "this:". IRI "file#MyHeading" is homonym for both sections.
|
|
76
|
+
*/
|
|
77
|
+
export declare class HomonymHeadingWarning extends Error {
|
|
78
|
+
name: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* TimeNoDateInHeadingHierarchyWarning is a possible cause in ParseError.
|
|
82
|
+
* Example:
|
|
83
|
+
* Heading with time "13:45" could be nested within a date to define schema:temporalCoverage. No parent date found.
|
|
84
|
+
*/
|
|
85
|
+
export declare class TimeNoDateInHeadingHierarchyWarning extends Error {
|
|
86
|
+
name: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Md2Rdf parses Markdown files and returns RDF quads.
|
|
90
|
+
*
|
|
91
|
+
* It follows the minimalistic LinkedDataNotes convention.
|
|
92
|
+
*
|
|
93
|
+
* It makes a "best effort" attempt to extract RDF from Markdown. It will report ParseError instances and go on if not stopped.
|
|
94
|
+
* Example: Syntax errors in one turtle code fence break this one fence, but the data in the next turtle code fences may be fine.
|
|
95
|
+
*
|
|
96
|
+
* Documentation: see README of the project.
|
|
97
|
+
*
|
|
98
|
+
*/
|
|
99
|
+
export declare class Md2Rdf {
|
|
100
|
+
protected options: Md2RdfParserOptions;
|
|
101
|
+
protected optionsNamespaceLineCount: number;
|
|
102
|
+
protected context?: ParseContext;
|
|
103
|
+
/**
|
|
104
|
+
* parserN3 is loaded lazily using _parserN3() when a Markdown file actually contains `turtle`.
|
|
105
|
+
*/
|
|
106
|
+
protected parserN3?: Parser;
|
|
107
|
+
constructor(options: Md2RdfParserOptions);
|
|
108
|
+
/**
|
|
109
|
+
* only instantiate the parser when we really need it, to save memory and performance when checking many files
|
|
110
|
+
* @returns lazy-loaded parser
|
|
111
|
+
*/
|
|
112
|
+
_parserN3(): Parser;
|
|
113
|
+
/**
|
|
114
|
+
* Parse the line.
|
|
115
|
+
* If it is an [atx heading](https://spec.commonmark.org/0.31.2/#atx-heading),
|
|
116
|
+
* 1. remember it in this.headings
|
|
117
|
+
* 2. generate quads that result from the heading, if it contains information according to LinkedDataNotes convention
|
|
118
|
+
* @param line
|
|
119
|
+
* @returns true, when this is a heading
|
|
120
|
+
*/
|
|
121
|
+
_parseHeading(line: string): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Parse turtle or N3 syntax from the passed code block from the markdown file
|
|
124
|
+
* @param {String} n3 - the turtle passed as String
|
|
125
|
+
* @param {number} startLine the line number where the block started
|
|
126
|
+
* @return quads the quads parsed from the turtleString as array
|
|
127
|
+
* @throws error , see N3 parse()
|
|
128
|
+
*/
|
|
129
|
+
_parseN3String(n3: string, startLine: number): void;
|
|
130
|
+
/**
|
|
131
|
+
* Check if the current line starts with a turtleBlock.
|
|
132
|
+
* If yes, parse the contents of a turtle code fence block and process it
|
|
133
|
+
* @param line - the line to check if it is an opening ```turtle code fence block
|
|
134
|
+
* @returns true, if this line started a turtle block
|
|
135
|
+
*/
|
|
136
|
+
_parseTurtleBlock(line: string): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Parses markdown and returns an array of quads.
|
|
139
|
+
* See README.md
|
|
140
|
+
*
|
|
141
|
+
* Note: the method must only be called by a single thread. To parallelize parsing, use two Md2Rdf instances.
|
|
142
|
+
*
|
|
143
|
+
* @param input string of markdown
|
|
144
|
+
* @returns
|
|
145
|
+
* quads: the array of rdf.js Quad parsed so far
|
|
146
|
+
* error: this is the error that stopped the run, it should have been thrown by options.onError.
|
|
147
|
+
* @throws errors when there are unexpected programming bugs
|
|
148
|
+
*/
|
|
149
|
+
parseString(input: string): {
|
|
150
|
+
quads: Array<Quad>;
|
|
151
|
+
error?: ParseError;
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Helper Object to
|
|
156
|
+
* - hold variables during parsing
|
|
157
|
+
* - share helpers between Md2Rdf and Headings2This
|
|
158
|
+
*/
|
|
159
|
+
declare class ParseContext {
|
|
160
|
+
options: Md2RdfParserOptions;
|
|
161
|
+
ns: {
|
|
162
|
+
rdf: import("@rdfjs/namespace").NamespaceBuilder<string>;
|
|
163
|
+
rdfs: import("@rdfjs/namespace").NamespaceBuilder<string>;
|
|
164
|
+
schema: import("@rdfjs/namespace").NamespaceBuilder<string>;
|
|
165
|
+
md2rdf: import("@rdfjs/namespace").NamespaceBuilder<string>;
|
|
166
|
+
};
|
|
167
|
+
quads: Array<Quad>;
|
|
168
|
+
byLine: StringByLine;
|
|
169
|
+
headings: Headings2This;
|
|
170
|
+
constructor(options: Md2RdfParserOptions, byLine: StringByLine);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* A generator that takes the passed string,
|
|
174
|
+
* splits it by \r\n and \n,
|
|
175
|
+
* yield each line,
|
|
176
|
+
* count current linenumber.
|
|
177
|
+
*
|
|
178
|
+
* Does not split everything in memory in the beginning to save memory.
|
|
179
|
+
*
|
|
180
|
+
* Use as iterator:
|
|
181
|
+
* let by = new StringByLine('example');
|
|
182
|
+
* for (const line of by) {
|
|
183
|
+
* console.log(line);
|
|
184
|
+
* }
|
|
185
|
+
*
|
|
186
|
+
* Use with linenumber: see below in parseString()
|
|
187
|
+
*
|
|
188
|
+
* @param input string
|
|
189
|
+
*/
|
|
190
|
+
declare class StringByLine {
|
|
191
|
+
input: string;
|
|
192
|
+
linenumber: number;
|
|
193
|
+
start: number;
|
|
194
|
+
idx?: number;
|
|
195
|
+
constructor(input: string);
|
|
196
|
+
next(): IteratorResult<string>;
|
|
197
|
+
[Symbol.iterator](): this;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Helper class to concatenate ISO Times from filename and headings.
|
|
201
|
+
*
|
|
202
|
+
* The first element in the DateTimeHierarchy is the current heading (or filename, if no section).
|
|
203
|
+
* It points to a parent element in DateTimeHierarchy for further information.
|
|
204
|
+
*
|
|
205
|
+
* To read it, call toISODateTimeString.
|
|
206
|
+
*
|
|
207
|
+
* Once a date or date+time is found in the time hierarchy, it is returned.
|
|
208
|
+
* If no date is found, undefined is returned.
|
|
209
|
+
*
|
|
210
|
+
* Updating the current DateTimeHierarchy while parsing Markdown is handled by update()
|
|
211
|
+
*
|
|
212
|
+
* Evaluation is lazy: the current hierarchy is stored after every heading,
|
|
213
|
+
* but the regex time parsing is only done when an actual this: element is found in a turtle block
|
|
214
|
+
* to save CPU.
|
|
215
|
+
*
|
|
216
|
+
* Assumptions:
|
|
217
|
+
* - vast majority of Markdown will not contain turtle and `this:`, only seldomly date will be needed
|
|
218
|
+
* - regex parsing costs CPU
|
|
219
|
+
*/
|
|
220
|
+
export declare class DateTimeHierarchy {
|
|
221
|
+
/**
|
|
222
|
+
* This should match a DATE followed by TIME followed by ZONE
|
|
223
|
+
* DATE is optional
|
|
224
|
+
* TIME is optional, if TIME is set, ZONE is also optional
|
|
225
|
+
* yyyy-mm-dd ... optional
|
|
226
|
+
* 13:55
|
|
227
|
+
* 2021-02-10
|
|
228
|
+
* 2021-02-10 13:55
|
|
229
|
+
* 2021-02-10T13:55
|
|
230
|
+
* 2021-02-10 13:55:44.1234
|
|
231
|
+
* 2021-02-10T13:55Z+01:00
|
|
232
|
+
*/
|
|
233
|
+
static readonly DATE_TIME_ZONE: RegExp;
|
|
234
|
+
static readonly TIME_ONLY: RegExp;
|
|
235
|
+
/**
|
|
236
|
+
* Same as DATE_TIME_ZONE, but the date part allows reduced ISO 8601 precision
|
|
237
|
+
* (yyyy or yyyy-mm, not just yyyy-mm-dd), and is anchored at both ends since it
|
|
238
|
+
* is only ever run against a single endpoint token already isolated by DURATION.
|
|
239
|
+
*/
|
|
240
|
+
static readonly DATE_TIME_ZONE_FLEX: RegExp;
|
|
241
|
+
/**
|
|
242
|
+
* Matches a schema:temporalCoverage-style duration: two date/time endpoints
|
|
243
|
+
* separated by "/", "-" or "–" (an ISO 8601 time interval, e.g. "1939/1945" or
|
|
244
|
+
* "2015-11/.."). The end endpoint may be ".." (open-ended), a date/time of its
|
|
245
|
+
* own, or a bare time that shares the start endpoint's date.
|
|
246
|
+
*/
|
|
247
|
+
static readonly DURATION: RegExp;
|
|
248
|
+
parent?: DateTimeHierarchy;
|
|
249
|
+
/**
|
|
250
|
+
* 0 = filename from baseIRI
|
|
251
|
+
* 1 = h1
|
|
252
|
+
* ...
|
|
253
|
+
* 6 = h6
|
|
254
|
+
*/
|
|
255
|
+
level: number;
|
|
256
|
+
/**
|
|
257
|
+
* the content of the heading (after the #)
|
|
258
|
+
* or
|
|
259
|
+
* the filename
|
|
260
|
+
*/
|
|
261
|
+
input: string;
|
|
262
|
+
/**
|
|
263
|
+
* was the input already parsed to date/time/zone?
|
|
264
|
+
* for lazy evaluation
|
|
265
|
+
*/
|
|
266
|
+
parsed: boolean;
|
|
267
|
+
date?: string;
|
|
268
|
+
time?: string;
|
|
269
|
+
zone?: string;
|
|
270
|
+
/**
|
|
271
|
+
* The following three fields are only set when the input is a duration
|
|
272
|
+
* (ISO 8601 time interval, e.g. "1939/1945" or "2015-11/..").
|
|
273
|
+
* endDate/endTime/endZone hold the end endpoint; when the end endpoint is a
|
|
274
|
+
* bare time (e.g. "09:00-17:00"), endDate stays undefined and the start's
|
|
275
|
+
* own date is reused for it.
|
|
276
|
+
*/
|
|
277
|
+
endDate?: string;
|
|
278
|
+
endTime?: string;
|
|
279
|
+
endZone?: string;
|
|
280
|
+
/**
|
|
281
|
+
* true when the duration's end endpoint was written as ".." (open-ended,
|
|
282
|
+
* e.g. "2015-11/..").
|
|
283
|
+
*/
|
|
284
|
+
openEnded?: boolean;
|
|
285
|
+
constructor(level: number, input: string, parent?: DateTimeHierarchy);
|
|
286
|
+
/**
|
|
287
|
+
* In the hierarchy, find the next date.
|
|
288
|
+
* @returns a date if found, as string.
|
|
289
|
+
*/
|
|
290
|
+
_findDate(): string | undefined;
|
|
291
|
+
/**
|
|
292
|
+
* Ensure this heading has been parsed before accessing the fields.
|
|
293
|
+
* Read the input, find a date and time, write it into the fields.
|
|
294
|
+
*/
|
|
295
|
+
_parse(): void;
|
|
296
|
+
/**
|
|
297
|
+
* true when this heading's input was parsed as a duration (ISO 8601 time
|
|
298
|
+
* interval), i.e. it has an end endpoint or is open-ended.
|
|
299
|
+
*/
|
|
300
|
+
get isDuration(): boolean;
|
|
301
|
+
/**
|
|
302
|
+
* Read the current Heading Hierarchy and format it as a schema:temporalCoverage value:
|
|
303
|
+
* either a plain ISO 8601 date/date-time, or - when the heading was written as a
|
|
304
|
+
* duration - an ISO 8601 time interval such as "1939/1945" or "2015-11/..".
|
|
305
|
+
* @returns the ISO 8601 date/date-time or interval defined by the heading hierarchy, or undefined if none found.
|
|
306
|
+
* @throws DoubleTimeInHeadingHierarchyWarning, TimeNoDateInHeadingHierarchyWarning
|
|
307
|
+
*/
|
|
308
|
+
toISODateTimeString(context: ParseContext): string | undefined;
|
|
309
|
+
/**
|
|
310
|
+
* update the DateTimeHierarchy based on the latest input
|
|
311
|
+
* @param level current level
|
|
312
|
+
* @param input content of the heading, after "#"
|
|
313
|
+
* @param parent parent in the DateTimeHierarchy
|
|
314
|
+
* @returns an update pointer to the current relevant heading or file in the DateTimeHierarchy
|
|
315
|
+
*/
|
|
316
|
+
static update(level: number, input: string, parent?: DateTimeHierarchy): DateTimeHierarchy | undefined;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Lazily load and cache the commonNamespaces.ttl shipped with md2rdf.
|
|
320
|
+
* @returns the common namespaces as turtle string
|
|
321
|
+
*/
|
|
322
|
+
export declare function commonNamespaces(): string;
|
|
323
|
+
/**
|
|
324
|
+
* Handling of headings and `this:`
|
|
325
|
+
*/
|
|
326
|
+
declare class Headings2This {
|
|
327
|
+
protected options: Md2RdfParserOptions;
|
|
328
|
+
/**
|
|
329
|
+
* reusable regex to match headings
|
|
330
|
+
*/
|
|
331
|
+
matchHeading: RegExp;
|
|
332
|
+
/**
|
|
333
|
+
* Buffer for the last heading content that was passed to parseLine,
|
|
334
|
+
* to be used when needed by prepThisSectionIRI.
|
|
335
|
+
* It is the "content" after the hash-marks and the space
|
|
336
|
+
* https://spec.commonmark.org/0.31.2/#atx-headings
|
|
337
|
+
*/
|
|
338
|
+
lastHeadingContent: string | undefined;
|
|
339
|
+
/**
|
|
340
|
+
* line number of the lastHeadingContent
|
|
341
|
+
*/
|
|
342
|
+
lastHeadingLinenumber: number | undefined;
|
|
343
|
+
/**
|
|
344
|
+
* The URI for the current section after the lastHeadingContent.
|
|
345
|
+
* Initiated undefined and reset to undefined after each heading, initialized lazily when needed.
|
|
346
|
+
*/
|
|
347
|
+
thisSectionIRI: NamedNode<string> | undefined;
|
|
348
|
+
/**
|
|
349
|
+
* multiple headings having the same hash?
|
|
350
|
+
* remember them to send a warning
|
|
351
|
+
*/
|
|
352
|
+
usedThisIRIs: Set<unknown>;
|
|
353
|
+
/**
|
|
354
|
+
* Time and date data found in the hierarchy of
|
|
355
|
+
* - filename (baseIRI) and
|
|
356
|
+
* - headings 1 to 6
|
|
357
|
+
*/
|
|
358
|
+
dateTimeHierarchy?: DateTimeHierarchy;
|
|
359
|
+
/**
|
|
360
|
+
* Passing options
|
|
361
|
+
* @param options
|
|
362
|
+
*/
|
|
363
|
+
constructor(options: Md2RdfParserOptions);
|
|
364
|
+
/**
|
|
365
|
+
* Translate thea markdown heading to a fragment which can be used in an IRI.
|
|
366
|
+
* See LinkeDataNotes-Markdown Syntax
|
|
367
|
+
* @param {String} headingContent the content of the heading. This is the string after the ATX heading hash-marks and space (not including leading hash-signs). https://spec.commonmark.org/0.31.2/#atx-headings
|
|
368
|
+
* @return {String} the fragment
|
|
369
|
+
*/
|
|
370
|
+
_headingToFragment(headingContent: string): string;
|
|
371
|
+
/**
|
|
372
|
+
* create a section IRI based on file and fragment
|
|
373
|
+
*/
|
|
374
|
+
_createSectionIri(inputfileIRI: string, fragment: string): string;
|
|
375
|
+
/**
|
|
376
|
+
* Parse the line for a heading starting with `#`, see [atx heading](https://spec.commonmark.org/0.31.2/#atx-heading).
|
|
377
|
+
* It remembers the headings that were passed to it, should they be later needed by prepThisSectionIRI() or the dateTimeHierarchy.
|
|
378
|
+
* @param line the Markdown line
|
|
379
|
+
* @param linenumber the current line number, should it be needed for error logging later
|
|
380
|
+
* @returns true, when the current line is an atx heading starting with '#'
|
|
381
|
+
*/
|
|
382
|
+
parseLine(line: string, linenumber: number): boolean;
|
|
383
|
+
/**
|
|
384
|
+
* Prepare the current section IRI, as the caller will use it in quads.
|
|
385
|
+
*
|
|
386
|
+
* This:
|
|
387
|
+
* - mints the IRI, remembers it as node for reuse further down the section
|
|
388
|
+
* - adds metadata about the section via quads.push()
|
|
389
|
+
*
|
|
390
|
+
* @returns the section IRI as RDF Node or undefined if no heading was in the file yet
|
|
391
|
+
*/
|
|
392
|
+
prepThisSectionIRI(context: ParseContext): undefined | NamedNode<string>;
|
|
393
|
+
}
|
|
394
|
+
export {};
|