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 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
|
||||
|
||||
node.cursor().iterate(
|
||||
|
@ -45,20 +43,21 @@ export function typesetNodeIntoElement(
|
|||
ancestor().append(
|
||||
document.createTextNode(state.sliceDoc(from, childNode.from))
|
||||
)
|
||||
from = ignoredRanges.some(
|
||||
range => range.from <= childNode.from && range.to >= childNode.from
|
||||
)
|
||||
? childNode.to
|
||||
: childNode.from
|
||||
|
||||
from = childNode.from
|
||||
}
|
||||
if (isUnknownCommandWithName(childNode, '\\textit', state)) {
|
||||
pushAncestor(document.createElement('i'))
|
||||
const argument = childNode.getChild('TextArgument')
|
||||
from = argument?.getChild('LongArg')?.from ?? childNode.to
|
||||
const endBrace = argument?.getChild('CloseBrace')
|
||||
if (endBrace) {
|
||||
ignoredRanges.push(endBrace)
|
||||
}
|
||||
const textArgument = childNode.getChild('TextArgument')
|
||||
from = textArgument?.getChild('LongArg')?.from ?? childNode.to
|
||||
} else if (isUnknownCommandWithName(childNode, '\\textbf', state)) {
|
||||
pushAncestor(document.createElement('b'))
|
||||
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)) {
|
||||
ancestor().appendChild(document.createElement('br'))
|
||||
from = childNode.to
|
||||
|
@ -69,6 +68,27 @@ export function typesetNodeIntoElement(
|
|||
if (isUnknownCommandWithName(childNode, '\\textit', 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, '\\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-title').should('contain.html', 'Document title<br>with')
|
||||
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 () {
|
||||
|
|
Loading…
Reference in a new issue