127 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import { useDocument } from '@terrace/core'
 | 
						|
import { createStringReader } from '@terrace/core/readers/js-string'
 | 
						|
 | 
						|
const lines = [
 | 
						|
  `name @terrace/core`,
 | 
						|
  `version 0.0.1`,
 | 
						|
  `randomthing test`,
 | 
						|
  `license MIT`,
 | 
						|
  `license GPL`,
 | 
						|
  `exports`,
 | 
						|
  ` .`,
 | 
						|
  `  import ./dist/index.js`,
 | 
						|
  `  require ./dist/index.cjs`,
 | 
						|
  ` ./parser`,
 | 
						|
  `  import ./dist/parser.js`,
 | 
						|
  `  require ./dist/parser.cjs`,
 | 
						|
  ``,
 | 
						|
  ` ./document`,
 | 
						|
  `  import ./dist/document.js`,
 | 
						|
  `  require ./dist/document.cjs`,
 | 
						|
  ``,
 | 
						|
  ` ./readers/node-readline`,
 | 
						|
  `  import ./dist/readers/node-readline.js`,
 | 
						|
  `  require ./dist/readers/node-readline.cjs`,
 | 
						|
  ``,
 | 
						|
  ` ./readers/js-string`,
 | 
						|
  `  import ./dist/readers/js-string.js`,
 | 
						|
  `  require ./dist/readers/js-string.cjs`,
 | 
						|
  `scripts`,
 | 
						|
  ` test vitest ./src`,
 | 
						|
  ` build vite build`,
 | 
						|
  `devDependencies`,
 | 
						|
  ` vite ^3.2.3`,
 | 
						|
  ` vitest ^0.24.5`,
 | 
						|
  ``,
 | 
						|
  `authors`,
 | 
						|
  ` author`,
 | 
						|
  `  name Joshua Bemenderfer`,
 | 
						|
  `  email josh@thederf.com`,
 | 
						|
  ``,
 | 
						|
  `  Further comments below. As I will now demonstrate, there is no simple`,
 | 
						|
  `   even if embedded`,
 | 
						|
  `  way of dealing with this problem.`,
 | 
						|
  ` author`,
 | 
						|
  `  name Second Person`,
 | 
						|
  `  email second@secondperson.com`,
 | 
						|
  `  More text,`,
 | 
						|
  `  across two lines.`,
 | 
						|
  `list`,
 | 
						|
  ` - item1`,
 | 
						|
  ` - item2`
 | 
						|
]
 | 
						|
 | 
						|
// Schema
 | 
						|
// name tail
 | 
						|
// version tail
 | 
						|
// license tail
 | 
						|
// exports object
 | 
						|
//   #any object
 | 
						|
//     import tail
 | 
						|
//     require tail
 | 
						|
// scripts object
 | 
						|
//   #any tail
 | 
						|
// devDependencies
 | 
						|
//   #any tail
 | 
						|
// author object
 | 
						|
//   name tail
 | 
						|
//   email tail
 | 
						|
//   #text
 | 
						|
 | 
						|
 | 
						|
async function main() {
 | 
						|
  const { head, tail, next, match, level, line } = useDocument(createStringReader(lines))
 | 
						|
 | 
						|
  const structure = {}
 | 
						|
 | 
						|
  async function kvObject(handle) {
 | 
						|
    const obj = {}
 | 
						|
    const l = level()
 | 
						|
    while (await next(l)) {
 | 
						|
      if (!head()) continue
 | 
						|
      obj[head()] = handle ? await handle(level()) : tail().trim()
 | 
						|
    }
 | 
						|
    return obj
 | 
						|
  }
 | 
						|
 | 
						|
  while (await next()) {
 | 
						|
    if (match('name')) structure.name = tail().trim()
 | 
						|
    if (match('version')) structure.version = tail().trim()
 | 
						|
    if (match('exports')) structure.exports = await kvObject(async l => {
 | 
						|
      const obj = {}
 | 
						|
      while (await next(l)) {
 | 
						|
        if (match('import')) obj.import = tail().trim()
 | 
						|
        if (match('require')) obj.require = tail().trim()
 | 
						|
      }
 | 
						|
      return obj
 | 
						|
    })
 | 
						|
 | 
						|
    if (match('scripts')) structure.scripts = await kvObject()
 | 
						|
    if (match('devDependencies')) structure.devDependencies = await kvObject()
 | 
						|
 | 
						|
    if (match('author')) {
 | 
						|
      if (!structure.authors) structure.authors = []
 | 
						|
      const author = {}
 | 
						|
      structure.authors.push(author)
 | 
						|
 | 
						|
      const l = level()
 | 
						|
      while (await next(l)) {
 | 
						|
        if (!head()) continue
 | 
						|
        if (match('name')) author.name = tail().trim()
 | 
						|
        else if (match('email')) author.email = tail().trim()
 | 
						|
        else {
 | 
						|
          if (!author['#text']) author['#text'] = [line(l + 1)]
 | 
						|
          // Loop through all remaining lines to avoid re-matching name or email above.
 | 
						|
          while(await next(l)) {
 | 
						|
            author['#text'].push(line(l + 1))
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  console.dir(structure, { depth: null })
 | 
						|
}
 | 
						|
 | 
						|
main()
 |