Skip to content

LaTeX options

Shawon edited this page Jan 30, 2025 · 4 revisions

📐 LaTeX options

Options that affect how LaTeX is shown in preview.

-- [ Markview | LaTeX ] -------------------------------------------------------------------

--- Configuration for LaTeX.
---@class config.latex
---
---@field enable boolean
---
---@field blocks? latex.blocks | fun(): latex.blocks
---@field commands? latex.commands | fun(): latex.commands
---@field escapes? latex.escapes | fun(): latex.escapes
---@field fonts? latex.fonts | fun(): latex.fonts
---@field inlines? latex.inlines | fun(): latex.inlines
---@field parenthesis? latex.parenthesis | fun(): latex.parenthesis
---@field subscripts? latex.subscripts | fun(): latex.subscripts
---@field superscripts? latex.superscripts | fun(): latex.superscripts
---@field symbols? latex.symbols | fun(): latex.symbols
---@field texts? latex.texts | fun(): latex.texts
M.latex = {
    enable = true,

    commands = {},
    texts = {},
    symbols = {},
    subscripts = {},
    superscripts = {},
    parenthesis = {},
    escapes = {},
    inlines = {},
    blocks = {},
    fonts = {}
};

-- [ Markview | LaTeX • Static ] ----------------------------------------------------------

--- Static configuration for LaTeX.
---@class config.latex_static
---
---@field enable boolean
---
--- LaTeX blocks configuration(typically made with `$$...$$`).
---@field blocks? latex.blocks
--- LaTeX commands configuration(e.g. `\frac{x}{y}`).
---@field commands? latex.commands
--- LaTeX escaped characters configuration.
---@field escapes? latex.escapes
--- LaTeX fonts configuration(e.g. `\mathtt{}`).
---@field fonts? latex.fonts
--- Inline LaTeX configuration(typically made with `$...$`).
---@field inlines? latex.inlines
--- Configuration for hiding `{}`.
---@field parenthesis? latex.parenthesis
--- LaTeX subscript configuration(`_{}`, `_x`).
---@field subscripts? latex.subscripts
--- LaTeX superscript configuration(`^{}`, `^x`).
---@field superscripts? latex.superscripts
--- TeX math symbols configuration(e.g. `\alpha`).
---@field symbols? latex.symbols
--- Text block configuration(`\text{}`).
---@field texts? latex.texts

blocks

  • Type: latex.blocks
  • Dynamic: true

Configuration for LaTeX blocks.

Expand to see default configuration
-- [ LaTeX | LaTeX blocks ] ---------------------------------------------------------------

--- Configuration table for latex math blocks.
---@class latex.blocks
---
---@field enable boolean
---
---@field hl? string | fun(buffer: integer, item: __latex.blocks): string?
---@field pad_amount integer | fun(buffer: integer, item: __latex.blocks): integer
---@field pad_char string | fun(buffer: integer, item: __latex.blocks): string
---
---@field text string | fun(buffer: integer, item: __latex.blocks): string
---@field text_hl? string | fun(buffer: integer, item: __latex.blocks): string?
blocks = {
    enable = true,

    hl = "MarkviewCode",
    pad_char = " ",
    pad_amount = 3,

    text = "  LaTeX ",
    text_hl = "MarkviewCodeInfo"
};

-- [ LaTeX | LaTeX blocks • Static ] ------------------------------------------------------

--- Configuration table for latex math blocks.
---@class latex.blocks_static
---
---@field enable boolean Enables rendering of LaTeX blocks.
---
---@field hl? string Primary highlight group for the LaTeX block.
---@field pad_amount integer Number of `pad_char` to add before & after the text.
---@field pad_char string Character to use for padding.
---
---@field text string Text to show on the top left.
---@field text_hl? string Highlight group for the `text`.
Expand to see type definitions & advanced usage
-- [ LaTeX | LaTeX blocks > Parameters ] --------------------------------------------------

--- Parsed version of a LaTeX block.
---@class __latex.blocks
---
---@field class "latex_block"
---@field marker string
---
---@field text string[]
---@field range node.range
M.__latex_blocks = {
    class = "latex_block",
    marker = "$$",

    text = { "$$1 + 2 = 3$$" },
    range = {
        row_start = 0,
        row_end = 0,
        col_start = 0,
        col_end = 13
    }
};

