diff --git a/services/web/frontend/js/features/source-editor/components/codemirror-command-tooltip.tsx b/services/web/frontend/js/features/source-editor/components/codemirror-command-tooltip.tsx index c8c4814688..cb31899c25 100644 --- a/services/web/frontend/js/features/source-editor/components/codemirror-command-tooltip.tsx +++ b/services/web/frontend/js/features/source-editor/components/codemirror-command-tooltip.tsx @@ -14,6 +14,7 @@ import { RefTooltipContent } from './command-tooltip/ref-tooltip' import { IncludeTooltipContent } from './command-tooltip/include-tooltip' import { InputTooltipContent } from './command-tooltip/input-tooltip' import { getTooltip } from '@codemirror/view' +import { SubfileTooltipContent } from '@/features/source-editor/components/command-tooltip/subfile-tooltip' export const CodeMirrorCommandTooltip = memo(function CodeMirrorLinkTooltip() { const view = useCodeMirrorViewContext() @@ -86,6 +87,8 @@ const CodeMirrorCommandTooltipContent = memo<{ return case 'Input': return + case 'Subfile': + return default: return null } diff --git a/services/web/frontend/js/features/source-editor/components/command-tooltip/subfile-tooltip.tsx b/services/web/frontend/js/features/source-editor/components/command-tooltip/subfile-tooltip.tsx new file mode 100644 index 0000000000..30c7a0a5ee --- /dev/null +++ b/services/web/frontend/js/features/source-editor/components/command-tooltip/subfile-tooltip.tsx @@ -0,0 +1,24 @@ +import { FC } from 'react' +import { useTranslation } from 'react-i18next' +import { useIncludedFile } from '@/features/source-editor/hooks/use-included-file' +import OLButton from '@/shared/components/ol/ol-button' +import MaterialIcon from '@/shared/components/material-icon' + +export const SubfileTooltipContent: FC = () => { + const { t } = useTranslation() + const { openIncludedFile } = useIncludedFile('SubfileArgument') + + return ( +
+ + + {t('open_file')} + +
+ ) +} diff --git a/services/web/frontend/js/features/source-editor/extensions/command-tooltip.ts b/services/web/frontend/js/features/source-editor/extensions/command-tooltip.ts index 545187eb94..567374bdf0 100644 --- a/services/web/frontend/js/features/source-editor/extensions/command-tooltip.ts +++ b/services/web/frontend/js/features/source-editor/extensions/command-tooltip.ts @@ -201,6 +201,16 @@ const createTooltipState = ( return buildTooltip(commandName, pos, value, commandNode, argumentNode) } + + // a subfile file (\subfile) + case 'Subfile': { + const argumentNode = commandNode + .getChild('SubfileArgument') + ?.getChild(FilePathArgument) + ?.getChild(LiteralArgContent) + + return buildTooltip(commandName, pos, value, commandNode, argumentNode) + } } return null diff --git a/services/web/frontend/js/features/source-editor/languages/latex/complete.ts b/services/web/frontend/js/features/source-editor/languages/latex/complete.ts index f512540421..698169648f 100644 --- a/services/web/frontend/js/features/source-editor/languages/latex/complete.ts +++ b/services/web/frontend/js/features/source-editor/languages/latex/complete.ts @@ -242,20 +242,7 @@ export const packageArgumentCompletionSource: CompletionSource = export const inputArgumentCompletionSource: CompletionSource = makeArgumentCompletionSource( - ['InputArgument'], - ({ completions, context, from }) => { - buildIncludeCompletions(completions, context) - - return { - from, - validFor: /^[^}]*/, - options: completions.includes, - } - } - ) -export const includeArgumentCompletionSource: CompletionSource = - makeArgumentCompletionSource( - ['IncludeArgument'], + ['InputArgument', 'IncludeArgument', 'SubfileArgument'], ({ completions, context, from }) => { buildIncludeCompletions(completions, context) @@ -355,7 +342,6 @@ export const argumentCompletionSources: CompletionSource[] = [ refArgumentCompletionSource, packageArgumentCompletionSource, inputArgumentCompletionSource, - includeArgumentCompletionSource, includeGraphicsArgumentCompletionSource, environmentNameCompletionSource, documentClassArgumentCompletionSource, diff --git a/services/web/frontend/js/features/source-editor/languages/latex/completions/include.ts b/services/web/frontend/js/features/source-editor/languages/latex/completions/include.ts index 7de46118e8..c439785c78 100644 --- a/services/web/frontend/js/features/source-editor/languages/latex/completions/include.ts +++ b/services/web/frontend/js/features/source-editor/languages/latex/completions/include.ts @@ -56,6 +56,14 @@ export function buildIncludeCompletions( apply: `\\input{${removeTexExtension(path)}}`, extend: extendOverUnpairedClosingBrace, }) + + // \subfile{path} + completions.commands.push({ + type: 'cmd', + label: `\\subfile{${path}}`, + apply: `\\subfile{${removeTexExtension(path)}}`, + extend: extendOverUnpairedClosingBrace, + }) } // TODO: a better list of graphics extensions? diff --git a/services/web/frontend/js/features/source-editor/languages/latex/latex-language.ts b/services/web/frontend/js/features/source-editor/languages/latex/latex-language.ts index 8e04adcb32..44e74cd412 100644 --- a/services/web/frontend/js/features/source-editor/languages/latex/latex-language.ts +++ b/services/web/frontend/js/features/source-editor/languages/latex/latex-language.ts @@ -51,6 +51,7 @@ const typeMap: Record = { HrefCommand: ['$CommandTooltipCommand'], Include: ['$CommandTooltipCommand'], Input: ['$CommandTooltipCommand'], + Subfile: ['$CommandTooltipCommand'], Ref: ['$CommandTooltipCommand'], UrlCommand: ['$CommandTooltipCommand'], // text formatting commands that can be toggled via the toolbar diff --git a/services/web/frontend/js/features/source-editor/lezer-latex/latex.grammar b/services/web/frontend/js/features/source-editor/lezer-latex/latex.grammar index fb8657a48c..73b5db8906 100644 --- a/services/web/frontend/js/features/source-editor/lezer-latex/latex.grammar +++ b/services/web/frontend/js/features/source-editor/lezer-latex/latex.grammar @@ -78,6 +78,7 @@ SubParagraphCtrlSeq, InputCtrlSeq, IncludeCtrlSeq, + SubfileCtrlSeq, ItemCtrlSeq, NewTheoremCtrlSeq, TheoremStyleCtrlSeq, @@ -350,6 +351,9 @@ KnownCommand { Include { IncludeCtrlSeq IncludeArgument { FilePathArgument } } | + Subfile { + SubfileCtrlSeq SubfileArgument { FilePathArgument } + } | Centering { CenteringCtrlSeq } | diff --git a/services/web/frontend/js/features/source-editor/lezer-latex/tokens.mjs b/services/web/frontend/js/features/source-editor/lezer-latex/tokens.mjs index 1c5bf6f51b..75c19ed43b 100644 --- a/services/web/frontend/js/features/source-editor/lezer-latex/tokens.mjs +++ b/services/web/frontend/js/features/source-editor/lezer-latex/tokens.mjs @@ -65,6 +65,7 @@ import { SubParagraphCtrlSeq, InputCtrlSeq, IncludeCtrlSeq, + SubfileCtrlSeq, ItemCtrlSeq, NewTheoremCtrlSeq, TheoremStyleCtrlSeq, @@ -580,6 +581,7 @@ const otherKnowncommands = { '\\subparagraph': SubParagraphCtrlSeq, '\\input': InputCtrlSeq, '\\include': IncludeCtrlSeq, + '\\subfile': SubfileCtrlSeq, '\\item': ItemCtrlSeq, '\\centering': CenteringCtrlSeq, '\\newtheorem': NewTheoremCtrlSeq, diff --git a/services/web/frontend/js/features/word-count-modal/utils/count-words-in-file.ts b/services/web/frontend/js/features/word-count-modal/utils/count-words-in-file.ts index 3cd2801ae2..df968dc610 100644 --- a/services/web/frontend/js/features/word-count-modal/utils/count-words-in-file.ts +++ b/services/web/frontend/js/features/word-count-modal/utils/count-words-in-file.ts @@ -254,7 +254,7 @@ export const countWordsInFile = ( iterateNode(nodeRef, 'footnote') return false }, - 'IncludeArgument InputArgument'(nodeRef) { + 'IncludeArgument InputArgument SubfileArgument'(nodeRef) { const path = content.substring(nodeRef.from + 1, nodeRef.to - 1) debugConsole.log(path) if (path) {