Skip to content

Commit

Permalink
type: define precise type for Event.annot
Browse files Browse the repository at this point in the history
This enables API users to identify the events returned
by `parseEvents` in a type-safe manner.
  • Loading branch information
not-my-profile committed Oct 20, 2024
1 parent fbcf18b commit ac6ba5b
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 32 deletions.
15 changes: 14 additions & 1 deletion src/attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,19 @@ handlers[State.SCANNING_QUOTED_VALUE_CONTINUATION] = function(parser : Attribute
}
}

export type AttrAnnot =
| "attr_class_marker"
| "attr_equal_marker"
| "attr_id_marker"
| "attr_quote_marker"
| "attr_space"
| "class"
| "comment"
| "id"
| "key"
| "value"
;

class AttributeParser {
subject : string;
state : State;
Expand All @@ -261,7 +274,7 @@ class AttributeParser {
this.matches = []
}

addEvent(startpos : number, endpos : number, annot : string) {
addEvent(startpos : number, endpos : number, annot : AttrAnnot) {
this.matches.push({ startpos: startpos, endpos: endpos, annot: annot });
}

Expand Down
63 changes: 47 additions & 16 deletions src/block.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Event } from "./event";
import { Annot, Event } from "./event";
import { Options, Warning } from "./options";
import { AttributeParser } from "./attributes";
import { AttrAnnot, AttributeParser } from "./attributes";
import { pattern, find } from "./find";
import { InlineParser } from "./inline";
import { InlineAnnot, InlineParser } from "./inline";

// Return array of list styles that match a marker.
// In ambiguous cases we return multiple values.
Expand Down Expand Up @@ -59,7 +59,7 @@ const pattListMarker = pattern("(:?[-*+:]|\\([0-9]+\\)|[0-9]+[.)]|[ivxlcdmIVXLCD
const pattTaskListMarker = pattern("[*+-] \\[[Xx ]\\][ \\t\\r\\n]");

type EventIterator = {
next: () => { value: Event, done: boolean };
next: () => { done: false, value: Event } | { done: true, value: Omit<Event, "annot"> };
}

enum ContentType {
Expand Down Expand Up @@ -106,6 +106,45 @@ class Container {
}
}

export type BlockAnnot =
| `+${BlockType}`
| `-${BlockType}`
| `+list|${string}`
| `+list_item|${string}`
| "-list"
| "-list_item"
| "blankline"
| "checkbox_checked"
| "checkbox_unchecked"
| "class"
| "code_language"
| "note_label"
| "raw_format"
| "reference_key"
| "reference_value"
| "separator_center"
| "separator_default"
| "separator_left"
| "separator_right"
| "str"
| "thematic_break"
;

type BlockType =
| "block_attributes"
| "block_quote"
| "caption"
| "cell"
| "code_block"
| "div"
| "footnote"
| "heading"
| "para"
| "reference_definition"
| "row"
| "table"
;

class EventParser {
options: Options;
warn: (warning : Warning) => void;
Expand Down Expand Up @@ -422,11 +461,7 @@ class EventParser {
const data = { styles: styles, indent: this.indent };
// adding container will close others
this.addContainer(new Container(spec, data));
let annot = "+list";
for (const style of styles) {
annot = annot + "|" + style;
}
this.addMatch(sp, ep - 1, annot);
this.addMatch(sp, ep - 1, `+list|${styles.join("|")}`);
return true;
},
close: () => {
Expand Down Expand Up @@ -467,11 +502,7 @@ class EventParser {
const data = { styles: styles, indent: this.indent };
// adding container will close others
this.addContainer(new Container(spec, data));
let annot = "+list_item";
for (const style of styles) {
annot = annot + "|" + style;
}
this.addMatch(sp, ep - 1, annot);
this.addMatch(sp, ep - 1, `+list_item|${styles.join("|")}`);
this.pos = ep;

if (checkbox) {
Expand Down Expand Up @@ -752,7 +783,7 @@ class EventParser {
}
}

addMatch(startpos: number, endpos: number, annot: string): void {
addMatch(startpos: number, endpos: number, annot: Annot): void {
this.matches.push({
startpos: Math.min(startpos, this.maxoffset),
endpos: Math.min(endpos, this.maxoffset),
Expand Down Expand Up @@ -884,7 +915,7 @@ class EventParser {
const m = find(this.subject, pattRowSep, p);
if (m !== null) {
const [left, right, trailing] = m.captures;
let st = "separator_default";
let st: BlockAnnot = "separator_default";
if (left.length > 0 && right.length > 0) {
st = "separator_center";
} else if (right.length > 0) {
Expand Down
8 changes: 7 additions & 1 deletion src/event.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { AttrAnnot } from "./attributes";
import { BlockAnnot } from "./block";
import { InlineAnnot } from "./inline";

export type Annot = BlockAnnot | InlineAnnot | AttrAnnot;

interface Event {
startpos : number;
endpos : number;
annot : string;
annot : Annot;

}

Expand Down
75 changes: 62 additions & 13 deletions src/inline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ const alwaysTrue = function() { return true; };

const betweenMatched = function(
c: string,
annotation: string,
defaultmatchFirst: string,
defaultmatchAlt: string | null,
annotation: InlineType,
defaultmatchFirst: InlineAnnot,
defaultmatchAlt: InlineAnnot | null,
opentest: ((self: InlineParser, pos: number) => boolean)) {

let defaultmatch = defaultmatchFirst;
Expand Down Expand Up @@ -149,9 +149,9 @@ const betweenMatched = function(
const opener = openers[openers.length - 1];
if (opener.endpos !== pos - 1) { // exclude empty emph
self.clearOpeners(opener.startpos, pos);
self.addMatch(opener.startpos, opener.endpos, "+" + annotation,
self.addMatch(opener.startpos, opener.endpos, `+${annotation}`,
opener.matchIndex);
self.addMatch(pos, endcloser, "-" + annotation);
self.addMatch(pos, endcloser, `-${annotation}`);
return endcloser + 1;
}
}
Expand Down Expand Up @@ -526,14 +526,64 @@ const matchers = {
}
};

export type InlineAnnot =
| `+${InlineType}`
| `-${InlineType}`
| "ellipses"
| "em_dash"
| "en_dash"
| "escape"
| "footnote_reference"
| "hard_break"
| "image_marker"
| "left_double_quote"
| "left_single_quote"
| "non_breaking_space"
| "open_marker"
| "raw_format"
| "right_double_quote"
| "right_single_quote"
| "soft_break"
| "str"
| "symb"
;

type InlineType =
| VerbatimType
| "attributes"
| "delete"
| "destination"
| "display_math"
| "double_quoted"
| "email"
| "emph"
| "imagetext"
| "insert"
| "linktext"
| "mark"
| "reference"
| "single_quoted"
| "span"
| "strong"
| "subscript"
| "superscript"
| "url"
;

type VerbatimType =
| "display_math"
| "inline_math"
| "verbatim"
;

class InlineParser {
options: Options;
warn: (warning : Warning) => void;
subject: string;
matches: Event[];
openers: OpenerMap; // map from opener type to Opener[] in reverse order
verbatim: number; // parsing a verbatim span to be ended by N backticks
verbatimType: string; // math or regular
verbatimType?: VerbatimType; // math or regular
destination: boolean; // parsing link destination?
firstpos: number; // position of first slice
lastpos: number; // position of last slice
Expand All @@ -551,7 +601,6 @@ class InlineParser {
this.matches = []; // array of matches
this.openers = {};
this.verbatim = 0;
this.verbatimType = "";
this.destination = false;
this.firstpos = -1;
this.lastpos = 0;
Expand All @@ -563,7 +612,7 @@ class InlineParser {
}

addMatch(startpos: number, endpos: number,
annot: string, matchIndex?: number): void {
annot: InlineAnnot, matchIndex?: number): void {
const match = { startpos: startpos, endpos: endpos, annot: annot };
if (matchIndex !== undefined) {
// insert into the proper place, replacing placeholder
Expand Down Expand Up @@ -629,7 +678,7 @@ class InlineParser {
this.matches.push({
startpos: last.endpos,
endpos: last.endpos,
annot: "-" + this.verbatimType
annot: `-${this.verbatimType!}`
});
}
return this.matches;
Expand All @@ -638,7 +687,7 @@ class InlineParser {
addOpener(name: string,
startpos: number,
endpos: number,
defaultAnnot: string) : void {
defaultAnnot: InlineAnnot) : void {
if (!this.openers[name]) {
this.openers[name] = [];
}
Expand Down Expand Up @@ -727,7 +776,7 @@ class InlineParser {
const attrMatches = this.attributeParser.matches;
// add attribute matches
for (const match of attrMatches) {
this.addMatch(match.startpos, match.endpos, match.annot);
this.matches.push(match);
}
this.addMatch(ep, ep, "-attributes");
// restore state to prior to adding attribute parser
Expand Down Expand Up @@ -787,11 +836,11 @@ class InlineParser {
// check for raw attribute
const m2 = find(subject, pattRawAttribute, endchar + 1, endpos);
if (m2 && this.verbatimType === "verbatim") { // raw
this.addMatch(pos, endchar, "-" + this.verbatimType);
this.addMatch(pos, endchar, `-${this.verbatimType}`);
this.addMatch(m2.startpos, m2.endpos, "raw_format");
pos = m2.endpos + 1;
} else {
this.addMatch(pos, endchar, "-" + this.verbatimType);
this.addMatch(pos, endchar, `-${this.verbatimType!}`);
pos = endchar + 1;
}
this.verbatim = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,7 @@ const parse = function(input: string, options: ParseOptions = {}): Doc {
ep = getSourceLoc(event.endpos);
pos = { start: sp, end: ep };
}
let annot = event.annot;
let annot: string = event.annot;
let suffixes: string[] = [];
if (event.annot.includes("|")) {
const parts = event.annot.split("|");
Expand Down

0 comments on commit ac6ba5b

Please sign in to comment.