--- [ Advanced Usage ] ---------------------------------------------------------------------

--- Colors math blocks differently based on
--- if their start row is even or odd.
blocks = {
    hl = function (_, item)
        local range = item.range;

        if range.row_start % 2 == 0 then
            return "MarkviewCode";
        else
            return "MarkviewPalette1Bg"
        end
    end
};

commands

  • Type: latex.commands
  • Dynamic: true

Configuration for LaTeX commands.

Expand to see default configuration
-- [ LaTeX | LaTeX commands ] -------------------------------------------------------------

--- Configuration for LaTeX commands.
---@class latex.commands
---
---@field enable boolean
---@field [string] commands.opts | fun(buffer: integer, item: __latex.commands): commands.opts
commands = {
    ---+${lua}

    enable = true,

    ---+${lua, Various commonly used LaTeX math commands}

    ["frac"] = {
        condition = function (item)
            return #item.args == 2;
        end,
        on_command = {
            conceal = ""
        },

        on_args = {
            {
                on_before = function (item)
                    return {
                        end_col = item.range[2] + 1,
                        conceal = "",

                        virt_text_pos = "inline",
                        virt_text = {
                            { "(", "@punctuation.bracket" }
                        },

                        hl_mode = "combine"
                    }
                end,

                after_offset = function (range)
                    return { range[1], range[2], range[3], range[4] - 1 };
                end,
                on_after = function (item)
                    return {
                        end_col = item.range[4],
                        conceal = "",

                        virt_text_pos = "inline",
                        virt_text = {
                            { ")", "@punctuation.bracket" },
                            { " ÷ ", "@keyword.function" }
                        },

                        hl_mode = "combine"
                    }
                end
            },
            {
                on_before = function (item)
                    return {
                        end_col = item.range[2] + 1,
                        conceal = "",

                        virt_text_pos = "inline",
                        virt_text = {
                            { "(", "@punctuation.bracket" }
                        },

                        hl_mode = "combine"
                    }
                end,

                after_offset = function (range)
                    return { range[1], range[2], range[3], range[4] - 1 };
                end,
                on_after = function (item)
                    return {
                        end_col = item.range[4],
                        conceal = "",

                        virt_text_pos = "inline",
                        virt_text = {
                            { ")", "@punctuation.bracket" },
                        },

                        hl_mode = "combine"
                    }
                end
            },
        }
    },

    ["sin"] = operator("sin"),
    ["cos"] = operator("cos"),
    ["tan"] = operator("tan"),

    ["sinh"] = operator("sinh"),
    ["cosh"] = operator("cosh"),
    ["tanh"] = operator("tanh"),

    ["csc"] = operator("csc"),
    ["sec"] = operator("sec"),
    ["cot"] = operator("cot"),

    ["csch"] = operator("csch"),
    ["sech"] = operator("sech"),
    ["coth"] = operator("coth"),

    ["arcsin"] = operator("arcsin"),
    ["arccos"] = operator("arccos"),
    ["arctan"] = operator("arctan"),

    ["arg"] = operator("arg"),
    ["deg"] = operator("deg"),
    ["det"] = operator("det"),
    ["dim"] = operator("dim"),
    ["exp"] = operator("exp"),
    ["gcd"] = operator("gcd"),
    ["hom"] = operator("hom"),
    ["inf"] = operator("inf"),
    ["ker"] = operator("ker"),
    ["lg"] = operator("lg"),

    ["lim"] = operator("lim"),
    ["liminf"] = operator("lim inf", "inline", 7),
    ["limsup"] = operator("lim sup", "inline", 7),

    ["ln"] = operator("ln"),
    ["log"] = operator("log"),
    ["min"] = operator("min"),
    ["max"] = operator("max"),
    ["Pr"] = operator("Pr"),
    ["sup"] = operator("sup"),
    ["sqrt"] = operator(symbols.entries.sqrt, "inline", 5),
    ["lvert"] = operator(symbols.entries.vert, "inline", 6),
    ["lVert"] = operator(symbols.entries.Vert, "inline", 6),

    ---_

    ---_
};

-- [ LaTeX | LaTeX commands • Static ] ----------------------------------------------------

