Skip to content

Commit

Permalink
Merge pull request #3 from hildjj/docs2
Browse files Browse the repository at this point in the history
Some doc tweaks
  • Loading branch information
hildjj committed May 7, 2023
2 parents b986245 + 3b172b3 commit fe18938
Show file tree
Hide file tree
Showing 13 changed files with 875 additions and 648 deletions.
13 changes: 11 additions & 2 deletions README.md
@@ -1,4 +1,6 @@
A simple DOM for [expat-wasm](https://github.com/hildjj/expat-wasm).
# expat-wasm-dom

A Document Object Model for [expat-wasm](https://github.com/hildjj/expat-wasm).

To install:

Expand All @@ -10,11 +12,18 @@ To use:

```js
import DomParser from 'expat-wasm-dom'
const doc = DomParser.parse('<foo/>')
const doc = DomParser.parse('<foo><bar/></foo>')
console.log(doc.root.toString())
console.log(doc.get('//bar'))
```

Note that there is an implementation of XPath3 included. It is not
feature-complete yet, but it has a bunch of useful features already.

Full [documentation](https://hildjj.github.io/expat-wasm-dom/) is available.

A Command Line Interface is available in [expat-wasm-dom-cli](https://github.com/hildjj/expat-wasm-dom/tree/main/cli).

--
[![Tests](https://github.com/hildjj/expat-wasm-dom/actions/workflows/node.js.yml/badge.svg)](https://github.com/hildjj/expat-wasm-dom/actions/workflows/node.js.yml)
[![codecov](https://codecov.io/gh/hildjj/expat-wasm-dom/branch/main/graph/badge.svg?token=MPGGvwbrqR)](https://codecov.io/gh/hildjj/expat-wasm-dom)
51 changes: 51 additions & 0 deletions cli/README.md
@@ -0,0 +1,51 @@
# expat-wasm-dom-cli

Command line utilities for [expat-wasm-dom](https://github.com/hildjj/expat-wasm-dom).

## ewlint

```txt
Usage: ewlint [options] [file...]
Parse each input file. If successful, print the contents of the file as
reconstructed from the DOM.
Arguments:
file Files to parse, use "-" for stdin (default: "-")
Options:
-b, --base Apply xml:base attributes to entities from included files
-e,--expand <root> Expand external entities, but only within the specified
root directory
-E Expand external entities, but only within the current
working directory
--encoding <enc> Encoding to assume for the input files (choices:
"US-ASCII", "UTF-8", "UTF-16", "ISO-8859-1", default:
Sniff encoding heuristically)
-r,--refs Keep entity references, rather than expanding them
-h, --help display help for command
```

## ewq

```txt
Usage: ewq [options] <xpath> [files...]
Parse each input file, then apply the given xpath to the generated documents.
Arguments:
xpath
files Files to parse, use "-" for stdin (default: "-")
Options:
-b, --base Apply xml:base attributes to entities from included files
-e,--expand <root> Expand external entities, but only within the specified
root directory
-E Expand external entities, but only within the current
working directory
--encoding <enc> Encoding to assume for the input files (choices:
"US-ASCII", "UTF-8", "UTF-16", "ISO-8859-1", default:
Sniff encoding heuristically)
-r,--refs Keep entity references, rather than expanding them
-h, --help display help for command
```
21 changes: 15 additions & 6 deletions cli/package.json
Expand Up @@ -7,20 +7,29 @@
"ewlint": "bin/ewlint.js",
"ewq": "bin/ewq.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"repository": {
"type": "git",
"url": "https://github.com/hildjj/expat-wasm-dom.git",
"directory": "cli"
},
"keywords": [],
"keywords": [
"xml",
"parse",
"dom",
"xpath",
"wasm",
"cli"
],
"author": "Joe Hildebrand <joe-github@cursive.net>",
"license": "MIT",
"engines": {
"node": ">=16"
},
"workspaces": [
".."
],
"dependencies": {
"commander": "10.0.1",
"expat-wasm-dom": "*"
},
"engines": {
"node": ">=16"
}
}
25 changes: 14 additions & 11 deletions lib/dom.js
@@ -1,3 +1,4 @@
/* eslint-disable no-use-before-define */
import {XPath} from './xpath.js'
import util from 'util'

Expand Down Expand Up @@ -191,7 +192,6 @@ export class Node {
cur = cur.parent
}

// eslint-disable-next-line no-use-before-define
if (cur instanceof Document) {
return cur
}
Expand All @@ -208,7 +208,7 @@ export class Node {
* @returns {string} The escaped string
*/
static escape(str, attrib = false) {
const re = attrib ? /[<&"]/g : /[<&]/g
const re = attrib ? /[<&"']/g : /[<&]/g
const ret = str.replace(re, c => {
switch (c) {
case '<': return '&lt;'
Expand Down Expand Up @@ -261,6 +261,17 @@ export class ParentNode extends Node {
* @returns {Node} The added node
*/
add(node) {
if (
(node instanceof Text) &&
(this.children.length > 0) &&
(this.children[this.children.length - 1] instanceof Text)
) {
const prev = this.children[this.children.length - 1]
// @ts-ignore
prev.txt += node.txt
return prev
}

node.parent = this
this.children.push(node)
return node
Expand Down Expand Up @@ -313,7 +324,6 @@ export class ParentNode extends Node {
*/
*descendantElements() {
for (const c of this.children) {
// eslint-disable-next-line no-use-before-define
if (c instanceof Element) {
yield c
yield *c.descendantElements()
Expand All @@ -333,7 +343,6 @@ export class ParentNode extends Node {
*/
*elements(local, ns) {
for (const c of this.children) {
// eslint-disable-next-line no-use-before-define
if ((c instanceof Element) &&
(!ns || (ns === c.name.ns)) &&
(!local || (local === c.name.local))) {
Expand Down Expand Up @@ -384,7 +393,6 @@ export class Document extends ParentNode {
*/
get root() {
return /** @type {Element|null} */ (
// eslint-disable-next-line no-use-before-define
this.children.find(c => c instanceof Element)
)
}
Expand Down Expand Up @@ -443,9 +451,7 @@ export class Element extends ParentNode {
constructor(name, attribs = [], ns = []) {
super()
this.name = (typeof name === 'string') ? {local: name} : name
// eslint-disable-next-line no-use-before-define
this.att = attribs.map(([n, v]) => new Attribute(n, v))
// eslint-disable-next-line no-use-before-define
this.ns = ns.map(([prefix, uri]) => new Namespace(prefix, uri))
}

Expand Down Expand Up @@ -492,7 +498,6 @@ export class Element extends ParentNode {
if (a) {
a.value = value
} else {
// eslint-disable-next-line no-use-before-define
a = new Attribute(name, value)
this.att.push(a)
}
Expand Down Expand Up @@ -550,7 +555,7 @@ export class Element extends ParentNode {
if (newText == null) {
return super.text()
}
// eslint-disable-next-line no-use-before-define

const t = new Text(newText)
t.parent = this
this.children = [t]
Expand Down Expand Up @@ -721,7 +726,6 @@ export class Text extends Node {
* @returns {string} The node, converted to a string
*/
toString(options = TOSTRING_OPTS) {
// eslint-disable-next-line no-use-before-define
if (this.parent instanceof CdataSection) {
// TODO: escape "]]>" ?
// replace ]]> by ]]]><![CDATA[]>
Expand Down Expand Up @@ -1189,7 +1193,6 @@ export class AttlistDecl extends ParentNode {
* @returns {Node} The added node
*/
add(node) {
// eslint-disable-next-line no-use-before-define
if (node instanceof AttributeDecl || !this.parent) {
return super.add(node)
}
Expand Down
11 changes: 10 additions & 1 deletion lib/xpath.js
Expand Up @@ -291,6 +291,9 @@ export class XPath {
*/
// eslint-disable-next-line class-methods-use-this
_textTest(num, context) {
if (typeof context === 'string') {
return [context]
}
if (typeof context.text !== 'function') {
throw new Error('Cannot get text from this node')
}
Expand Down Expand Up @@ -343,7 +346,7 @@ export class XPath {
} else if (Array.isArray(expr)) {
return (this._eval([context], expr).length > 0) ? [context] : []
}
/* istanbul ignore next */

throw new Error(`Unimplemented predicate in "${this.pattern}": "${util.inspect(expr)}"`)
}

Expand Down Expand Up @@ -390,6 +393,12 @@ export class XPath {
return [true]
}
break
case '!=':
case 'ne':
if (eLeft !== eRight) {
return [true]
}
break
default:
throw new Error(`Unimplemented op: "${op}"`)
}
Expand Down

0 comments on commit fe18938

Please sign in to comment.