From ca9593e74cb34669e4eb2463e05b0f49310bcd54 Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Tue, 18 Jul 2023 11:52:28 +0100 Subject: [PATCH] [visual] Decorate quotation environments (#13728) GitOrigin-RevId: 65c4bb8b4695d0698120936d3b2fb8ec6fa402dc --- .../extensions/visual/atomic-decorations.ts | 4 +++ .../extensions/visual/mark-decorations.ts | 32 +++++++++++++++++++ .../extensions/visual/visual-theme.ts | 5 +++ .../codemirror-editor-visual.spec.tsx | 16 ++++++++++ 4 files changed, 57 insertions(+) diff --git a/services/web/frontend/js/features/source-editor/extensions/visual/atomic-decorations.ts b/services/web/frontend/js/features/source-editor/extensions/visual/atomic-decorations.ts index 7911fc21cd..deabf097af 100644 --- a/services/web/frontend/js/features/source-editor/extensions/visual/atomic-decorations.ts +++ b/services/web/frontend/js/features/source-editor/extensions/visual/atomic-decorations.ts @@ -242,6 +242,10 @@ export const atomicDecorations = (options: Options) => { 'table', 'verbatim', 'lstlisting', + 'quote', + 'quotation', + 'quoting', + 'displayquote', ] if (envName && hideInEnvironmentTypes.includes(envName)) { const beginNode = nodeRef.node.getChild('BeginEnv') diff --git a/services/web/frontend/js/features/source-editor/extensions/visual/mark-decorations.ts b/services/web/frontend/js/features/source-editor/extensions/visual/mark-decorations.ts index 9d5173472d..ffdf11b1dc 100644 --- a/services/web/frontend/js/features/source-editor/extensions/visual/mark-decorations.ts +++ b/services/web/frontend/js/features/source-editor/extensions/visual/mark-decorations.ts @@ -153,6 +153,38 @@ export const markDecorations = ViewPlugin.define( } break + case 'quote': + case 'quotation': + case 'quoting': + case 'displayquote': + { + const lines = { + start: state.doc.lineAt(nodeRef.from), + end: state.doc.lineAt(nodeRef.to), + } + + for ( + let lineNumber = lines.start.number; + lineNumber <= lines.end.number; + lineNumber++ + ) { + const line = state.doc.line(lineNumber) + + const classNames = [ + `ol-cm-environment-${environmentName}`, + 'ol-cm-environment-quote-block', + 'ol-cm-environment-line', + ] + + decorations.push( + Decoration.line({ + class: classNames.join(' '), + }).range(line.from) + ) + } + } + break + default: if (theoremStyles.has(environmentName)) { const theoremStyle = theoremStyles.get(environmentName) diff --git a/services/web/frontend/js/features/source-editor/extensions/visual/visual-theme.ts b/services/web/frontend/js/features/source-editor/extensions/visual/visual-theme.ts index 21266832a2..ae4c9adcb8 100644 --- a/services/web/frontend/js/features/source-editor/extensions/visual/visual-theme.ts +++ b/services/web/frontend/js/features/source-editor/extensions/visual/visual-theme.ts @@ -150,6 +150,11 @@ export const visualTheme = EditorView.theme({ '.ol-cm-begin-proof > .ol-cm-environment-name': { fontStyle: 'italic', }, + '.ol-cm-environment-quote-block.ol-cm-environment-line': { + borderLeft: '4px solid rgba(125, 125, 125, 0.25)', + paddingLeft: '1em', + borderRadius: '0', + }, '.ol-cm-environment-padding': { flex: 1, height: '1px', diff --git a/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual.spec.tsx b/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual.spec.tsx index c26afdf8ba..d08651204f 100644 --- a/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual.spec.tsx +++ b/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual.spec.tsx @@ -626,6 +626,22 @@ describe(' in Visual mode', function () { }) }) + forEach(['quote', 'quotation', 'quoting', 'displayquote']).it( + 'renders a %s environment', + function (environment) { + cy.get('@first-line').type(`\\begin{{}${environment}`) + cy.findAllByRole('listbox').should('have.length', 1) + cy.findByRole('listbox').contains(`\\begin{${environment}}`).click() + cy.get('@second-line').type('foo') + cy.get('.cm-content').should( + 'have.text', + [`\\begin{${environment}}`, ' foo', `\\end{${environment}}`].join('') + ) + cy.get('.cm-line').eq(4).click() + cy.get('.cm-content').should('have.text', ' foo') + } + ) + // TODO: \input // TODO: Math // TODO: Abstract