Browse Source

Migrate to TS (pass 3, Ruler)

pull/1197/head
Vitaly Puzrin 3 months ago
parent
commit
1f4eb333c0
  1. 8
      src/parser_block.ts
  2. 7
      src/parser_core.ts
  3. 14
      src/parser_inline.ts
  4. 35
      src/ruler.ts
  5. 6
      src/rules_block/html_block.ts

8
src/parser_block.ts

@ -24,7 +24,11 @@ import r_paragraph from './rules_block/paragraph.ts'
type MarkdownIt = InstanceType<typeof MarkdownItConstructor>
const _rules = [
const _rules: Array<[
name: string,
rule: (state: StateBlock, startLine: number, endLine: number, silent: boolean) => boolean,
alt?: string[]
]> = [
// First 2 params - rule name & source. Secondary array - list of rules,
// which can be terminated by this one.
['table', r_table, ['paragraph', 'reference']],
@ -49,7 +53,7 @@ class ParserBlock {
*
* [[Ruler]] instance. Keep configuration of block rules.
**/
ruler = new Ruler()
ruler = new Ruler<[StateBlock, number, number, boolean], boolean>()
State = StateBlock

7
src/parser_core.ts

@ -16,7 +16,10 @@ import r_replacements from './rules_core/replacements.ts'
import r_smartquotes from './rules_core/smartquotes.ts'
import r_text_join from './rules_core/text_join.ts'
const _rules = [
const _rules: Array<[
name: string,
rule: (state: StateCore) => void
]> = [
['normalize', r_normalize],
['block', r_block],
['inline', r_inline],
@ -37,7 +40,7 @@ class ParserCore {
*
* [[Ruler]] instance. Keep configuration of core rules.
**/
ruler = new Ruler()
ruler = new Ruler<[StateCore], void>()
State = StateCore

14
src/parser_inline.ts

@ -30,7 +30,10 @@ type MarkdownIt = InstanceType<typeof MarkdownItConstructor>
// Parser rules
const _rules = [
const _rules: Array<[
name: string,
rule: (state: StateInline, silent: boolean) => boolean
]> = [
['text', r_text],
['linkify', r_linkify],
['newline', r_newline],
@ -50,7 +53,10 @@ const _rules = [
//
// Don't use this for anything except pairs (plugins working with `balance_pairs`).
//
const _rules2 = [
const _rules2: Array<[
name: string,
rule: (state: StateInline) => void
]> = [
['balance_pairs', r_balance_pairs],
['strikethrough', r_strikethrough.postProcess],
['emphasis', r_emphasis.postProcess],
@ -68,7 +74,7 @@ class ParserInline {
*
* [[Ruler]] instance. Keep configuration of inline rules.
**/
ruler = new Ruler()
ruler = new Ruler<[StateInline, boolean], boolean>()
/**
* ParserInline#ruler2 -> Ruler
@ -76,7 +82,7 @@ class ParserInline {
* [[Ruler]] instance. Second ruler used for post-processing
* (e.g. in emphasis-like rules).
**/
ruler2 = new Ruler()
ruler2 = new Ruler<[StateInline], void>()
State = StateInline

35
src/ruler.ts

@ -19,7 +19,9 @@
/**
* new Ruler()
**/
class Ruler {
type RuleOptions = { alt?: string[] }
class Ruler<Args extends unknown[], Result> {
// List of added rules. Each element is:
//
// {
@ -29,20 +31,25 @@ class Ruler {
// alt: [ name2, name3 ]
// }
//
__rules__ = []
__rules__: Array<{
name: string
enabled: boolean
fn: (...args: Args) => Result
alt: string[]
}> = []
// Cached rule chains.
//
// First level - chain name, '' for default.
// Second level - diginal anchor for fast filtering by charcodes.
//
__cache__ = null
__cache__: Record<string, Array<(...args: Args) => Result>> | null = null
// Helper methods, should not be used directly
// Find rule index by name
//
__find__ (name) {
__find__ (name: string): number {
for (let i = 0; i < this.__rules__.length; i++) {
if (this.__rules__[i].name === name) {
return i
@ -53,8 +60,8 @@ class Ruler {
// Build rules lookup cache
//
__compile__ () {
const chains = new Set()
__compile__ (): void {
const chains = new Set<string>()
// collect unique names
this.__rules__.forEach(rule => {
@ -109,7 +116,7 @@ class Ruler {
* });
* ```
**/
at (name, fn, options = {}) {
at (name: string, fn: (...args: Args) => Result, options: RuleOptions = {}): void {
const index = this.__find__(name)
if (index === -1) { throw new Error('Parser rule not found: ' + name) }
@ -143,7 +150,7 @@ class Ruler {
* });
* ```
**/
before (beforeName, ruleName, fn, options = {}) {
before (beforeName: string, ruleName: string, fn: (...args: Args) => Result, options: RuleOptions = {}): void {
const index = this.__find__(beforeName)
if (index === -1) { throw new Error('Parser rule not found: ' + beforeName) }
@ -182,7 +189,7 @@ class Ruler {
* });
* ```
**/
after (afterName, ruleName, fn, options = {}) {
after (afterName: string, ruleName: string, fn: (...args: Args) => Result, options: RuleOptions = {}): void {
const index = this.__find__(afterName)
if (index === -1) { throw new Error('Parser rule not found: ' + afterName) }
@ -220,7 +227,7 @@ class Ruler {
* });
* ```
**/
push (ruleName, fn, options = {}) {
push (ruleName: string, fn: (...args: Args) => Result, options: RuleOptions = {}): void {
this.__rules__.push({
name: ruleName,
enabled: true,
@ -243,7 +250,7 @@ class Ruler {
*
* See also [[Ruler.disable]], [[Ruler.enableOnly]].
**/
enable (list, ignoreInvalid = false) {
enable (list: string | string[], ignoreInvalid = false): string[] {
if (!Array.isArray(list)) { list = [list] }
const result = []
@ -274,7 +281,7 @@ class Ruler {
*
* See also [[Ruler.disable]], [[Ruler.enable]].
**/
enableOnly (list, ignoreInvalid = false) {
enableOnly (list: string | string[], ignoreInvalid = false): void {
if (!Array.isArray(list)) { list = [list] }
this.__rules__.forEach(rule => { rule.enabled = false })
@ -294,7 +301,7 @@ class Ruler {
*
* See also [[Ruler.enable]], [[Ruler.enableOnly]].
**/
disable (list, ignoreInvalid = false) {
disable (list: string | string[], ignoreInvalid = false): string[] {
if (!Array.isArray(list)) { list = [list] }
const result = []
@ -324,7 +331,7 @@ class Ruler {
* Default chain name is `''` (empty string). It can't be skipped. That's
* done intentionally, to keep signature monomorphic for high speed.
**/
getRules (chainName) {
getRules (chainName: string): Array<(...args: Args) => Result> {
if (!this.__cache__) this.__compile__()
// Chain can be empty, if rules disabled. But we still have to return Array.

6
src/rules_block/html_block.ts

@ -6,7 +6,11 @@ import { HTML_OPEN_CLOSE_TAG_RE } from '../common/html_re.ts'
// An array of opening and corresponding closing sequences for html tags,
// last argument defines whether it can terminate a paragraph or not
//
const HTML_SEQUENCES = [
const HTML_SEQUENCES: Array<[
open: RegExp,
close: RegExp,
canTerminateParagraph: boolean
]> = [
[/^<(script|pre|style|textarea)(?=(\s|>|$))/i, /<\/(script|pre|style|textarea)>/i, true],
[/^<!--/, /-->/, true],
[/^<\?/, /\?>/, true],

Loading…
Cancel
Save