--- Static configuration for LaTeX commands.
---@class latex.commands_static
---
---@field enable boolean Enables latex command preview.
---@field [string] commands.opts Configuration table for {string}.

--- [ Helper functions ] -------------------------------------------------------------------

--- Creates a configuration table for a LaTeX command.
---@param name string Command name(Text to show).
---@param text_pos? "overlay" | "inline" `virt_text_pos` extmark options.
---@param cmd_conceal? integer Characters to conceal.
---@param cmd_hl? string Highlight group for the command.
---@return commands.opts
local operator = function (name, text_pos, cmd_conceal, cmd_hl)
    ---+${func}
    return {
        condition = function (item)
            return #item.args == 1;
        end,


        on_command = function (item)
            return {
                end_col = item.range[2] + (cmd_conceal or 1),
                conceal = "",

                virt_text_pos = text_pos or "overlay",
                virt_text = {
                    { symbols.tostring("default", name), cmd_hl or "@keyword.function" }
                },

                hl_mode = "combine"
            }
        end,

        on_args = {
            {
                on_before = function (item)
                    return {
                        end_col = item.range[2] + 1,

                        virt_text_pos = "overlay",
                        virt_text = {
                            { "(", "@punctuation.bracket" }
                        },

                        hl_mode = "combine"
                    }
                end,

                after_offset = function (range)
                    return { range[1], range[2], range[3], range[4] - 1 };
                end,

                on_after = function (item)
                    return {
                        end_col = item.range[4],

                        virt_text_pos = "overlay",
                        virt_text = {
                            { ")", "@punctuation.bracket" }
                        },

                        hl_mode = "combine"
                    }
                end
            }
        }
    };
    ---_
end
Expand to see type definitions & advanced usage
-- [ LaTeX | LaTeX commands > Type definitions ] -------------------------------------------

---@class commands.opts
---
---@field condition? fun(item: __latex.commands): boolean Condition used to determine if a command is valid.
---
---@field command_offset? fun(range: integer[]): integer[] Modifies the command's range(`{ row_start, col_start, row_end, col_end }`).
---@field on_command? config.extmark | fun(tag: table): config.extmark Extmark configuration to use on the command.
---@field on_args? commands.arg_opts[]? Configuration table for each argument.
M.latex_commands_opts = {
    condition = function (item)
        --- The item must have 2 arguments.
        --- \frac{1}{2}
        return #item.args == 2;
    end,

    --- Hide the `\frac` part.
    on_command = {
        conceal = ""
    },

    --- Add decorations to each of the arguments.
    --- Note: Making it use `x ÷ y` should be possible but
    ---       making this more complicated is not worth the
    ---       effort(at the moment).
    on_args = {
        {
            --- Replace the `{` with a `(`.
            --- An overlay virtual text would have worked too
            --- but it has issues with horizontal scrolling.
            on_before = function (item)
                return {
                    end_col = item.range[2] + 1,
                    conceal = "",

                    virt_text_pos = "inline",
                    virt_text = {
                        { "(", "@punctuation.bracket" }
                    },

                    hl_mode = "combine"
                }
            end,

            --- We need to modify the after extmarks range to
            --- hide the `}`.
            ---     {arg1}
            ---         │ └ Original `range[4]`
            --          └ New `range[4]`
            after_offset = function (range)
                return { range[1], range[2], range[3], range[4] - 1 };
            end,

            --- Replace `}` with a `)`.
            --- Also add ` ÷ ` to "fake" the operator.
            on_after = function (item)
                return {
                    end_col = item.range[4],
                    conceal = "",

                    virt_text_pos = "inline",
                    virt_text = {
                        { ")", "@punctuation.bracket" },
                        { " ÷ ", "@keyword.function" }
                    },

                    hl_mode = "combine"
                }
            end
        },
        {
            on_before = function (item)
                return {
                    end_col = item.range[2] + 1,
                    conceal = "",

                    virt_text_pos = "inline",
                    virt_text = {
                        { "(", "@punctuation.bracket" }
                    },

                    hl_mode = "combine"
                }
            end,

            after_offset = function (range)
                return { range[1], range[2], range[3], range[4] - 1 };
            end,

            on_after = function (item)
                return {
                    end_col = item.range[4],
                    conceal = "",

                    virt_text_pos = "inline",
                    virt_text = {
                        { ")", "@punctuation.bracket" },
                    },

                    hl_mode = "combine"
                }
            end
        },
    }
};

