Apply prettier formatting

This commit is contained in:
Michael Weimann 2022-12-12 12:24:14 +01:00
parent 1cac306093
commit 526645c791
No known key found for this signature in database
GPG key ID: 53F535A266BB9584
1576 changed files with 65385 additions and 62478 deletions

View file

@ -39,8 +39,7 @@ export default class AutocompleteWrapperModel {
private getAutocompleterComponent: GetAutocompleterComponent,
private updateQuery: UpdateQuery,
private partCreator: PartCreator | CommandPartCreator,
) {
}
) {}
public onEscape(e: KeyboardEvent): void {
this.getAutocompleterComponent().onEscape(e);

View file

@ -34,8 +34,11 @@ export function isSlashCommand(model: EditorModel): boolean {
return true;
}
if (firstPart.text.startsWith("/") && !firstPart.text.startsWith("//")
&& (firstPart.type === Type.Plain || firstPart.type === Type.PillCandidate)) {
if (
firstPart.text.startsWith("/") &&
!firstPart.text.startsWith("//") &&
(firstPart.type === Type.Plain || firstPart.type === Type.PillCandidate)
) {
return true;
}
}
@ -81,7 +84,7 @@ export async function runSlashCommand(
const title = isServerError ? _td("Server error") : _td("Command error");
let errText;
if (typeof error === 'string') {
if (typeof error === "string") {
errText = error;
} else if ((error as ITranslatableError).translatedMessage) {
// Check for translatable errors (newTranslatableError)
@ -107,23 +110,31 @@ export async function shouldSendAnyway(commandText: string): Promise<boolean> {
// ask the user if their unknown command should be sent as a message
const { finished } = Modal.createDialog(QuestionDialog, {
title: _t("Unknown Command"),
description: <div>
<p>
{ _t("Unrecognised command: %(commandText)s", { commandText }) }
</p>
<p>
{ _t("You can use <code>/help</code> to list available commands. " +
"Did you mean to send this as a message?", {}, {
code: t => <code>{ t }</code>,
}) }
</p>
<p>
{ _t("Hint: Begin your message with <code>//</code> to start it with a slash.", {}, {
code: t => <code>{ t }</code>,
}) }
</p>
</div>,
button: _t('Send as message'),
description: (
<div>
<p>{_t("Unrecognised command: %(commandText)s", { commandText })}</p>
<p>
{_t(
"You can use <code>/help</code> to list available commands. " +
"Did you mean to send this as a message?",
{},
{
code: (t) => <code>{t}</code>,
},
)}
</p>
<p>
{_t(
"Hint: Begin your message with <code>//</code> to start it with a slash.",
{},
{
code: (t) => <code>{t}</code>,
},
)}
</p>
</div>
),
button: _t("Send as message"),
});
const [sendAnyway] = await finished;
return sendAnyway;

View file

@ -29,7 +29,7 @@ const LIST_TYPES = ["UL", "OL", "LI"];
// Escapes all markup in the given text
function escape(text: string): string {
return text.replace(/[\\*_[\]`<]|^>/g, match => `\\${match}`);
return text.replace(/[\\*_[\]`<]|^>/g, (match) => `\\${match}`);
}
// Finds the length of the longest backtick sequence in the given text, used for
@ -77,12 +77,14 @@ function parseLink(n: Node, pc: PartCreator, opts: IParseOptions): Part[] {
const resourceId = getPrimaryPermalinkEntity(href); // The room/user ID
switch (resourceId?.[0]) {
case "@": return [pc.userPill(n.textContent, resourceId)];
case "#": return [pc.roomPill(resourceId)];
case "@":
return [pc.userPill(n.textContent, resourceId)];
case "#":
return [pc.roomPill(resourceId)];
}
const children = Array.from(n.childNodes);
if (href === n.textContent && children.every(c => c.nodeType === Node.TEXT_NODE)) {
if (href === n.textContent && children.every((c) => c.nodeType === Node.TEXT_NODE)) {
return parseAtRoomMentions(n.textContent, pc, opts);
} else {
return [pc.plain("["), ...parseChildren(n, pc, opts), pc.plain(`](${href})`)];
@ -110,7 +112,7 @@ function parseCodeBlock(n: Node, pc: PartCreator, opts: IParseOptions): Part[] {
const fence = "`".repeat(Math.max(3, longestBacktickSequence(text) + 1));
const parts: Part[] = [...pc.plainWithEmoji(fence + language), pc.newline()];
text.split("\n").forEach(line => {
text.split("\n").forEach((line) => {
parts.push(...pc.plainWithEmoji(line));
parts.push(pc.newline());
});
@ -148,7 +150,7 @@ function prefixLines(parts: Part[], prefix: string, pc: PartCreator) {
function parseChildren(n: Node, pc: PartCreator, opts: IParseOptions, mkListItem?: (li: Node) => Part[]): Part[] {
let prev;
return Array.from(n.childNodes).flatMap(c => {
return Array.from(n.childNodes).flatMap((c) => {
const parsed = parseNode(c, pc, opts, mkListItem);
if (parsed.length && prev && (checkBlockNode(prev) || checkBlockNode(c))) {
if (isListChild(c)) {
@ -213,7 +215,7 @@ function parseNode(n: Node, pc: PartCreator, opts: IParseOptions, mkListItem?: (
case "LI":
return mkListItem?.(n) ?? parseChildren(n, pc, opts);
case "UL": {
const parts = parseChildren(n, pc, opts, li => [pc.plain("- "), ...parseChildren(li, pc, opts)]);
const parts = parseChildren(n, pc, opts, (li) => [pc.plain("- "), ...parseChildren(li, pc, opts)]);
if (isListChild(n)) {
prefixLines(parts, " ", pc);
}
@ -221,7 +223,7 @@ function parseNode(n: Node, pc: PartCreator, opts: IParseOptions, mkListItem?: (
}
case "OL": {
let counter = (n as HTMLOListElement).start ?? 1;
const parts = parseChildren(n, pc, opts, li => {
const parts = parseChildren(n, pc, opts, (li) => {
const parts = [pc.plain(`${counter}. `), ...parseChildren(li, pc, opts)];
counter++;
return parts;
@ -236,12 +238,10 @@ function parseNode(n: Node, pc: PartCreator, opts: IParseOptions, mkListItem?: (
// Math nodes are translated back into delimited latex strings
if ((n as Element).hasAttribute("data-mx-maths")) {
const delims = SdkConfig.get().latex_maths_delims;
const delimLeft = (n.nodeName === "SPAN") ?
delims?.inline?.left ?? "\\(" :
delims?.display?.left ?? "\\[";
const delimRight = (n.nodeName === "SPAN") ?
delims?.inline?.right ?? "\\)" :
delims?.display?.right ?? "\\]";
const delimLeft =
n.nodeName === "SPAN" ? delims?.inline?.left ?? "\\(" : delims?.display?.left ?? "\\[";
const delimRight =
n.nodeName === "SPAN" ? delims?.inline?.right ?? "\\)" : delims?.display?.right ?? "\\]";
const tex = (n as Element).getAttribute("data-mx-maths");
return pc.plainWithEmoji(`${delimLeft}${tex}${delimRight}`);
@ -268,11 +268,7 @@ function parseHtmlMessage(html: string, pc: PartCreator, opts: IParseOptions): P
return parts;
}
export function parsePlainTextMessage(
body: string,
pc: PartCreator,
opts: IParseOptions,
): Part[] {
export function parsePlainTextMessage(body: string, pc: PartCreator, opts: IParseOptions): Part[] {
const lines = body.split(/\r\n|\r|\n/g); // split on any new-line combination not just \n, collapses \r\n
return lines.reduce((parts, line, i) => {
if (opts.isQuotedMessage) {

View file

@ -187,16 +187,8 @@ function getTextNodeValue(node: Node): string {
}
export function getRangeForSelection(editor: HTMLDivElement, model: EditorModel, selection: Selection): Range {
const focusOffset = getSelectionOffsetAndText(
editor,
selection.focusNode,
selection.focusOffset,
).offset;
const anchorOffset = getSelectionOffsetAndText(
editor,
selection.anchorNode,
selection.anchorOffset,
).offset;
const focusOffset = getSelectionOffsetAndText(editor, selection.focusNode, selection.focusOffset).offset;
const anchorOffset = getSelectionOffsetAndText(editor, selection.anchorNode, selection.anchorOffset).offset;
const focusPosition = focusOffset.asPosition(model);
const anchorPosition = anchorOffset.asPosition(model);
return model.startRange(focusPosition, anchorPosition);

View file

@ -53,9 +53,8 @@ export default class HistoryManager {
// so we can't push the state before something happened.
// not ideal but changing this would be harder to fit cleanly into
// the editor model.
const isNonBulkInput = inputType === "insertText" ||
inputType === "deleteContentForward" ||
inputType === "deleteContentBackward";
const isNonBulkInput =
inputType === "insertText" || inputType === "deleteContentForward" || inputType === "deleteContentBackward";
if (diff && isNonBulkInput) {
if (diff.added) {
this.addedSinceLastPush = true;
@ -88,7 +87,7 @@ export default class HistoryManager {
private pushState(model: EditorModel, caret: Caret) {
// remove all steps after current step
while (this.currentIndex < (this.stack.length - 1)) {
while (this.currentIndex < this.stack.length - 1) {
this.stack.pop();
}
const parts = model.serializeParts();
@ -132,7 +131,7 @@ export default class HistoryManager {
}
public canRedo(): boolean {
return this.currentIndex < (this.stack.length - 1);
return this.currentIndex < this.stack.length - 1;
}
// returns state that should be applied to model

View file

@ -91,7 +91,7 @@ export default class EditorModel {
}
public clone(): EditorModel {
const clonedParts = this.parts.map(p => this.partCreator.deserializePart(p.serialize()));
const clonedParts = this.parts.map((p) => this.partCreator.deserializePart(p.serialize()));
return new EditorModel(clonedParts, this._partCreator, this.updateCallback);
}
@ -146,7 +146,7 @@ export default class EditorModel {
}
public serializeParts(): SerializedPart[] {
return this._parts.map(p => p.serialize());
return this._parts.map((p) => p.serialize());
}
private diff(newValue: string, inputType: string, caret: DocumentOffset): IDiff {
@ -160,7 +160,7 @@ export default class EditorModel {
}
public reset(serializedParts: SerializedPart[], caret?: Caret, inputType?: string): void {
this._parts = serializedParts.map(p => this._partCreator.deserializePart(p));
this._parts = serializedParts.map((p) => this._partCreator.deserializePart(p));
if (!caret) {
caret = this.getPositionAtEnd();
}
@ -218,7 +218,7 @@ export default class EditorModel {
private getTransformAddedLen(newPosition: DocumentPosition, inputType: string, diff: IDiff): number {
const result = this.transformCallback(newPosition, inputType, diff);
return Number.isFinite(result) ? result as number : 0;
return Number.isFinite(result) ? (result as number) : 0;
}
private setActivePart(pos: DocumentPosition, canOpenAutoComplete: boolean): Promise<void> {
@ -397,11 +397,11 @@ export default class EditorModel {
public positionForOffset(totalOffset: number, atPartEnd = false): DocumentPosition {
let currentOffset = 0;
const index = this._parts.findIndex(part => {
const index = this._parts.findIndex((part) => {
const partLen = part.text.length;
if (
(atPartEnd && (currentOffset + partLen) >= totalOffset) ||
(!atPartEnd && (currentOffset + partLen) > totalOffset)
(atPartEnd && currentOffset + partLen >= totalOffset) ||
(!atPartEnd && currentOffset + partLen > totalOffset)
) {
return true;
}

View file

@ -18,8 +18,7 @@ import EditorModel from "./model";
import DocumentPosition from "./position";
export default class DocumentOffset {
constructor(public offset: number, public readonly atNodeEnd: boolean) {
}
constructor(public offset: number, public readonly atNodeEnd: boolean) {}
public asPosition(model: EditorModel): DocumentPosition {
return model.positionForOffset(this.offset, this.atNodeEnd);

View file

@ -17,7 +17,7 @@ limitations under the License.
import Range from "./range";
import { Part, Type } from "./parts";
import { Formatting } from "../components/views/rooms/MessageComposerFormatBar";
import { longestBacktickSequence } from './deserialize';
import { longestBacktickSequence } from "./deserialize";
/**
* Some common queries and transformations on the editor model
@ -109,11 +109,13 @@ export function replaceRangeAndAutoAdjustCaret(
const distanceFromEnd = range.length - relativeOffset;
// Handle edge case where the caret is located within the suffix or prefix
if (rangeHasFormatting) {
if (relativeOffset < prefixLength) { // Was the caret at the left format string?
if (relativeOffset < prefixLength) {
// Was the caret at the left format string?
replaceRangeAndMoveCaret(range, newParts, -(range.length - 2 * suffixLength));
return;
}
if (distanceFromEnd < suffixLength) { // Was the caret at the right format string?
if (distanceFromEnd < suffixLength) {
// Was the caret at the right format string?
replaceRangeAndMoveCaret(range, newParts, 0, true);
return;
}
@ -122,7 +124,10 @@ export function replaceRangeAndAutoAdjustCaret(
model.transform(() => {
const offsetDirection = Math.sign(range.replace(newParts)); // Compensates for shrinkage or expansion
const atEnd = distanceFromEnd === suffixLength;
return lastStartingPosition.asOffset(model).add(offsetDirection * prefixLength, atEnd).asPosition(model);
return lastStartingPosition
.asOffset(model)
.add(offsetDirection * prefixLength, atEnd)
.asPosition(model);
});
}
@ -180,12 +185,10 @@ export function formatRangeAsCode(range: Range): void {
const { model, parts } = range;
const { partCreator } = model;
const hasBlockFormatting = (range.length > 0)
&& range.text.startsWith("```")
&& range.text.endsWith("```")
&& range.text.includes('\n');
const hasBlockFormatting =
range.length > 0 && range.text.startsWith("```") && range.text.endsWith("```") && range.text.includes("\n");
const needsBlockFormatting = parts.some(p => p.type === Type.Newline);
const needsBlockFormatting = parts.some((p) => p.type === Type.Newline);
if (hasBlockFormatting) {
parts.shift();
@ -199,9 +202,7 @@ export function formatRangeAsCode(range: Range): void {
if (!rangeStartsAtBeginningOfLine(range)) {
parts.unshift(partCreator.newline());
}
parts.push(
partCreator.newline(),
partCreator.plain("```"));
parts.push(partCreator.newline(), partCreator.plain("```"));
if (!rangeEndsAtEndOfLine(range)) {
parts.push(partCreator.newline());
}
@ -232,8 +233,8 @@ export function formatRangeAsLink(range: Range, text?: string) {
}
// parts helper methods
const isBlank = part => !part.text || !/\S/.test(part.text);
const isNL = part => part.type === Type.Newline;
const isBlank = (part) => !part.text || !/\S/.test(part.text);
const isNL = (part) => part.type === Type.Newline;
export function toggleInlineFormat(range: Range, prefix: string, suffix = prefix): void {
const { model, parts } = range;
@ -277,9 +278,8 @@ export function toggleInlineFormat(range: Range, prefix: string, suffix = prefix
const base = startIdx + offset;
const index = endIdx + offset;
const isFormatted = (index - base > 0) &&
parts[base].text.startsWith(prefix) &&
parts[index - 1].text.endsWith(suffix);
const isFormatted =
index - base > 0 && parts[base].text.startsWith(prefix) && parts[index - 1].text.endsWith(suffix);
if (isFormatted) {
// remove prefix and suffix formatting string

View file

@ -21,11 +21,7 @@ import { MatrixClient } from "matrix-js-sdk/src/client";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { Room } from "matrix-js-sdk/src/models/room";
import AutocompleteWrapperModel, {
GetAutocompleterComponent,
UpdateCallback,
UpdateQuery,
} from "./autocomplete";
import AutocompleteWrapperModel, { GetAutocompleterComponent, UpdateCallback, UpdateQuery } from "./autocomplete";
import { unicodeToShortcode } from "../HtmlUtils";
import * as Avatar from "../Avatar";
import defaultDispatcher from "../dispatcher/dispatcher";
@ -117,7 +113,7 @@ abstract class BasePart {
public remove(offset: number, len: number): string | undefined {
// validate
const strWithRemoval = this.text.slice(0, offset) + this.text.slice(offset + len);
for (let i = offset; i < (len + offset); ++i) {
for (let i = offset; i < len + offset; ++i) {
const chr = this.text.charAt(i);
if (!this.acceptsRemoval(i, chr)) {
return strWithRemoval;
@ -216,8 +212,7 @@ abstract class PlainBasePart extends BasePart {
// or split if the previous character is a space
// or if it is a + and this is a :
return this._text[offset - 1] !== " " &&
(this._text[offset - 1] !== "+" || chr !== ":");
return this._text[offset - 1] !== " " && (this._text[offset - 1] !== "+" || chr !== ":");
}
return true;
}
@ -262,7 +257,7 @@ export abstract class PillPart extends BasePart implements IPillPart {
}
protected acceptsRemoval(position: number, chr: string): boolean {
return position !== 0; //if you remove initial # or @, pill should become plain
return position !== 0; //if you remove initial # or @, pill should become plain
}
public toDOMNode(): Node {
@ -291,10 +286,12 @@ export abstract class PillPart extends BasePart implements IPillPart {
}
public canUpdateDOMNode(node: HTMLElement): boolean {
return node.nodeType === Node.ELEMENT_NODE &&
node.nodeName === "SPAN" &&
node.childNodes.length === 1 &&
node.childNodes[0].nodeType === Node.TEXT_NODE;
return (
node.nodeType === Node.ELEMENT_NODE &&
node.nodeName === "SPAN" &&
node.childNodes.length === 1 &&
node.childNodes[0].nodeType === Node.TEXT_NODE
);
}
// helper method for subclasses
@ -519,12 +516,7 @@ class PillCandidatePart extends PlainBasePart implements IPillCandidatePart {
export function getAutoCompleteCreator(getAutocompleterComponent: GetAutocompleterComponent, updateQuery: UpdateQuery) {
return (partCreator: PartCreator) => {
return (updateCallback: UpdateCallback) => {
return new AutocompleteWrapperModel(
updateCallback,
getAutocompleterComponent,
updateQuery,
partCreator,
);
return new AutocompleteWrapperModel(updateCallback, getAutocompleterComponent, updateQuery, partCreator);
};
};
}
@ -615,8 +607,7 @@ export class PartCreator {
room = this.client.getRoom(roomId || alias);
} else {
room = this.client.getRooms().find((r) => {
return r.getCanonicalAlias() === alias ||
r.getAltAliases().includes(alias);
return r.getCanonicalAlias() === alias || r.getAltAliases().includes(alias);
});
}
return new RoomPillPart(alias, room ? room.name : alias, room);

View file

@ -27,8 +27,7 @@ type Callback = (part: Part, startIdx: number, endIdx: number) => void;
export type Predicate = (index: number, offset: number, part: Part) => boolean;
export default class DocumentPosition implements IPosition {
constructor(public readonly index: number, public readonly offset: number) {
}
constructor(public readonly index: number, public readonly offset: number) {}
public compare(otherPos: DocumentPosition): number {
if (this.index === otherPos.index) {
@ -73,7 +72,7 @@ export default class DocumentPosition implements IPosition {
offset += 1;
}
// end reached
if (index === (parts.length - 1)) {
if (index === parts.length - 1) {
return new DocumentPosition(index, offset);
} else {
index += 1;

View file

@ -150,15 +150,18 @@ function reconcileEmptyLine(lineContainer: HTMLElement): void {
}
export function renderModel(editor: HTMLDivElement, model: EditorModel): void {
const lines = model.parts.reduce((linesArr, part) => {
if (part.type === Type.Newline) {
linesArr.push([]);
} else {
const lastLine = linesArr[linesArr.length - 1];
lastLine.push(part);
}
return linesArr;
}, [[]]);
const lines = model.parts.reduce(
(linesArr, part) => {
if (part.type === Type.Newline) {
linesArr.push([]);
} else {
const lastLine = linesArr[linesArr.length - 1];
lastLine.push(part);
}
return linesArr;
},
[[]],
);
lines.forEach((parts, i) => {
// find first (and remove anything else) div without className
// (as browsers insert these in contenteditable) line container

View file

@ -15,16 +15,16 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { encode } from 'html-entities';
import cheerio from 'cheerio';
import { encode } from "html-entities";
import cheerio from "cheerio";
import escapeHtml from "escape-html";
import Markdown from '../Markdown';
import Markdown from "../Markdown";
import { makeGenericPermalink } from "../utils/permalinks/Permalinks";
import EditorModel from "./model";
import SettingsStore from '../settings/SettingsStore';
import SdkConfig from '../SdkConfig';
import { Type } from './parts';
import SettingsStore from "../settings/SettingsStore";
import SdkConfig from "../SdkConfig";
import { Type } from "./parts";
export function mdSerialize(model: EditorModel): string {
return model.parts.reduce((html, part) => {
@ -40,11 +40,17 @@ export function mdSerialize(model: EditorModel): string {
case Type.RoomPill:
// Here we use the resourceId for compatibility with non-rich text clients
// See https://github.com/vector-im/element-web/issues/16660
return html +
`[${part.resourceId.replace(/[[\\\]]/g, c => "\\" + c)}](${makeGenericPermalink(part.resourceId)})`;
return (
html +
`[${part.resourceId.replace(/[[\\\]]/g, (c) => "\\" + c)}](${makeGenericPermalink(
part.resourceId,
)})`
);
case Type.UserPill:
return html +
`[${part.text.replace(/[[\\\]]/g, c => "\\" + c)}](${makeGenericPermalink(part.resourceId)})`;
return (
html +
`[${part.text.replace(/[[\\\]]/g, (c) => "\\" + c)}](${makeGenericPermalink(part.resourceId)})`
);
}
}, "");
}
@ -59,7 +65,7 @@ export function htmlSerializeIfNeeded(
{ forceHTML = false, useMarkdown = true }: ISerializeOpts = {},
): string {
if (!useMarkdown) {
return escapeHtml(textSerialize(model)).replace(/\n/g, '<br/>');
return escapeHtml(textSerialize(model)).replace(/\n/g, "<br/>");
}
const md = mdSerialize(model);
@ -71,10 +77,10 @@ export function htmlSerializeFromMdIfNeeded(md: string, { forceHTML = false } =
const orig = md;
if (SettingsStore.getValue("feature_latex_maths")) {
const patternNames = ['tex', 'latex'];
const patternTypes = ['display', 'inline'];
const patternNames = ["tex", "latex"];
const patternTypes = ["display", "inline"];
const patternDefaults = {
"tex": {
tex: {
// detect math with tex delimiters, inline: $...$, display $$...$$
// preferably use negative lookbehinds, not supported in all major browsers:
// const displayPattern = "^(?<!\\\\)\\$\\$(?![ \\t])(([^$]|\\\\\\$)+?)\\$\\$$";
@ -83,7 +89,7 @@ export function htmlSerializeFromMdIfNeeded(md: string, { forceHTML = false } =
// conditions for display math detection $$...$$:
// - pattern starts and ends on a new line
// - left delimiter ($$) is not escaped by backslash
"display": "(^)\\$\\$(([^$]|\\\\\\$)+?)\\$\\$$",
display: "(^)\\$\\$(([^$]|\\\\\\$)+?)\\$\\$$",
// conditions for inline math detection $...$:
// - pattern starts at beginning of line, follows whitespace character or punctuation
@ -91,32 +97,31 @@ export function htmlSerializeFromMdIfNeeded(md: string, { forceHTML = false } =
// - left and right delimiters ($) are not escaped by backslashes
// - left delimiter is not followed by whitespace character
// - right delimiter is not prefixed with whitespace character
"inline":
"(^|\\s|[.,!?:;])(?!\\\\)\\$(?!\\s)(([^$\\n]|\\\\\\$)*([^\\\\\\s\\$]|\\\\\\$)(?:\\\\\\$)?)\\$",
inline: "(^|\\s|[.,!?:;])(?!\\\\)\\$(?!\\s)(([^$\\n]|\\\\\\$)*([^\\\\\\s\\$]|\\\\\\$)(?:\\\\\\$)?)\\$",
},
"latex": {
latex: {
// detect math with latex delimiters, inline: \(...\), display \[...\]
// conditions for display math detection \[...\]:
// - pattern starts and ends on a new line
// - pattern is not empty
"display": "(^)\\\\\\[(?!\\\\\\])(.*?)\\\\\\]$",
display: "(^)\\\\\\[(?!\\\\\\])(.*?)\\\\\\]$",
// conditions for inline math detection \(...\):
// - pattern starts at beginning of line or is not prefixed with backslash
// - pattern is not empty
"inline": "(^|[^\\\\])\\\\\\((?!\\\\\\))(.*?)\\\\\\)",
inline: "(^|[^\\\\])\\\\\\((?!\\\\\\))(.*?)\\\\\\)",
},
};
patternNames.forEach(function(patternName) {
patternTypes.forEach(function(patternType) {
patternNames.forEach(function (patternName) {
patternTypes.forEach(function (patternType) {
// get the regex replace pattern from config or use the default
const pattern = (((SdkConfig.get("latex_maths_delims") ||
{})[patternType] || {})["pattern"] || {})[patternName] ||
const pattern =
(((SdkConfig.get("latex_maths_delims") || {})[patternType] || {})["pattern"] || {})[patternName] ||
patternDefaults[patternName][patternType];
md = md.replace(RegExp(pattern, "gms"), function(m, p1, p2) {
md = md.replace(RegExp(pattern, "gms"), function (m, p1, p2) {
const p2e = encode(p2);
switch (patternType) {
case "display":
@ -130,7 +135,9 @@ export function htmlSerializeFromMdIfNeeded(md: string, { forceHTML = false } =
// make sure div tags always start on a new line, otherwise it will confuse
// the markdown parser
md = md.replace(/(.)<div/g, function(m, p1) { return `${p1}\n<div`; });
md = md.replace(/(.)<div/g, function (m, p1) {
return `${p1}\n<div`;
});
}
const parser = new Markdown(md);
@ -156,13 +163,13 @@ export function htmlSerializeFromMdIfNeeded(md: string, { forceHTML = false } =
// since maths delimiters are handled before Markdown,
// code blocks could contain mangled content.
// replace code blocks with original content
phtmlOrig('code').each(function(i) {
phtml('code').eq(i).text(phtmlOrig('code').eq(i).text());
phtmlOrig("code").each(function (i) {
phtml("code").eq(i).text(phtmlOrig("code").eq(i).text());
});
// add fallback output for latex math, which should not be interpreted as markdown
phtml('div, span').each(function(i, e) {
const tex = phtml(e).attr('data-mx-maths');
phtml("div, span").each(function (i, e) {
const tex = phtml(e).attr("data-mx-maths");
if (tex) {
phtml(e).html(`<code>${tex}</code>`);
}
@ -207,7 +214,7 @@ export function startsWith(model: EditorModel, prefix: string, caseSensitive = t
const firstPart = model.parts[0];
// part type will be "plain" while editing,
// and "command" while composing a message.
let text = firstPart?.text || '';
let text = firstPart?.text || "";
if (!caseSensitive) {
prefix = prefix.toLowerCase();
text = text.toLowerCase();