diff --git a/lib/parser.js b/lib/parser.js index f775c56..88599c7 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -1,119 +1,103 @@ -const Parsimmon = require('parsimmon'); +const bnb = require('bread-n-butter'); function makeNode(type) { return function makeNodeWrapper(parser) { - return Parsimmon.seqMap( - Parsimmon.index, - parser, - Parsimmon.index, - function makeNode_(start, value, end) { + return bnb + .all(bnb.location, parser, bnb.location) + .map(function makeNode_([start, value, end]) { return { type, - start: start.offset, - end: end.offset, + start: start.index, + end: end.index, + // @ts-ignore ...value, }; - } - ); + }); }; } -const Lang = Parsimmon.createLanguage({ - Program: (r) => - Parsimmon.alt( - r.Superscript, - r.Subscript, - r.UnaryMacro, - r.NullaryMacro, - r.Illegal, - r.PlainText - ) - .many() - .map((nodes) => { - return { - body: nodes, - }; - }) - .thru(makeNode('Program')), +const Spaces = bnb.match(/\s*/); - Superscript: () => - Parsimmon.seq( - Parsimmon.regexp(/\^\s*/), - Parsimmon.alt( - Parsimmon.regexp(/{[a-zA-Z0-9+-]+}/), - Parsimmon.regexp(/[a-zA-Z0-9+-]/) - ) - ) - .map(([, b]) => ({ - content: b, - })) - .thru(makeNode('Superscript')), +const Superscript = bnb + .all( + bnb.match(/\^\s*/), + bnb.choice(bnb.match(/{[a-zA-Z0-9+-]+}/), bnb.match(/[a-zA-Z0-9+-]/)) + ) + .map(([, b]) => ({ + content: b, + })) + .thru(makeNode('Superscript')); - Subscript: () => - Parsimmon.seq( - Parsimmon.regexp(/_\s*/), - Parsimmon.alt( - Parsimmon.regexp(/{[a-zA-Z0-9+-]+}/), - Parsimmon.regexp(/[a-zA-Z0-9+-]/) - ) - ) - .map(([_, b]) => { - return { - content: b, - }; - }) - .thru(makeNode('Subscript')), +const Subscript = bnb + .all( + bnb.match(/_\s*/), + bnb.choice(bnb.match(/{[a-zA-Z0-9+-]+}/), bnb.match(/[a-zA-Z0-9+-]/)) + ) + .map(([_, b]) => { + return { + content: b, + }; + }) + .thru(makeNode('Subscript')); - UnaryMacro: (r) => - Parsimmon.seq( - Parsimmon.alt( - Parsimmon.regexp(/\\mathbb(?![a-zA-Z])/), - Parsimmon.regexp(/\\mathfrak(?![a-zA-Z])/), - Parsimmon.regexp(/\\mathcal(?![a-zA-Z])/), - Parsimmon.regexp(/\\not(?![a-zA-Z])/) - ), - r._, - Parsimmon.alt( - r.CurlyGroup, - r.NullaryMacro, - Parsimmon.regexp(/[a-zA-Z0-9]/) - .map((x) => ({value: x})) - .thru(makeNode('PlainText')) - ) - ) - .map(([a, _, c]) => ({ - macro: a, - argument: c, - })) - .thru(makeNode('UnaryMacro')), +const NullaryMacro = bnb + .choice(bnb.match(/\\[a-zA-Z]+/), bnb.match(/\\\|/)) + .map((x) => { + return { + macro: x, + }; + }) + .thru(makeNode('NullaryMacro')); - NullaryMacro: () => - Parsimmon.alt(Parsimmon.regexp(/\\[a-zA-Z]+/), Parsimmon.regexp(/\\\|/)) - .map((x) => { - return { - macro: x, - }; - }) - .thru(makeNode('NullaryMacro')), +const CurlyGroup = bnb + .match(/\{.*?\}/) + .map((x) => ({value: x})) + .thru(makeNode('CurlyGroup')); - Illegal: () => - Parsimmon.regexp(/[\^_\\]/) - .map((r) => ({ - value: r, - })) - .thru(makeNode('PlainText')), +const UnaryMacro = bnb + .all( + bnb.choice( + bnb.match(/\\mathbb(?![a-zA-Z])/), + bnb.match(/\\mathfrak(?![a-zA-Z])/), + bnb.match(/\\mathcal(?![a-zA-Z])/), + bnb.match(/\\not(?![a-zA-Z])/) + ), + Spaces, + bnb.choice( + CurlyGroup, + NullaryMacro, + bnb + .match(/[a-zA-Z0-9]/) + .map((x) => ({value: x})) + .thru(makeNode('PlainText')) + ) + ) + .map(([a, _, c]) => ({ + macro: a, + argument: c, + })) + .thru(makeNode('UnaryMacro')); - PlainText: () => - Parsimmon.regexp(/[^_^\\]+/) - .map((x) => ({value: x})) - .thru(makeNode('PlainText')), +const Illegal = bnb + .match(/[\^_\\]/) + .map((r) => ({ + value: r, + })) + .thru(makeNode('PlainText')); - CurlyGroup: () => - Parsimmon.regexp(/\{.*?\}/) - .map((x) => ({value: x})) - .thru(makeNode('CurlyGroup')), +const PlainText = bnb + .match(/[^_^\\]+/) + .map((x) => ({value: x})) + .thru(makeNode('PlainText')); - _: () => Parsimmon.regexp(/\s*/), -}); +const Program = bnb + .choice(Superscript, Subscript, UnaryMacro, NullaryMacro, Illegal, PlainText) + .repeat() + .map((nodes) => { + return { + body: nodes, + }; + }) + .thru(makeNode('Program')); -module.exports = Lang.Program; +module.exports = Program; diff --git a/package-lock.json b/package-lock.json index 0fa5090..a46e9bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,7 @@ "name": "tex-to-unicode", "license": "MIT", "dependencies": { - "parsimmon": "^1.12.0" + "bread-n-butter": "^0.6.0" }, "devDependencies": { "@types/chrome": "^0.0.176", @@ -1783,6 +1783,11 @@ "node": ">=8" } }, + "node_modules/bread-n-butter": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/bread-n-butter/-/bread-n-butter-0.6.0.tgz", + "integrity": "sha512-ATCbBoEdO7LPmFPCfO1dz8jgFEsOIlMx4hDPd4NtX42gJXNC7er8vK45jHlUmC1Ok/1I+VuZ6VZNbU+WipxR6Q==" + }, "node_modules/browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -4470,11 +4475,6 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "node_modules/parsimmon": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.18.1.tgz", - "integrity": "sha512-u7p959wLfGAhJpSDJVYXoyMCXWYwHia78HhRBWqk7AIbxdmlrfdp5wX0l3xv/iTSH5HvhN9K7o26hwwpgS5Nmw==" - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -7276,6 +7276,11 @@ "fill-range": "^7.0.1" } }, + "bread-n-butter": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/bread-n-butter/-/bread-n-butter-0.6.0.tgz", + "integrity": "sha512-ATCbBoEdO7LPmFPCfO1dz8jgFEsOIlMx4hDPd4NtX42gJXNC7er8vK45jHlUmC1Ok/1I+VuZ6VZNbU+WipxR6Q==" + }, "browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -9337,11 +9342,6 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "parsimmon": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.18.1.tgz", - "integrity": "sha512-u7p959wLfGAhJpSDJVYXoyMCXWYwHia78HhRBWqk7AIbxdmlrfdp5wX0l3xv/iTSH5HvhN9K7o26hwwpgS5Nmw==" - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", diff --git a/package.json b/package.json index 740f755..c8c0b71 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "ci": "npm run prettier && npm run lint && npm run tsc && npm run test" }, "dependencies": { - "parsimmon": "^1.12.0" + "bread-n-butter": "^0.6.0" }, "devDependencies": { "@types/chrome": "^0.0.176", diff --git a/test/index.spec.js b/test/index.spec.js index 01e421c..9b0bc7a 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -101,7 +101,7 @@ describe('convertText', () => { describe('Parser', () => { test('Should successfully parse \\\\^^__', () => { - expect(parser.parse('\\\\^^__').status).toEqual(true); + expect(parser.parse('\\\\^^__').type).toEqual('ParseOK'); }); });