98 lines
2.8 KiB
TypeScript
98 lines
2.8 KiB
TypeScript
|
import { Anchor, Href, BoolHash, AltText } from './Model';
|
||
|
|
||
|
export class Util {
|
||
|
private static regexLib: { [name: string]: RegExp } = {
|
||
|
anchors: /(\[((?:[^\[\]]+|\[(?:[^\[\]]+|\[(?:[^\[\]]+|\[(?:[^\[\]]+|\[(?:[^\[\]]+|\[(?:[^\[\]]+|\[\])*\])*\])*\])*\])*\])*)\]\([ ]*((?:[^()\s]+|\((?:[^()\s]+|\((?:[^()\s]+|\((?:[^()\s]+|\((?:[^()\s]+|\((?:[^()\s]+|\(\))*\))*\))*\))*\))*\))*)[ ]*((['"])(.*?)\5[ ]*)?\))/gm,
|
||
|
|
||
|
href: /^(?:\/([a-zA-Z](?:-?[a-zA-Z0-9])*))?(?:\?((?:!?[a-zA-Z](?:-?[a-zA-Z0-9])*)(?:&!?[a-zA-Z](?:-?[a-zA-Z0-9])*)*)?)?(?:#((?:[a-zA-Z](?:-?[a-zA-Z0-9])*)(?:\+[a-zA-Z](?:-?[a-zA-Z0-9])*)*))?$/,
|
||
|
|
||
|
trim: /^\s+|\s+$/g,
|
||
|
|
||
|
altText: /^((?:[^|\\]|\\.)*)(?:\|((?:[^|\\]|\\.)+))?$/,
|
||
|
|
||
|
escapeChar: /\\(?=[^\\])/g,
|
||
|
|
||
|
emptyListItem: /^[ ]*-\s*([\r\n]+|$)/gm,
|
||
|
};
|
||
|
|
||
|
private static matchToAnchor(match: RegExpExecArray): Anchor {
|
||
|
const result: Anchor = {
|
||
|
anchor: match[1],
|
||
|
text: match[2],
|
||
|
href: match[3],
|
||
|
title: match[6],
|
||
|
};
|
||
|
if(result.href.indexOf('"') === 0) {
|
||
|
result.title = result.href.substring(1, result.href.length - 1);
|
||
|
result.href = '';
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static matchAnchor(text: string): Anchor | undefined {
|
||
|
const match = this.regexLib.anchors.exec(text);
|
||
|
if(match) return this.matchToAnchor(match);
|
||
|
}
|
||
|
|
||
|
public static matchAnchors(text: string): Anchor[] {
|
||
|
let match: RegExpExecArray | null;
|
||
|
const anchors: Anchor[] = [];
|
||
|
while(match = this.regexLib.anchors.exec(text)) {
|
||
|
anchors.push(this.matchToAnchor(match));
|
||
|
}
|
||
|
return anchors;
|
||
|
}
|
||
|
|
||
|
public static matchHref(text: string): Href | undefined {
|
||
|
const match = this.regexLib.href.exec(text);
|
||
|
if(match) {
|
||
|
return {
|
||
|
target: match[1],
|
||
|
conditions: match[2],
|
||
|
toggles: match[3],
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static trimText(text: string): string {
|
||
|
return text.replace(this.regexLib.trim, '');
|
||
|
}
|
||
|
|
||
|
public static normalize(text: string): string {
|
||
|
return text.toLowerCase().replace(/^\W+|\W+$/g, '').replace(/\W+/g, '-');
|
||
|
}
|
||
|
|
||
|
public static toBoolHash(names: string[]): BoolHash | undefined {
|
||
|
if(names) {
|
||
|
const hash: BoolHash = {};
|
||
|
for(let name of names) {
|
||
|
if(name.indexOf('!') === 0) {
|
||
|
hash[name.substring(1, name.length)] = false;
|
||
|
} else {
|
||
|
hash[name] = true;
|
||
|
}
|
||
|
}
|
||
|
return hash;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static conditionsMet(state: BoolHash, conditions: BoolHash): boolean {
|
||
|
for(let [cond, val] of Object.entries(conditions)) {
|
||
|
if((val && !state[cond]) || (!val && state[cond])) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public static splitAltText(text: string): AltText | undefined {
|
||
|
const match = this.regexLib.altText.exec(text);
|
||
|
if(match) {
|
||
|
return {
|
||
|
passed: match[0],
|
||
|
failed: match[1],
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
}
|