import { Command } from 'prosemirror-state';
import { Decoration } from 'prosemirror-view';
import { default as default_2 } from 'katex';
import { EditorView } from 'prosemirror-view';
import { Fragment } from 'prosemirror-model';
import { InputRule } from 'prosemirror-inputrules';
import { Mark } from 'prosemirror-model';
import { MarkSpec } from 'prosemirror-model';
import { MarkType } from 'prosemirror-model';
import { Node as Node_2 } from 'prosemirror-model';
import { NodeSpec } from 'prosemirror-model';
import { NodeType } from 'prosemirror-model';
import { NodeView } from 'prosemirror-view';
import { NodeViewConstructor } from 'prosemirror-view';
import { Plugin as Plugin_2 } from 'prosemirror-state';
import { PluginKey } from 'prosemirror-state';
import { Schema } from 'prosemirror-model';
import { SchemaSpec } from 'prosemirror-model';
import { Slice } from 'prosemirror-model';
import { TagParseRule } from 'prosemirror-model';
import { Transaction } from 'prosemirror-state';

/**
 * Use the prosemirror-math default SchemaSpec to create a new Schema.
 */
export declare function createMathSchema(): Schema<"math_inline" | "math_display" | "text" | "doc" | "paragraph", "math_select">;

/**
 * Returns a function suitable for passing as a field in `EditorProps.nodeViews`.
 * @param displayMode TRUE for block math, FALSE for inline math.
 * @see https://prosemirror.net/docs/ref/#view.EditorProps.nodeViews
 */
export declare function createMathView(displayMode: boolean): NodeViewConstructor;

export declare const defaultBlockMathParseRules: TagParseRule[];

export declare const defaultInlineMathParseRules: TagParseRule[];

export declare interface IMathPluginState {
    macros: {
        [cmd: string]: string;
    };
    /**
     * Used to determine whether to place the cursor in the front- or back-most
     * position when expanding a math node, without overriding the default arrow
     * key behavior.
     */
    prevCursorPos: number;
}

declare interface IMathViewOptions {
    /** Dom element name to use for this NodeView */
    tagName?: string;
    /** Whether to render this node as display or inline math. */
    katexOptions?: default_2.KatexOptions;
}

/**
 * Returns a new command that can be used to inserts a new math node at the
 * user's current document position, provided that the document schema actually
 * allows a math node to be placed there.
 *
 * @param mathNodeType An instance for either your math_inline or math_display
 *     NodeType.  Must belong to the same schema that your EditorState uses!
 * @param initialText (optional) The initial source content for the math editor.
 */
export declare function insertMathCmd(mathNodeType: NodeType, initialText?: string): Command;

export declare function makeBlockMathInputRule(pattern: RegExp, nodeType: NodeType, getAttrs?: (match: string[]) => any): InputRule;

export declare function makeInlineMathInputRule(pattern: RegExp, nodeType: NodeType, getAttrs?: (match: string[]) => any): InputRule;

declare type MarkSerializer<T extends string> = (mark: TypedMark<T>) => string;

export declare const mathBackspaceCmd: Command;

export declare const mathPlugin: Plugin_2<IMathPluginState>;

export declare const mathSchemaSpec: SchemaSpecJson<"math_inline" | "math_display" | "text" | "doc" | "paragraph", "math_select">;

/**
 * Due to the internals of KaTeX, by default, selecting rendered
 * math will put a box around each individual character of a
 * math expression.  This plugin attempts to make math selections
 * slightly prettier by instead setting a background color on the node.
 *
 * (remember to use the included math.css!)
 *
 * @todo (benrbray @ 6/13/20) math selection rectangles are not quite even with text
 */
export declare const mathSelectPlugin: Plugin_2;

export declare const mathSerializer: ProseMirrorTextSerializer<Schema<"math_inline" | "math_display" | "text" | "doc" | "paragraph", "math_select">>;

