Skip to content

Commit

Permalink
feat: implement ways to interact with collect via transform API
Browse files Browse the repository at this point in the history
  • Loading branch information
brotheroftux committed Dec 11, 2024
1 parent 4ac094b commit e10386a
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 8 deletions.
44 changes: 38 additions & 6 deletions src/transform/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type {EnvType, OptionsType, OutputType} from './typings';
import type {EnvType, OptionsType, OutputType, RootCollectorOptions} from './typings';

import {bold} from 'chalk';

import {log} from './log';
import liquidSnippet from './liquid';
import liquidDocument from './liquid';
import initMarkdownIt from './md';

function applyLiquid(input: string, options: OptionsType) {
Expand All @@ -17,7 +17,7 @@ function applyLiquid(input: string, options: OptionsType) {

return disableLiquid || isLiquided
? input
: liquidSnippet(input, vars, path, {conditionsInCode});
: liquidDocument(input, vars, path, {conditionsInCode});
}

function handleError(error: unknown, path?: string): never {
Expand All @@ -33,8 +33,14 @@ function emitResult(html: string, env: EnvType): OutputType {
};
}

type TransformFunction = {
(originInput: string, options?: OptionsType): OutputType;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
collect: (input: string, options: RootCollectorOptions<any>) => string;
};

// eslint-disable-next-line consistent-return
function transform(originInput: string, options: OptionsType = {}) {
const transform: TransformFunction = (originInput: string, options: OptionsType = {}) => {
const input = applyLiquid(originInput, options);
const {parse, compile, env} = initMarkdownIt(options);

Expand All @@ -43,11 +49,37 @@ function transform(originInput: string, options: OptionsType = {}) {
} catch (error) {
handleError(error, options.path);
}
}
};

transform.collect = (
input: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
{mdItInitOptions, pluginCollectOptions}: RootCollectorOptions<any>,
) => {
const maybeLiquidedInput = applyLiquid(input, mdItInitOptions);
const {parse} = initMarkdownIt(mdItInitOptions);

const plugins = mdItInitOptions.plugins ?? [];

try {
const tokenStream = parse(maybeLiquidedInput);

return plugins.reduce((collected, plugin) => {
const collectOutput = plugin.collect?.(collected, {
...pluginCollectOptions,
tokenStream,
});

return collectOutput ?? collected;
}, input);
} catch (error) {
handleError(error, mdItInitOptions.path);
}
};

export = transform;

// eslint-disable-next-line @typescript-eslint/no-namespace, no-redeclare -- backward compatibility
// eslint-disable-next-line @typescript-eslint/no-namespace, @typescript-eslint/no-redeclare -- backward compatibility
namespace transform {
export type Options = OptionsType;
export type Output = OutputType;
Expand Down
25 changes: 23 additions & 2 deletions src/transform/typings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {LanguageFn} from 'highlight.js';
import DefaultMarkdownIt from 'markdown-it';
import DefaultMarkdownIt, {Token} from 'markdown-it';
import DefaultStateCore from 'markdown-it/lib/rules_core/state_core';

import {SanitizeOptions} from './sanitize';
Expand Down Expand Up @@ -47,7 +47,7 @@ export interface OptionsType {
sanitizeOptions?: SanitizeOptions;
needFlatListHeadings?: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
plugins?: MarkdownItPluginCb<any>[];
plugins?: ExtendedPluginWithCollect<any, any>[];
preprocessors?: MarkdownItPreprocessorCb[]; // Preprocessors should modify the input before passing it to MD
highlightLangs?: HighlightLangMap;
disableRules?: string[];
Expand Down Expand Up @@ -96,6 +96,27 @@ export type MarkdownItPluginCb<T extends {} = {}> = {
(md: MarkdownIt, opts: T & MarkdownItPluginOpts): void;
};

export type IntrinsicCollectOptions = {
tokenStream: Token[];
};

export type ExtendedPluginWithCollect<
PluginRegularOptions extends {} = {},
PluginCollectOptions = {},
> = MarkdownItPluginCb<PluginRegularOptions> & {
collect?: (
input: string,
options: PluginCollectOptions & IntrinsicCollectOptions,
) => string | void;
};

export type RootCollectorOptions<PluginCollectOptions> = {
mdItInitOptions: OptionsType;
pluginCollectOptions: PluginCollectOptions;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
pluginsToCollect: ExtendedPluginWithCollect<any, any>[];
};

export type MarkdownItPreprocessorCb<T extends unknown = {}> = {
(input: string, opts: T & Partial<MarkdownItPluginOpts>, md?: MarkdownIt): string;
};
Expand Down

0 comments on commit e10386a

Please sign in to comment.