framework-parsers-maintenance
Create and maintain framework parser and spec packages for markuplint.
Architecture
See FRAMEWORK-PARSERS-ARCHITECTURE.md for the overall design, parser hierarchy, and extension patterns.
For individual package details, see each package's ARCHITECTURE.md and docs/maintenance.md.
Key Concepts
- •Template Engine Parsers extend
HtmlParserand configure onlyignoreTags - •Full Framework Parsers extend
Parserand implementtokenize(),nodeize(),visitAttr(),detectElementType() - •Spec Packages export an
ExtendedSpecobject with global attributes and element overrides
Tasks
create-template-parser
Create a new template engine parser package.
- •Copy an existing template parser (e.g.,
ejs-parser) as a starting point - •Update
package.jsonwith the new package name and description - •Edit
src/parser.ts:- •Rename the class
- •Configure
ignoreTagswith the template language's delimiter patterns - •Each pattern needs
type(descriptive name),start(string or regex),end(string or regex)
- •Write tests in
src/index.spec.tsusingnodeListToDebugMaps - •Build:
yarn build --scope @markuplint/<new-parser> - •Test:
yarn test --scope @markuplint/<new-parser>
create-full-parser
Create a new full framework parser package.
- •Copy an existing full parser (e.g.,
astro-parser) as a starting point - •Install the external parser library as a dependency
- •Implement the parser class extending
Parser:- •
tokenize()— call the external parser - •
nodeize()— map external AST nodes to markuplint nodes - •
visitAttr()— handle framework-specific attribute syntax - •
detectElementType()— define the component naming pattern
- •
- •Configure constructor options:
endTagType,tagNameCaseSensitive, etc. - •Write tests in
src/index.spec.ts - •Build:
yarn build --scope @markuplint/<new-parser> - •Test:
yarn test --scope @markuplint/<new-parser>
create-spec
Create a new framework spec package.
- •Copy an existing spec (e.g.,
react-spec) as a starting point - •Define the
ExtendedSpecobject insrc/index.ts:- •
def['#globalAttrs']['#extends']— global attributes available on all elements - •
specs[]— per-element attribute overrides orpossibleToAddProperties
- •
- •Each attribute definition needs at minimum a
typefield (e.g.,'Any','Boolean','NoEmptyAny') - •Optional fields:
description,condition(CSS selector),caseSensitive - •Build:
yarn build --scope @markuplint/<new-spec> - •Test:
yarn test --scope @markuplint/<new-spec>
add-directive
Add a new directive or special attribute to an existing framework parser.
- •Read the parser's
ARCHITECTURE.mdto understand the current attribute processing - •Read
src/parser.tsand locate thevisitAttr()method - •Add the new directive pattern:
- •Set
isDirective: truefor template directives - •Set
potentialNameif the directive maps to a standard HTML attribute - •Set
isDynamicValue: trueif the value is a script expression - •Set
isDuplicatable: trueif the attribute can appear multiple times
- •Set
- •Build:
yarn build --scope @markuplint/<parser> - •Test:
yarn test --scope @markuplint/<parser>
Rules
- •Template parsers should only configure
ignoreTags-- never overridetokenize()ornodeize(). - •Full parsers should delegate tokenization to external libraries -- never implement framework parsing from scratch.
- •Spec packages should only export an
ExtendedSpecobject -- no parsing logic. - •Use
potentialNamefor attribute mapping -- this tells markuplint which standard HTML attribute the framework attribute corresponds to. - •Test with
nodeListToDebugMaps-- this is the standard assertion pattern across all parsers.