export declare class MathView implements NodeView {
    private _node;
    private _outerView;
    private _getPos;
    dom: HTMLElement;
    private _mathRenderElt;
    private _mathSrcElt;
    private _innerView;
    private _katexOptions;
    private _tagName;
    private _isEditing;
    private _mathPluginKey;
    /**
     * Math Views support the following options:
     * @option displayMode If TRUE, will render math in display mode, otherwise in inline mode.
     * @option tagName HTML tag name to use for this NodeView.  If none is provided,
     *     will use the node name with underscores converted to hyphens.
     */
    constructor(node: Node_2, view: EditorView, getPos: (() => number | undefined), options: IMathViewOptions | undefined, mathPluginKey: PluginKey<IMathPluginState>);
    destroy(): void;
    /**
     * Ensure focus on the inner editor whenever this node has focus.
     * This helps to prevent accidental deletions of math blocks.
     */
    ensureFocus(): void;
    update(node: Node_2, decorations: readonly Decoration[]): boolean;
    selectNode(): void;
    deselectNode(): void;
    stopEvent(event: Event): boolean;
    ignoreMutation(): boolean;
    renderMath(): void;
    dispatchInner(tr: Transaction): void;
    openEditor(): void;
    /**
     * Called when the inner ProseMirror editor should close.
     *
     * @param render Optionally update the rendered math after closing. (which
     *    is generally what we want to do, since the user is done editing!)
     */
    closeEditor(render?: boolean): void;
}

declare type NodeSerializer<T extends string> = (node: TypedNode<T>) => string;

declare class ProseMirrorTextSerializer<S extends Schema<any, any>> {
    nodes: {
        [name: string]: NodeSerializer<string> | undefined;
    };
    marks: {
        [name: string]: NodeSerializer<string> | undefined;
    };
    constructor(fns: {
        nodes?: {
            [name in SchemaNodeT<S>]?: NodeSerializer<name>;
        };
        marks?: {
            [name in SchemaMarkT<S>]?: MarkSerializer<name>;
        };
    }, base?: ProseMirrorTextSerializer<S>);
    serializeFragment(fragment: Fragment): string;
    serializeSlice(slice: Slice): string;
    serializeNode(node: Node_2): string | null;
}

export declare const REGEX_BLOCK_MATH_DOLLARS: RegExp;

export declare const REGEX_INLINE_MATH_DOLLARS: RegExp;

export declare const REGEX_INLINE_MATH_DOLLARS_ESCAPED: RegExp;

export declare type SchemaMarkT<S> = S extends Schema<infer _, infer M> ? M : never;

export declare type SchemaNodeT<S> = S extends Schema<infer N, infer _> ? N : never;

/**
 * Borrowed from ProseMirror typings, modified to exclude OrderedMaps in spec,
 * in order to help with the schema-building functions below.
 *
 * NOTE:  TypeScript's typings for the spread operator { ...a, ...b } are only
 * an approximation to the true type, and have difficulty with optional fields.
 * So, unlike the SchemaSpec type, the `marks` field is NOT optional here.
 *
 * function example<T extends string>(x: { [name in T]: string; } | null) {
 *     const s = { ...x }; // inferred to have type `{}`.
 * }
 *
 * @see https://github.com/microsoft/TypeScript/issues/10727
 */
declare interface SchemaSpecJson<N extends string = any, M extends string = any> extends SchemaSpec<N, M> {
    nodes: {
        [name in N]: NodeSpec;
    };
    marks: {
        [name in M]: MarkSpec;
    };
    topNode?: string;
}

export declare type SchemaSpecMarkT<Spec> = Spec extends SchemaSpec<infer _, infer M> ? M : never;

export declare type SchemaSpecNodeT<Spec> = Spec extends SchemaSpec<infer N, infer _> ? N : never;

declare type TypedMark<T extends string> = Mark & {
    type: MarkType & {
        name: T;
    };
};

declare type TypedNode<T extends string> = Node_2 & {
    type: NodeType & {
        name: T;
    };
};

export { }
