Procházet zdrojové kódy

Add footnote and endnote commands to the LaTeX grammar (#24939)

GitOrigin-RevId: f0342156fa22a1bcf73ae2e8afdcc6f330ba5d37
Alf Eaton před 1 rokem
rodič
revize
c378f0961c

+ 38 - 37
services/web/frontend/js/features/source-editor/extensions/visual/atomic-decorations.ts

@@ -1066,6 +1066,44 @@ export const atomicDecorations = (options: Options) => {
               )
             )
           }
+        } else if (
+          nodeRef.type.is('FootnoteCommand') ||
+          nodeRef.type.is('EndnoteCommand')
+        ) {
+          const textArgumentNode = nodeRef.node.getChild('TextArgument')
+          if (textArgumentNode) {
+            if (
+              state.readOnly &&
+              selectionIntersects(state.selection, nodeRef)
+            ) {
+              // a special case for a read-only document:
+              // always display the content, styled differently from the main content.
+              decorations.push(
+                ...decorateArgumentBraces(
+                  new BraceWidget(),
+                  textArgumentNode,
+                  nodeRef.from
+                ),
+                Decoration.mark({
+                  class: 'ol-cm-footnote ol-cm-footnote-view',
+                }).range(textArgumentNode.from, textArgumentNode.to)
+              )
+            } else {
+              if (shouldDecorate(state, nodeRef)) {
+                // collapse the footnote when the selection is outside it
+                decorations.push(
+                  Decoration.replace({
+                    widget: new FootnoteWidget(
+                      nodeRef.type.is('FootnoteCommand')
+                        ? 'footnote'
+                        : 'endnote'
+                    ),
+                  }).range(nodeRef.from, nodeRef.to)
+                )
+                return false
+              }
+            }
+          }
         } else if (nodeRef.type.is('UnknownCommand')) {
           // a command that's not defined separately by the grammar
           const commandNode = nodeRef.node
@@ -1091,43 +1129,6 @@ export const atomicDecorations = (options: Options) => {
                   )
                   return false
                 }
-              } else if (
-                commandName === '\\footnote' ||
-                commandName === '\\endnote'
-              ) {
-                if (textArgumentNode) {
-                  if (
-                    state.readOnly &&
-                    selectionIntersects(state.selection, nodeRef)
-                  ) {
-                    // a special case for a read-only document:
-                    // always display the content, styled differently from the main content.
-                    decorations.push(
-                      ...decorateArgumentBraces(
-                        new BraceWidget(),
-                        textArgumentNode,
-                        nodeRef.from
-                      ),
-                      Decoration.mark({
-                        class: 'ol-cm-footnote ol-cm-footnote-view',
-                      }).range(textArgumentNode.from, textArgumentNode.to)
-                    )
-                  } else {
-                    if (shouldDecorate(state, nodeRef)) {
-                      // collapse the footnote when the selection is outside it
-                      decorations.push(
-                        Decoration.replace({
-                          widget: new FootnoteWidget(
-                            commandName === '\\footnote'
-                              ? 'footnote'
-                              : 'endnote'
-                          ),
-                        }).range(nodeRef.from, nodeRef.to)
-                      )
-                      return false
-                    }
-                  }
-                }
               } else if (commandName === '\\LaTeX') {
                 if (shouldDecorate(state, nodeRef)) {
                   decorations.push(

+ 9 - 1
services/web/frontend/js/features/source-editor/lezer-latex/latex.grammar

@@ -108,7 +108,9 @@
     TextStrikeOutCtrlSeq,
     EmphasisCtrlSeq,
     UnderlineCtrlSeq,
-    SetLengthCtrlSeq
+    SetLengthCtrlSeq,
+    FootnoteCtrlSeq,
+    EndnoteCtrlSeq
 }
 
 @external specialize {EnvName} specializeEnvName from "./tokens.mjs" {
@@ -410,6 +412,12 @@ KnownCommand<ArgumentType> {
     } |
     SetLengthCommand {
         SetLengthCtrlSeq optionalWhitespace? ShortTextArgument optionalWhitespace? ShortTextArgument
+    } |
+    FootnoteCommand {
+        FootnoteCtrlSeq optionalWhitespace? OptionalArgument? optionalWhitespace? TextArgument
+    } |
+    EndnoteCommand {
+        EndnoteCtrlSeq optionalWhitespace? OptionalArgument? optionalWhitespace? TextArgument
     }
 }
 

+ 4 - 0
services/web/frontend/js/features/source-editor/lezer-latex/tokens.mjs

@@ -99,6 +99,8 @@ import {
   EmphasisCtrlSeq,
   UnderlineCtrlSeq,
   SetLengthCtrlSeq,
+  FootnoteCtrlSeq,
+  EndnoteCtrlSeq,
 } from './latex.terms.mjs'
 
 const MAX_ARGUMENT_LOOKAHEAD = 100
@@ -605,6 +607,8 @@ const otherKnowncommands = {
   '\\emph': EmphasisCtrlSeq,
   '\\underline': UnderlineCtrlSeq,
   '\\setlength': SetLengthCtrlSeq,
+  '\\footnote': FootnoteCtrlSeq,
+  '\\endnote': EndnoteCtrlSeq,
 }
 // specializer for control sequences
 // return new tokens for specific control sequences