mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
[cm6] support \emph and \textbf in maketitle (#13703)
* [cm6] support \textbf in maketitle * support for emph * added support for \\textbf * fix overlapping ignored ranges * fix overlapping fn, added test * multiple maketitle cases in the same test * prettier * simplify from calculation * added test cases from #13736 GitOrigin-RevId: 00dcf15d6d62903ae30b387a16929e68dde8ca1b
This commit is contained in:
parent
fdeb36c2c2
commit
8ab6239a24
2 changed files with 66 additions and 13 deletions
|
@ -34,8 +34,6 @@ export function typesetNodeIntoElement(
|
||||||
const popAncestor = () => ancestorStack.pop()!
|
const popAncestor = () => ancestorStack.pop()!
|
||||||
const pushAncestor = (x: HTMLElement) => ancestorStack.push(x)
|
const pushAncestor = (x: HTMLElement) => ancestorStack.push(x)
|
||||||
|
|
||||||
// NOTE: Quite hack-ish way to omit closing braces from the output
|
|
||||||
const ignoredRanges: { from: number; to: number }[] = []
|
|
||||||
let from = node.from
|
let from = node.from
|
||||||
|
|
||||||
node.cursor().iterate(
|
node.cursor().iterate(
|
||||||
|
@ -45,20 +43,21 @@ export function typesetNodeIntoElement(
|
||||||
ancestor().append(
|
ancestor().append(
|
||||||
document.createTextNode(state.sliceDoc(from, childNode.from))
|
document.createTextNode(state.sliceDoc(from, childNode.from))
|
||||||
)
|
)
|
||||||
from = ignoredRanges.some(
|
|
||||||
range => range.from <= childNode.from && range.to >= childNode.from
|
from = childNode.from
|
||||||
)
|
|
||||||
? childNode.to
|
|
||||||
: childNode.from
|
|
||||||
}
|
}
|
||||||
if (isUnknownCommandWithName(childNode, '\\textit', state)) {
|
if (isUnknownCommandWithName(childNode, '\\textit', state)) {
|
||||||
pushAncestor(document.createElement('i'))
|
pushAncestor(document.createElement('i'))
|
||||||
const argument = childNode.getChild('TextArgument')
|
const textArgument = childNode.getChild('TextArgument')
|
||||||
from = argument?.getChild('LongArg')?.from ?? childNode.to
|
from = textArgument?.getChild('LongArg')?.from ?? childNode.to
|
||||||
const endBrace = argument?.getChild('CloseBrace')
|
} else if (isUnknownCommandWithName(childNode, '\\textbf', state)) {
|
||||||
if (endBrace) {
|
pushAncestor(document.createElement('b'))
|
||||||
ignoredRanges.push(endBrace)
|
const textArgument = childNode.getChild('TextArgument')
|
||||||
}
|
from = textArgument?.getChild('LongArg')?.from ?? childNode.to
|
||||||
|
} else if (isUnknownCommandWithName(childNode, '\\emph', state)) {
|
||||||
|
pushAncestor(document.createElement('em'))
|
||||||
|
const textArgument = childNode.getChild('TextArgument')
|
||||||
|
from = textArgument?.getChild('LongArg')?.from ?? childNode.to
|
||||||
} else if (isNewline(childNode, state)) {
|
} else if (isNewline(childNode, state)) {
|
||||||
ancestor().appendChild(document.createElement('br'))
|
ancestor().appendChild(document.createElement('br'))
|
||||||
from = childNode.to
|
from = childNode.to
|
||||||
|
@ -69,6 +68,27 @@ export function typesetNodeIntoElement(
|
||||||
if (isUnknownCommandWithName(childNode, '\\textit', state)) {
|
if (isUnknownCommandWithName(childNode, '\\textit', state)) {
|
||||||
const typeSetElement = popAncestor()
|
const typeSetElement = popAncestor()
|
||||||
ancestor().appendChild(typeSetElement)
|
ancestor().appendChild(typeSetElement)
|
||||||
|
const textArgument = childNode.getChild('TextArgument')
|
||||||
|
const endBrace = textArgument?.getChild('CloseBrace')
|
||||||
|
if (endBrace) {
|
||||||
|
from = endBrace.to
|
||||||
|
}
|
||||||
|
} else if (isUnknownCommandWithName(childNode, '\\textbf', state)) {
|
||||||
|
const typeSetElement = popAncestor()
|
||||||
|
ancestor().appendChild(typeSetElement)
|
||||||
|
const textArgument = childNode.getChild('TextArgument')
|
||||||
|
const endBrace = textArgument?.getChild('CloseBrace')
|
||||||
|
if (endBrace) {
|
||||||
|
from = endBrace.to
|
||||||
|
}
|
||||||
|
} else if (isUnknownCommandWithName(childNode, '\\emph', state)) {
|
||||||
|
const typeSetElement = popAncestor()
|
||||||
|
ancestor().appendChild(typeSetElement)
|
||||||
|
const textArgument = childNode.getChild('TextArgument')
|
||||||
|
const endBrace = textArgument?.getChild('CloseBrace')
|
||||||
|
if (endBrace) {
|
||||||
|
from = endBrace.to
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -360,6 +360,39 @@ describe('<CodeMirrorEditor/> in Visual mode', function () {
|
||||||
cy.get('.ol-cm-maketitle')
|
cy.get('.ol-cm-maketitle')
|
||||||
cy.get('.ol-cm-title').should('contain.html', 'Document title<br>with')
|
cy.get('.ol-cm-title').should('contain.html', 'Document title<br>with')
|
||||||
cy.get('.ol-cm-author').should('have.text', 'Author')
|
cy.get('.ol-cm-author').should('have.text', 'Author')
|
||||||
|
|
||||||
|
cy.get('.ol-cm-preamble-widget').click()
|
||||||
|
const deleteLine =
|
||||||
|
'{command}{leftArrow}{shift}{command}{rightArrow}{backspace}'
|
||||||
|
|
||||||
|
cy.get('@second-line').type(deleteLine)
|
||||||
|
cy.get('@second-line').type(
|
||||||
|
'\\title{{}formatted with \\textit{{}italic} \\textbf{{}bold} \\emph{{}emph}}'
|
||||||
|
)
|
||||||
|
cy.get('.ol-cm-title').should(
|
||||||
|
'contain.html',
|
||||||
|
'formatted with <i>italic</i> <b>bold</b> <em>emph</em>'
|
||||||
|
)
|
||||||
|
|
||||||
|
cy.get('@second-line').type(deleteLine)
|
||||||
|
cy.get('@second-line').type(
|
||||||
|
'\\title{{}title\\\\ \\textbf{{}\\textit{{}\\emph{{}formated}}} \\textit{{}only italic}}'
|
||||||
|
)
|
||||||
|
cy.get('.ol-cm-title').should(
|
||||||
|
'contain.html',
|
||||||
|
'title<br> <b><i><em>formated</em></i></b> <i>only italic</i>'
|
||||||
|
)
|
||||||
|
|
||||||
|
cy.get('@second-line').type(deleteLine)
|
||||||
|
cy.get('@second-line').type('\\title{{}Title with \\& ampersands}')
|
||||||
|
cy.get('.ol-cm-title').should(
|
||||||
|
'contain.html',
|
||||||
|
'Title with \\& ampersands'
|
||||||
|
)
|
||||||
|
|
||||||
|
cy.get('@second-line').type(deleteLine)
|
||||||
|
cy.get('@second-line').type('\\title{{}My \\LaTeX{{}} document}')
|
||||||
|
cy.get('.ol-cm-title').should('contain.html', 'My \\LaTeX{} document')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('decorates footnotes', function () {
|
it('decorates footnotes', function () {
|
||||||
|
|
Loading…
Reference in a new issue