Skip to content

Commit

Permalink
Add document composition, with test wrapper at compose/parse-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
eemeli committed Oct 5, 2020
1 parent 373ae03 commit b4d223d
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 10 deletions.
5 changes: 2 additions & 3 deletions src/compose/compose-block-map.ts
Expand Up @@ -13,11 +13,10 @@ export function composeBlockMap(
const start = offset
const map = new YAMLMap(doc.schema)
if (anchor) doc.anchors.setAnchor(map, anchor)
const onRelError = (rel: number, msg: string) => onError(offset + rel, msg)

for (const { start, key, sep, value } of items) {
// key properties
const keyProps = resolveProps(start, 'explicit-key-ind', onRelError)
const keyProps = resolveProps(start, 'explicit-key-ind', offset, onError)
if (!keyProps.found) {
// implicit key
if (keyProps.anchor || keyProps.tagName || sep) {
Expand Down Expand Up @@ -49,7 +48,7 @@ export function composeBlockMap(
}

// value properties
const valueProps = resolveProps(sep || [], 'map-value-ind', onRelError)
const valueProps = resolveProps(sep || [], 'map-value-ind', offset, onError)
offset += valueProps.length

if (valueProps.found) {
Expand Down
4 changes: 1 addition & 3 deletions src/compose/compose-block-seq.ts
Expand Up @@ -14,9 +14,7 @@ export function composeBlockSeq(
const seq = new YAMLSeq(doc.schema)
if (anchor) doc.anchors.setAnchor(seq, anchor)
for (const { start, value } of items) {
const props = resolveProps(start, 'seq-item-ind', (o, m) =>
onError(offset + o, m)
)
const props = resolveProps(start, 'seq-item-ind', offset, onError)
offset += props.length
if (!props.found) {
if (props.anchor || props.tagName || value) {
Expand Down
39 changes: 39 additions & 0 deletions src/compose/compose-doc.ts
@@ -0,0 +1,39 @@
import { Document } from '../doc/Document.js'
import type { Options } from '../options.js'
import type * as Parser from '../parse/parser.js'
import { composeNode } from './compose-node.js'
import { resolveEnd } from './resolve-end.js'
import { resolveProps } from './resolve-props.js'
import { StreamDirectives } from './stream-directives.js'

export function composeDoc(
options: Options | null,
directives: StreamDirectives,
{ offset, start, value, end }: Parser.Document,
onError: (offset: number, message: string, warning?: boolean) => void
) {
const doc = new Document(undefined, options || undefined) as Document.Parsed
doc.version = directives.yaml.version
doc.setSchema() // FIXME: always do this in the constructor

const props = resolveProps(start, 'doc-start', offset, onError)
if (props.found) doc.directivesEndMarker = true

let to = offset + props.length
const token = value || { type: 'scalar', offset: to, indent: -1, source: '' }
doc.contents = composeNode(doc, token, props, onError)
if (doc.contents.range) to = doc.contents.range[1]
else {
// FIXME: remove once verified never happens
onError(to, 'Resolved child node has no range')
if (value) {
if ('offset' in value) to = value.offset
if ('source' in value && value.source) to += value.source.length
}
}
const { comment, length } = resolveEnd(end)
if (comment) doc.comment = comment

doc.range = [offset, to + length]
return doc
}
33 changes: 33 additions & 0 deletions src/compose/parse-docs.ts
@@ -0,0 +1,33 @@
import { Document } from '../doc/Document'
import { Parser } from '../parse/parser'
import { composeDoc } from './compose-doc'
import { StreamDirectives } from './stream-directives'

export function parseDocs(source: string) {
const directives = new StreamDirectives()
const docs: Document.Parsed[] = []
const lines: number[] = []

const onError = (offset: number, message: string, warning?: boolean) => {
console.error(warning ? '???' : '!!!', { offset, message })
}

const parser = new Parser(
token => {
switch (token.type) {
case 'directive':
directives.add(token.source, onError)
break
case 'document':
docs.push(composeDoc(null, directives, token, onError))
break
default:
console.log('###', token)
}
},
n => lines.push(n)
)
parser.parse(source)

return docs
}
11 changes: 8 additions & 3 deletions src/compose/resolve-props.ts
Expand Up @@ -11,8 +11,13 @@ export interface Props {

export function resolveProps(
start: SourceToken[],
indicator: 'explicit-key-ind' | 'map-value-ind' | 'seq-item-ind',
onError: (relOffset: number, message: string) => void
indicator:
| 'doc-start'
| 'explicit-key-ind'
| 'map-value-ind'
| 'seq-item-ind',
offset: number,
onError: (offset: number, message: string) => void
) {
let length = 0
let spaceBefore = false
Expand Down Expand Up @@ -50,7 +55,7 @@ export function resolveProps(
found = true
break
default:
onError(length, `Unexpected ${token.type} token`)
onError(offset + length, `Unexpected ${token.type} token`)
}
if (token.source) length += token.source.length
}
Expand Down
2 changes: 1 addition & 1 deletion src/compose/stream-directives.ts
@@ -1,6 +1,6 @@
export class StreamDirectives {
tags: Record<string, string> = { '!!': 'tag:yaml.org,2002:' }
yaml: { version: '1.1' | '1.2' } = { version: '1.2' }
yaml: { version: '1.1' | '1.2' | undefined } = { version: undefined }

static from(src: StreamDirectives) {
const res = new StreamDirectives()
Expand Down

0 comments on commit b4d223d

Please sign in to comment.