Initial work on collecting tail and text. Reorganizing for cleaner public API.
This commit is contained in:
@@ -1,13 +1,33 @@
|
|||||||
import { createLineData, useDocument } from '@terrace/core'
|
import { createLineData, useDocument } from '@terrace/core'
|
||||||
import { createStringReader } from '@terrace/core/readers/js-string'
|
import { createStringReader } from '@terrace/core/readers/js-string'
|
||||||
|
|
||||||
|
|
||||||
|
const tceSchema = `
|
||||||
|
types
|
||||||
|
section object, text as content, tail as pos
|
||||||
|
content string
|
||||||
|
pos number
|
||||||
|
position number
|
||||||
|
options object
|
||||||
|
parameter1 number
|
||||||
|
parameter2 string
|
||||||
|
|
||||||
|
root object
|
||||||
|
title string
|
||||||
|
options options
|
||||||
|
options2 options
|
||||||
|
subsection section
|
||||||
|
`
|
||||||
|
|
||||||
const schema = {
|
const schema = {
|
||||||
types: {
|
types: {
|
||||||
subsection: {
|
section: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
text: 'content',
|
text: 'content',
|
||||||
tail: 'number',
|
tail: 'pos',
|
||||||
values: {
|
values: {
|
||||||
|
content: 'string',
|
||||||
|
pos: 'number',
|
||||||
position: {
|
position: {
|
||||||
type: 'number'
|
type: 'number'
|
||||||
}
|
}
|
||||||
@@ -28,8 +48,7 @@ const schema = {
|
|||||||
options: 'options',
|
options: 'options',
|
||||||
options2: 'options',
|
options2: 'options',
|
||||||
subsection: {
|
subsection: {
|
||||||
type: 'collection',
|
type: 'section',
|
||||||
collection: 'subsection'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,51 +67,49 @@ const lines = [
|
|||||||
` Ea dolore in aliquip fugiat anim adipisicing amet aute tempor et deserunt est duis sint.`,
|
` Ea dolore in aliquip fugiat anim adipisicing amet aute tempor et deserunt est duis sint.`,
|
||||||
`subsection 2`,
|
`subsection 2`,
|
||||||
` position 2`,
|
` position 2`,
|
||||||
` Aute deserunt incididunt ad in sint adipisicing est officia velit pariatur ipsum deserunt quis nulla.`
|
` Aute deserunt incididunt ad in sint adipisicing est officia velit pariatur ipsum deserunt quis nulla.`,
|
||||||
|
` Ea dolore in aliquip fugiat anim adipisicing amet aute tempor et deserunt est duis sint.`
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
const typeHandlers = {
|
const typeHandlers = {
|
||||||
string (key, definition, add) {
|
string (doc) {
|
||||||
return (doc, handlers) => {
|
return doc.tail().slice(1)
|
||||||
if (doc.head() !== key) return
|
|
||||||
add(key, doc.tail().slice(1))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
number (key, definition, add) {
|
number (doc) {
|
||||||
return (doc, handlers) => {
|
return +doc.tail().slice(1)
|
||||||
if (doc.head() !== key) return
|
|
||||||
add(key, +doc.tail().slice(1))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
object (key, definition, add) {
|
object (doc, handlers, definition) {
|
||||||
definition = resolve(definition)
|
definition = lookup(definition)
|
||||||
return (doc, handlers) => {
|
|
||||||
if (doc.head() !== key) return
|
|
||||||
const object = {}
|
|
||||||
add(key, object)
|
|
||||||
|
|
||||||
for (const [key, child] of Object.entries(definition.values)) {
|
const object = {}
|
||||||
addHandler(handlers, doc.level() + 1, key, child, (key, value) => (object[key] = value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collection (key, definition, add) {
|
|
||||||
return (doc, handlers) => {
|
|
||||||
if (doc.head() !== key) return
|
|
||||||
const collection = []
|
|
||||||
add(key, collection)
|
|
||||||
|
|
||||||
const child = resolve(definition.collection)
|
for (const [key, child] of Object.entries(definition.values)) {
|
||||||
addHandler(handlers, doc.level() + 1, '*', child, (key, value) => ( collection.push(value) ))
|
addHandler(handlers, doc.level() + 1, key, child, (key, value) => {
|
||||||
|
object[key] = value
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (definition.tail) {
|
||||||
|
object[definition.tail] = typeHandlers[definition.values[definition.tail]](doc, handlers)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (definition.text) {
|
||||||
|
const textKey = definition.text
|
||||||
|
object[textKey] = ''
|
||||||
|
addHandler(handlers, doc.level() + 1, '', definition.values[textKey], (key, value) => {
|
||||||
|
object[textKey] += object[textKey] ? `\n${doc.line()}` : doc.line()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return object
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolve (definition) {
|
function lookup (definition) {
|
||||||
const type = typeof definition === 'string' ? definition : definition.type
|
const type = typeof definition === 'string' ? definition : definition.type
|
||||||
if (schema.types[type]) return schema.types[type]
|
const resolvedDefinition = schema.types[type] || definition
|
||||||
else return definition
|
return typeof definition === 'string' ? resolvedDefinition : Object.assign({}, definition, resolvedDefinition)
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerTypes(typeHandlers, types) {
|
function registerTypes(typeHandlers, types) {
|
||||||
@@ -102,22 +119,27 @@ function registerTypes(typeHandlers, types) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addHandler(handlers, level, key, definition, add) {
|
function addHandler(handlers, level, key, definition, resolve) {
|
||||||
const type = typeof definition === 'string' ? definition : definition.type
|
const type = typeof definition === 'string' ? definition : definition.type
|
||||||
if (!handlers[level]) handlers[level] = []
|
if (!handlers[level]) handlers[level] = []
|
||||||
handlers[level].push(typeHandlers[type](key, definition, add))
|
handlers[level].push({
|
||||||
|
key,
|
||||||
|
resolve,
|
||||||
|
definition,
|
||||||
|
handler: typeHandlers[type]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const doc = useDocument(createStringReader(lines))
|
const doc = useDocument(createStringReader(lines))
|
||||||
|
|
||||||
const handlers = []
|
const handlers = []
|
||||||
|
|
||||||
registerTypes(typeHandlers, schema.types)
|
registerTypes(typeHandlers, schema.types)
|
||||||
|
|
||||||
const root = {}
|
const root = {}
|
||||||
|
|
||||||
for (const [key, child] of Object.entries(schema.root.values)) {
|
for (const [key, child] of Object.entries(schema.root.values)) {
|
||||||
addHandler(handlers, 0, key, child, (key, value) => (root[key] = value))
|
addHandler(handlers, 0, key, child, (k, v) => (root[k] = v))
|
||||||
}
|
}
|
||||||
|
|
||||||
let ended = false
|
let ended = false
|
||||||
@@ -128,8 +150,16 @@ async function main() {
|
|||||||
const level = doc.level()
|
const level = doc.level()
|
||||||
handlers.length = level + 1
|
handlers.length = level + 1
|
||||||
|
|
||||||
for (const handler of handlers[level] || []) {
|
const unmatchedHandler = handlers[level].find(h => h.key === '')
|
||||||
handler(doc, handlers)
|
let matched = false
|
||||||
|
for (const { key, definition, resolve, handler } of handlers[level] || []) {
|
||||||
|
if (doc.head() !== key) continue;
|
||||||
|
resolve(doc.head(), handler(doc, handlers, definition))
|
||||||
|
matched = true
|
||||||
|
}
|
||||||
|
if (!matched && unmatchedHandler) {
|
||||||
|
const { resolve, definition, handler } = unmatchedHandler
|
||||||
|
resolve(doc.head(), handler(doc, handlers, definition))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user