ecmarkdown
Advanced tools
Comparing version 6.0.2 to 7.0.0
@@ -80,4 +80,4 @@ "use strict"; | ||
emitListItem(li) { | ||
let id = li.id === null ? '' : ` id="${li.id}"`; | ||
this.str += `<li${id}>`; | ||
const attrs = li.attrs.map(a => ` ${a.key}=${JSON.stringify(a.value)}`).join(''); | ||
this.str += `<li${attrs}>`; | ||
this.emitFragment(li.contents); | ||
@@ -84,0 +84,0 @@ if (li.sublist !== null) { |
@@ -70,4 +70,5 @@ declare type ActualOmit<T, K extends string> = T extends unknown ? Omit<T, K> : never; | ||
}; | ||
export declare type IdToken = { | ||
name: 'id'; | ||
export declare type AttrToken = { | ||
name: 'attr'; | ||
key: string; | ||
value: string; | ||
@@ -149,3 +150,6 @@ location: LocationRange; | ||
sublist: ListNode | null; | ||
id: string | null; | ||
attrs: { | ||
key: string; | ||
value: string; | ||
}[]; | ||
location: LocationRange; | ||
@@ -157,3 +161,6 @@ }; | ||
sublist: ListNode | null; | ||
id: string | null; | ||
attrs: { | ||
key: string; | ||
value: string; | ||
}[]; | ||
location: LocationRange; | ||
@@ -160,0 +167,0 @@ }; |
@@ -23,3 +23,3 @@ import type { Unlocated, LocationRange, Position, Token, Format, Node, PipeNode, TextNode, CommentNode, TagNode, FragmentNode, OrderedListNode, OrderedListItemNode, UnorderedListItemNode } from './node-types'; | ||
}; | ||
parseList(): (Pick<OrderedListNode, "start" | "contents" | "name" | "indent"> & { | ||
parseList(): (Pick<OrderedListNode, "contents" | "name" | "indent" | "start"> & { | ||
location: LocationRange; | ||
@@ -39,3 +39,3 @@ }) | (Pick<import("./node-types").UnorderedListNode, "contents" | "name" | "indent"> & { | ||
}) | null; | ||
parseFormat(format: Format, opts: ParseFragmentOpts): (TagNode | CommentNode | TextNode)[] | (Pick<PipeNode, "optional" | "contents" | "name" | "nonTerminal" | "params"> & { | ||
parseFormat(format: Format, opts: ParseFragmentOpts): (TagNode | CommentNode | TextNode)[] | (Pick<PipeNode, "contents" | "name" | "nonTerminal" | "params" | "optional"> & { | ||
location: LocationRange; | ||
@@ -42,0 +42,0 @@ })[] | ({ |
@@ -75,3 +75,3 @@ "use strict"; | ||
this._t.next(); | ||
const id = this._t.tryScanId(); | ||
const attrs = this._t.tryScanListItemAttributes(); | ||
const contents = this.parseFragment({ inList: true }); | ||
@@ -88,3 +88,3 @@ const listItemTok = this._t.peek(); | ||
let name = kind === 'ol' ? 'ordered-list-item' : 'unordered-list-item'; | ||
return this.finish({ name, contents, sublist, id: id == null ? null : id.value }); | ||
return this.finish({ name, contents, sublist, attrs }); | ||
} | ||
@@ -91,0 +91,0 @@ parseFragment(opts, closingFormatKind) { |
@@ -1,2 +0,2 @@ | ||
import type { Unlocated, Token, IdToken, Position } from './node-types'; | ||
import type { Unlocated, Token, AttrToken, Position } from './node-types'; | ||
export declare class Tokenizer { | ||
@@ -20,3 +20,3 @@ str: string; | ||
tryScanComment(): string | undefined; | ||
tryScanId(): IdToken | null; | ||
tryScanListItemAttributes(): AttrToken[]; | ||
matchToken(): void; | ||
@@ -29,5 +29,5 @@ getLocation(): Position; | ||
locate(tok: Unlocated<Token>, startPos: Position): asserts tok is Token; | ||
locate(tok: Unlocated<IdToken>, startPos: Position): asserts tok is IdToken; | ||
locate(tok: Unlocated<AttrToken>, startPos: Position): asserts tok is AttrToken; | ||
expect(name: Token['name']): void; | ||
raise(message: string, pos: Position): void; | ||
} |
@@ -5,3 +5,3 @@ "use strict"; | ||
const commentRegexp = /^<!--[\w\W]*?-->/; | ||
const idRegexp = /^\[id="([\w-]+)"] /; | ||
const attrRegexp = /^\[ *[\w-]+ *= *"(?:[^"\\\x00-\x1F]|\\["\\/bfnrt]|\\u[a-fA-F]{4})*" *(?:, *[\w-]+ *= *"(?:[^"\\\x00-\x1F]|\\["\\/bfnrt]|\\u[a-fA-F]{4})*" *)*] /; | ||
const digitRegexp = /\d/; | ||
@@ -113,13 +113,31 @@ const opaqueTags = new Set(['emu-grammar', 'emu-production', 'pre', 'code', 'script', 'style']); | ||
} | ||
// ID tokens are only valid immediately after list tokens, so we let this be called by the parser. | ||
tryScanId() { | ||
const match = this.str.slice(this.pos).match(idRegexp); | ||
// attribute tokens are only valid immediately after list tokens, so we let this be called by the parser. | ||
tryScanListItemAttributes() { | ||
const match = this.str.slice(this.pos).match(attrRegexp); | ||
if (!match) { | ||
return null; | ||
return []; | ||
} | ||
const start = this.getLocation(); | ||
this.pos += match[0].length; | ||
let token = { name: 'id', value: match[1] }; | ||
this.locate(token, start); | ||
return token; | ||
const parts = match[0].matchAll(/([\w-]+) *= *("(?:[^"\\\x00-\x1F]|\\["\\/bfnrt]|\\u[a-fA-F]{4})*")/g); | ||
const tokens = []; | ||
let offset = 0; | ||
for (const { 0: part, 1: key, 2: value, index } of parts) { | ||
this.pos += index - offset; | ||
// updating column manually is kind of cheating, but whatever | ||
// it only works because we know attributes can't contain linebreaks | ||
// doing this allows us to avoid having tokens for the `,` and the ` ` between attributes | ||
this.column += index - offset; | ||
const tokStart = this.getLocation(); | ||
const tok = { | ||
name: 'attr', | ||
key, | ||
value: JSON.parse(value), | ||
}; | ||
this.pos += part.length; | ||
this.locate(tok, tokStart); | ||
offset = index + part.length; | ||
tokens.push(tok); | ||
} | ||
this.pos += match[0].length - offset; | ||
this.column += match[0].length - offset; | ||
return tokens; | ||
} | ||
@@ -126,0 +144,0 @@ // Attempts to match any of the tokens at the given index of str |
{ | ||
"name": "ecmarkdown", | ||
"version": "6.0.2", | ||
"version": "7.0.0", | ||
"description": "A compiler for \"Ecmarkdown\" algorithm shorthand into HTML.", | ||
@@ -5,0 +5,0 @@ "main": "dist/ecmarkdown.js", |
@@ -58,3 +58,3 @@ # Ecmarkdown | ||
List items can be given a id by putting `[id="something"]` at the start of the item, as in `1. [id="something"]`. This will generate a `<li>` element with an id property of `something`. This is used by Ecmarkup for referencing specific steps of Ecmarkdown algorithms. | ||
List items can be given arbitrary attributes by putting `[attr="something"]` at the start of the item, as in `1. [attr="something"]`. This will generate `<li attr="something">`. Multiple attributes are also supported as comma-seperated lists, as in `[attr1="a", attr2="b"]`. | ||
@@ -61,0 +61,0 @@ #### HTML Blocks |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
51366
1229
0