mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-10 21:50:14 -07:00
Labs: Add opt-in single-dollar inline LaTeX rendering
Add a 'Dollar Inline LaTeX' toggle in Settings > Labs that enables single-dollar ($...$) inline math rendering via remark-math. Off by default since it can cause false positives with currency ($10) and stock symbols ($AAPL). Closes #795. Co-authored-by: Enrico Ros <enricoros@users.noreply.github.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import * as React from 'react';
|
||||
import { FormControl, Typography } from '@mui/joy';
|
||||
import EditNoteIcon from '@mui/icons-material/EditNote';
|
||||
import AttachFileRoundedIcon from '@mui/icons-material/AttachFileRounded';
|
||||
import FunctionsIcon from '@mui/icons-material/Functions';
|
||||
import ShortcutIcon from '@mui/icons-material/Shortcut';
|
||||
import SpeedIcon from '@mui/icons-material/Speed';
|
||||
|
||||
@@ -24,6 +25,7 @@ export function UxLabsSettings() {
|
||||
labsAutoHideComposer, setLabsAutoHideComposer,
|
||||
labsShowShortcutBar, setLabsShowShortcutBar,
|
||||
labsComposerAttachmentsInline, setLabsComposerAttachmentsInline,
|
||||
labsSingleDollarLatex, setLabsSingleDollarLatex,
|
||||
} = useUXLabsStore();
|
||||
|
||||
return <>
|
||||
@@ -39,6 +41,17 @@ export function UxLabsSettings() {
|
||||
checked={labsLosslessImages} onChange={setLabsPreserveLosslessImages}
|
||||
/>
|
||||
|
||||
<FormSwitchControl
|
||||
title={<><FunctionsIcon sx={{ fontSize: 'lg', mr: 0.5, mb: 0.25 }} />Dollar Inline LaTeX</>} description={labsSingleDollarLatex ? 'Enabled' : 'Disabled'}
|
||||
tooltipWarning={labsSingleDollarLatex}
|
||||
tooltip={<>
|
||||
Renders single-dollar <code>$...$</code> as inline LaTeX math formulas, in addition to the default <code>{'\\\\(...)\\\\)'}</code> and <code>$$...$$</code> formats.
|
||||
<hr />
|
||||
WARNING: This may cause false positives - currency values like $10 or stock symbols like $AAPL could be incorrectly rendered as math.
|
||||
</>}
|
||||
checked={labsSingleDollarLatex} onChange={setLabsSingleDollarLatex}
|
||||
/>
|
||||
|
||||
<FormSwitchControl
|
||||
title={<><SpeedIcon sx={{ fontSize: 'lg', mr: 0.5, mb: 0.25 }} />Unlock Refresh</>} description={labsHighPerformance ? 'Unlocked' : 'Default'}
|
||||
tooltipWarning={labsHighPerformance}
|
||||
|
||||
@@ -25,6 +25,9 @@ interface UXLabsStore {
|
||||
labsLosslessImages: boolean;
|
||||
setLabsPreserveLosslessImages: (labsLosslessImages: boolean) => void;
|
||||
|
||||
labsSingleDollarLatex: boolean;
|
||||
setLabsSingleDollarLatex: (labsSingleDollarLatex: boolean) => void;
|
||||
|
||||
}
|
||||
|
||||
export const useUXLabsStore = create<UXLabsStore>()(
|
||||
@@ -46,6 +49,9 @@ export const useUXLabsStore = create<UXLabsStore>()(
|
||||
labsLosslessImages: false,
|
||||
setLabsPreserveLosslessImages: (labsLosslessImages: boolean) => set({ labsLosslessImages }),
|
||||
|
||||
labsSingleDollarLatex: false,
|
||||
setLabsSingleDollarLatex: (labsSingleDollarLatex: boolean) => set({ labsSingleDollarLatex }),
|
||||
|
||||
}),
|
||||
{
|
||||
name: 'app-ux-labs',
|
||||
|
||||
@@ -12,6 +12,7 @@ import { Box, Chip } from '@mui/joy';
|
||||
|
||||
import { copyToClipboard } from '~/common/util/clipboardUtils';
|
||||
import { downloadBlob } from '~/common/util/downloadUtils';
|
||||
import { useUXLabsStore } from '~/common/stores/store-ux-labs';
|
||||
|
||||
import { CustomARenderer } from './CustomARenderer';
|
||||
import { remarkTableCellBreaks } from './tableBreaks.remark';
|
||||
@@ -208,18 +209,18 @@ const reactMarkdownComponents = {
|
||||
// math/inlineMath components are not needed, rehype-katex handles this automatically
|
||||
} as ReactMarkdownComponents;
|
||||
|
||||
const remarkPluginsStable: UnifiedPluggable[] = [
|
||||
const remarkPluginsBase: UnifiedPluggable[] = [
|
||||
remarkGfm, // GitHub Flavored Markdown
|
||||
remarkMark, // Mark-Highlight, for ==yellow==
|
||||
remarkTableCellBreaks, // Convert <br> HTML tags inside tables to break nodes (for line breaks in table cells)
|
||||
[remarkMath, {
|
||||
/**
|
||||
* NOTE: this could be configurable, some users reported liking single dollar signs math, despite even the official
|
||||
* LaTeX documentation recommending against it: https://docs.mathjax.org/en/latest/input/tex/delimiters.html
|
||||
* So in the future this could be a user setting.
|
||||
*/
|
||||
singleDollarTextMath: false,
|
||||
}],
|
||||
[remarkMath, { singleDollarTextMath: false }],
|
||||
];
|
||||
|
||||
const remarkPluginsSingleDollar: UnifiedPluggable[] = [
|
||||
remarkGfm,
|
||||
remarkMark,
|
||||
remarkTableCellBreaks,
|
||||
[remarkMath, { singleDollarTextMath: true }],
|
||||
];
|
||||
|
||||
const rehypePluginsStable: UnifiedPluggable[] = [
|
||||
@@ -275,10 +276,14 @@ function preprocessMarkdown(markdownText: string) {
|
||||
}
|
||||
|
||||
export default function CustomMarkdownRenderer(props: { content: string, disablePreprocessor?: boolean }) {
|
||||
|
||||
// external state
|
||||
const singleDollarLatex = useUXLabsStore((s) => s.labsSingleDollarLatex);
|
||||
|
||||
return (
|
||||
<ReactMarkdown
|
||||
components={reactMarkdownComponents}
|
||||
remarkPlugins={remarkPluginsStable}
|
||||
remarkPlugins={singleDollarLatex ? remarkPluginsSingleDollar : remarkPluginsBase}
|
||||
rehypePlugins={rehypePluginsStable}
|
||||
>
|
||||
{props.disablePreprocessor ? props.content : preprocessMarkdown(props.content)}
|
||||
|
||||
Reference in New Issue
Block a user