---@class commands.arg_opts
---
---@field after_offset? fun(range: integer[]): integer[] Modifies the range of the argument(only for `on_after`).
---@field before_offset? fun(range: integer[]): integer[] Modifies the range of the argument(only for `on_before`).
---@field condition? fun(item: table): boolean Can be used to change when the command preview is shown.
---@field content_offset? fun(range: integer[]): table Modifies the argument's range(only for `on_content`).
---@field on_after? config.extmark | fun(tag: table): config.extmark Extmark configuration to use at the end of the argument.
---@field on_before? config.extmark | fun(tag: table): config.extmark Extmark configuration to use at the start of the argument.
---@field on_content? config.extmark | fun(tag: table): config.extmark Extmark configuration to use on the argument.
M.latex_commands_arg_opts = {
    on_after = { virt_text = { { ")", "Comment" } }, virt_text_pos = "overlay" },
    on_before = { virt_text = { { ")", "Comment" } }, virt_text_pos = "overlay" }
};

-- [ LaTeX | LaTeX commands > Parameters ] -------------------------------------------------

--- LaTeX commands(must have at least 1 argument).
---@class __latex.commands
---
---@field class "latex_command"
---
---@field command { name: string, range: integer[] } Command name(without `\`) and it's range.
---@field args { text: string, range: integer[] }[] List of arguments(inside `{...}`) with their text & range.
---
---@field text string[]
---@field range node.range
M.__latex_commands = {
    class = "latex_command",

    command = {
        name = "frac",
        range = { 0, 0, 0, 5 }
    },
    args = {
        {
            text = "{1}",
            range = { 0, 5, 0, 8 }
        },
        {
            text = "{2}",
            range = { 0, 8, 0, 11 }
        }
    },
    text = { "\\frac{1}{2}" },
    range = {
        row_start = 0,
        row_end = 0,

        col_start = 0,
        col_end = 11
    }
};

--- [ Advanced Usage ] ---------------------------------------------------------------------

--- TODO, Add advanced usage.

escapes

  • Type: latex.escapes
  • Dynamic: true

Configuration for escaped LaTeX characters.

Expand to see default configuration
-- [ LaTeX | LaTeX escapes ] --------------------------------------------------------------

--- Configuration table for latex escaped characters.
---@class latex.escapes_static
---
---@field enable boolean Enables escaped character preview.
---@field hl? string | fun(item: __latex.escapes): string? Highlight group for the escaped character.
escapes = {
    enable = true
};

-- [ LaTeX | LaTeX escapes • Static ] -----------------------------------------------------

--- Static configuration table for latex escaped characters.
---@class latex.escapes
---
---@field enable boolean Enables escaped character preview.
---@field hl? string | fun(item: __latex.escapes): string? Highlight group for the escaped character.
Expand to see type definitions & advanced usage
-- [ LaTeX | LaTeX escapes > Parameters ] -------------------------------------------------

--- Escaped characters.
---@class __latex.escapes
---
---@field class "latex_escaped"
---
---@field text string[]
---@field range node.range
M.__latex_escapes = {
    class = "latex_escaped",

    text = { "\\|" },
    range = {
        row_start = 0,
        row_end = 0,

        col_start = 0,
        col_end = 2
    }
};

-- [ Advanced usage ] ----------------------------------------------------------------------

fonts

  • Type: latex.fonts
  • Dynamic: true

Configuration for escaped LaTeX characters.

Expand to see default configuration
-- [ LaTeX | LaTeX fonts ] ----------------------------------------------------------------

--- Configuration table for latex math fonts.
---@class latex.fonts_static
---
---@field enable boolean
---
---@field default fonts.opts | fun(buffer: integer, item: __latex.fonts): fonts.opts
---@field [string] fonts.opts | fun(buffer: integer, item: __latex.fonts): fonts.opts
fonts = {
    ---+${lua}

    enable = true,

    default = {
        enable = true
        hl = "MarkviewSpecial"
    },
    -- ["^mathtt$"] = { hl = "MarkviewPalette1" }
    ---_
};

-- [ LaTeX | LaTeX fonts • Static ] -------------------------------------------------------

--- Static configuration table for latex math fonts.
---@class latex.fonts_static
---
---@field enable boolean
---
---@field default fonts.opts Default configuration for fonts
---@field [string] fonts.opts Configuration for `\string{}` font.
Expand to see type definitions & advanced usage
-- [ LaTeX | LaTeX fonts > Type definitions ] ----------------------------------------------

--- Configuration for a specific fonts.
---@class fonts.opts
---
---@field enable? boolean Whether to enable this font.
---@field hl? string | fun(buffer: integer, item: __latex.fonts): string? Highlight group for this font.
M.fonts_opts = {
    enable = true,
    hl = "Conditional"
};

-- [ LaTeX | LaTeX fonts > Parameters ] ----------------------------------------------------

--- Math fonts
---@class __latex.fonts
---
---@field class "latex_font"
---
---@field name string Font name.
---
---@field text string[]
---@field range node.range
M.__latex_fonts = {
    class = "latex_font",

    name = "mathtt",

    text = { "\\mathtt{abcd}" },
    range = {
        font = { 0, 0, 0, 7 },
        row_start = 0,
        row_end = 0,
        col_start = 0,
        col_end = 13
    }
};

--- [ Advanced Usage ] ---------------------------------------------------------------------

fonts = {
    enable = true,
    default = { hl = "Special" },

    --- Dynamic highlight group based on
    --- font name.
    ["bf$"] = {
        hl = function (_, item)
            if item.name == "mathbf" then
                return "Comment";
            else
                return "Conditional";
            end
        end
    }
};

inlines

  • Type: latex.inlines
  • Dynamic: true

Configuration for inline LaTeX.

Expand to see default configuration
--- Configuration table for inline latex math.
---@class latex.inlines
---
---@field enable boolean Enables preview of inline latex maths.
---
---@field corner_left? string | fun(buffer: integer, item: __latex.inlines): string? Left corner.
---@field corner_left_hl? string | fun(buffer: integer, item: __latex.inlines): string? Highlight group for left corner.
---@field corner_right? string | fun(buffer: integer, item: __latex.inlines): string? Right corner.
---@field corner_right_hl? string | fun(buffer: integer, item: __latex.inlines): string? Highlight group for right corner.
---@field hl? string | fun(buffer: integer, item: __latex.inlines): string? Base Highlight group.
---@field padding_left? string | fun(buffer: integer, item: __latex.inlines): string? Left padding.
---@field padding_left_hl? string | fun(buffer: integer, item: __latex.inlines): string? Highlight group for left padding.
---@field padding_right? string | fun(buffer: integer, item: __latex.inlines): string? Right padding.
---@field padding_right_hl? string | fun(buffer: integer, item: __latex.inlines): string? Highlight group for right padding.
inlines = {
    enable = true,

    padding_left = " ",
    padding_right = " ",

    hl = "MarkviewInlineCode"
};
Expand to see type definitions & advanced usage
-- [ LaTeX | Inline LaTeX > Parameters ] --------------------------------------------------

--- Inline LaTeX(typically made using `$...$`).
---@class __latex.inlines
---
---@field class "latex_inlines"
---@field marker string
---
---@field text string[]
---@field range node.range
M.__latex_inlines = {
    class = "latex_inlines",
    marker = "$",

    text = { "$1 + 1 = 2$" },
    range = {
        row_start = 0,
        col_start = 0,

        row_end = 0,
        col_end = 11
    }
};

parenthesis

  • Type: latex.parenthesis
  • Dynamic: false

Hides {}.

Expand to see default configuration
--- Configuration for {}.
---@class latex.parenthesis
---
---@field enable boolean
parenthesis = {
    enable = true
};
Expand to see type definitions & advanced usage
-- [ LaTeX | Parenthesis > Parameters ] ----------------------------------------------------------------

--- {} in LaTeX.
---@class __latex.parenthesis
---
---@field class "latex_parenthesis"
---@field text string[]
---@field range node.range
M.__latex_parenthesis = {
    class = "latex_parenthesis",
    text = { "{1+2}" },
    range = {
        row_start = 0,
        row_end = 0,

        col_start = 0,
        col_end = 5
    }
};

subscripts

  • Type: latex.subscripts
  • Dynamic: true

Configuration for subscripts(_{}).

Expand to see default configuration
-- [ LaTeX | Subscripts ] ----------------------------------------------------------------

--- Configuration for subscripts.
---@class latex.subscripts
---
---@field enable boolean Enables preview of subscript text.
---@field fake_preview? boolean When `true`, subscript characters are *faked*.
---@field hl? string | string[] Highlight group for the subscript text. Can be a list to use different hl for nested subscripts.
subscripts = {
    enable = true,
    hl = "MarkviewSubscript"
};
Expand to see type definitions & advanced usage
-- [ LaTeX | Subscripts > Parameters ] -----------------------------------------------------

--- Subscript text(e.g. _h, _{hi}, _{+} etc.).
---@class __latex.subscripts
---
---@field class "latex_subscript"
---
---@field parenthesis boolean Is the text within `{...}`?
---@field level integer Level of the subscript text. Used for handling nested subscript text.
---@field preview boolean Can the text be previewed?
---
---@field text string[]
---@field range node.range
M.__latex_subscripts = {
    class = "latex_subscript",
    parenthesis = true,
    preview = true,
    level = 1,

    text = { "_{hi}" },
    range = {
        row_start = 0,
        row_end = 0,

        col_start = 0,
        col_end = 5
    }
};

superscripts

  • Type: latex.superscripts
  • Dynamic: true

Configuration for superscripts(^{}).

Expand to see default configuration
-- [ LaTeX | Superscripts ] ---------------------------------------------------------------

--- Configuration for superscripts.
---@class latex.superscripts
---
---@field enable boolean Enables preview of superscript text.
---@field fake_preview? boolean When `true`, superscript characters are *faked*.
---@field hl? string | string[] Highlight group for the superscript text. Can be a list to use different hl for nested superscripts.
subscripts = {
    enable = true,
    hl = "MarkviewSuperscript"
};
Expand to see type definitions & advanced usage
-- [ LaTeX | Superscripts > Parameters ] --------------------------------------------------

--- Superscript text(e.g. ^h, ^{hi}, ^{+} etc.).
---@class __latex.superscripts
---
---@field class "latex_superscript"
---
---@field parenthesis boolean Is the text within `{...}`?
---@field level integer Level of the superscript text. Used for handling nested superscript text.
---@field preview boolean Can the text be previewed?
---
---@field text string[]
---@field range node.range
M.__latex_superscripts = {
    class = "latex_superscript",
    parenthesis = true,
    preview = true,
    level = 1,

    text = { "^{hi}" },
    range = {
        row_start = 0,
        row_end = 0,

        col_start = 0,
        col_end = 5
    }
};

symbols

  • Type: latex.symbols
  • Dynamic: true

Configuration for TeX math symbols.

Expand to see default configuration
-- [ LaTeX | Symbols ] --------------------------------------------------------------------

--- Configuration table for TeX math symbols.
---@class latex.symbols
---
---@field enable boolean
---@field hl? string | fun(buffer: integer, item: __latex.symbols): string?
symbols = {
    enable = true,
    hl = "MarkviewSuperscript"
};

-- [ LaTeX | Symbols • Static ] -----------------------------------------------------------

--- Configuration table for TeX math symbols.
---@class latex.symbols_static
---
---@field enable boolean Enables preview of latex math symbols.
---@field hl? string Highlight group for the symbols.
Expand to see type definitions & advanced usage
-- [ LaTeX | Symbols > Parameters ] -------------------------------------------------------

--- Math symbols in LaTeX(e.g. \Alpha).
---@class __latex.symbols
---
---@field class "latex_symbols"
---@field name string Symbol name(without the `\`).
---@field style "superscripts" | "subscripts" | nil Text styles to apply(if possible).
---
---@field text string[]
---@field range node.range
M.__latex_symbols = {
    class = "latex_symbols",
    name = "pi",
    style = nil,

    text = { "\\pi" },
    range = {
        row_start = 0,
        row_end = 0,

        col_start = 0,
        col_end = 3
    }
};

texts

  • Type: latex.texts
  • Dynamic: true

Configuration for \text{}.

Expand to see default configuration
--- Configuration table for `\text{}.
---@class latex.texts
---
---@field enable boolean
texts = {
    enable = true
};

Also available in vimdoc, :h markview.nvim-latex.