Open devraj112 opened 2 weeks ago
Thanks for following the issue template! This is a good report.
I think this is behaving correctly, but the meaning of position
might be confusing. The position
property refers to the places where the cursor can be positioned: the first position, at the very beginning of the expression is position 0, and the last one, after the last matrix, is position 46.
This is a position in a tree that represents the expression. It does not correspond to an index in the LaTeX string representing this expression. The same expression can be represented in ASCII Math, and the string representation would be different, and have different indexes.
The first matrix is from position 0 to position 17.
Thank you for the response.
So, how can I get the exact position of the cursor in the latex string?
With a regex I am able to extract the matrix from the whole equation. After that I am trying to find where the cursor is, as in this case(d & x+y\\ p-q & 4^
) the second matrix but when I am using the 45(mf.position) value and checking for that in the mf.getValue("latex-extended")
then obviously position 45 is inside the first matrix(\begin{array}{lc}a+1 & b+1\\ c & \frac{1}{d}\end{array}
)
const mf = this.mathfield.nativeElement as MathfieldElement;
const cursorPosition = mf.position;
const fullLatex = mf.getValue('latex-expanded');
const matrices = [...fullLatex.matchAll(/\\begin\{array\}(.*?)\\end\{array\}/g)];
/*
[
"\begin{array}{lc}a+1 & b+1\\ c & \frac{1}{d}\end{array}",
"{lc}a+1 & b+1\\ c & \frac{1}{d}"
],
[
"\begin{array}{cc}d & x+y\\ p-q & 4\end{array}",
"{cc}d & x+y\\ p-q & 4"
]
*/
const activeMatrix = matrices.find((matrix) => {
const start = matrix.index as number;
const end = start + matrix[0].length;
return cursorPosition >= start && cursorPosition <= end;
});
With 45 as position value I am not even able to reach to the 2nd matrix.
So, What other option do I have here instead of mf.position? how to get the exact offset value?
Yes, that is as expected. Again, the "position" and "index in a LaTeX string" are completely unrelated values. Just like "position" and "index in an ASCIIMath string" or "position" and "horizontal coordinate on the screen of the cursor".
Could you explain what you are trying to do? That's not very clear from what you've described so far. If you're trying to get the LaTeX representation from the start of the expression to the current position, you can use mf.getValue([0, mf.position])
.
If you're trying to "understand" the input in the mathfield, you can use mf.expression
to get a representation of the expression as a MathJSON syntax tree, which is independent of the LaTeX representation.
Could you explain what you are trying to do?
My requirement is to align the matrix column based on user requirement("left", "right", "centre").
For instance, I have a angular popup like contextual balloon which will be taking input("left", "right", "centre") from the user for aligning the specific matrix column where the user has placed their cursor. After taking input I am just changing the format in the matrix array {lcr}.
So, for that I need the cursor position of the according to the full latex.
setAlignment(alignment: 'left' | 'center' | 'right'): void {
const mf = this.mathfield.nativeElement as MathfieldElement;
const cursorPosition = mf.position;
const fullLatex = mf.getValue('latex-expanded');
const matrices = [...fullLatex.matchAll(/\\begin\{array\}(.*?)\\end\{array\}/g)];
/*
[
"\begin{array}{lc}a+1 & b+1\\ c & \frac{1}{d}\end{array}",
"{lc}a+1 & b+1\\ c & \frac{1}{d}"
],
[
"\begin{array}{cc}d & x+y\\ p-q & 4\end{array}",
"{cc}d & x+y\\ p-q & 4"
]
*/
const activeMatrix = matrices.find((matrix) => {
const start = matrix.index as number;
const end = start + matrix[0].length;
return cursorPosition >= start && cursorPosition <= end;
});
if (activeMatrix) {
const alignmentChar = alignment === 'left' ? 'l' : alignment === 'right' ? 'r' : 'c';
const updatedLatex = this.updateMatrixAlignment(fullLatex, activeMatrix, cursorPosition, alignmentChar);
mf.setValue(updatedLatex, { format: 'latex' });
} else {
console.warn('Cursor is not in a matrix');
}
}
Here, in the above method I am extracting the matrix from the equation. And iterating the matrices until I found the matrix where the user cursor is.
updateMatrixAlignment(matrixLatex: string, targetMatrix: string, cursorPosition: number, alignmentChar: string): string {
const envRegex = /\\begin\{array\}\{([lcr]+)\}/;
const match = targetMatrix.match(envRegex);
if (match) {
let alignments = match[1].split('');
const colIndex = this.determineColumnFromCursor(targetMatrix, cursorPosition);
if (colIndex >= 0 && colIndex < alignments.length) {
alignments[colIndex] = alignmentChar;
const updatedTargetMatrix = targetMatrix.replace(envRegex, `\\begin{array}{${alignments.join('')}}`);
return matrixLatex.replace(targetMatrix, updatedTargetMatrix);
}
}
return matrixLatex;
}
Here, I am focusing on the target matrix and after that getting the column. And at the end updating the column alignment of the target matrix.
If you're trying to get the LaTeX representation from the start of the expression to the current position, you can use
mf.getValue([0, mf.position])
.
Full latex:\begin{array}{lc}a+1 & b+1\\ c & \frac{1}{d}\end{array}\sqrt{asdfasdfsdfsdf}\begin{array}{cc}d & x+y\\ p-q & 4\end{array}
output from mf.getValue([0, mf.position])
: "\begin{array}{lc}a+1 & b+1\\ c & \frac{1}{d}\end{array}\sqrt{asdfasdfsdfsdf}dx+yp-q4"
Here, why the second matrix is not coming with the full latex?
If you're trying to "understand" the input in the mathfield, you can use mf.expression to get a representation of the expression as a MathJSON syntax tree, which is independent of the LaTeX representation.
I am trying to get the position based on the full latex.
OK, thanks for the explanation. I now understand what you're trying to do.
Something important to understand is that the math-field is not a LaTeX editor. It's a math equation editor. Internally, the equation is represented as a tree. It is possible to convert LaTeX into that tree, and the tree into LaTeX or MathML or ASCIIMath. However, the editing state (position, etc...) are relative to the tree structure, not to the LaTeX, which is only generated on demand.
There is a mf.getElementInfo()
method that provides information about the current selection or caret position, however it currently does not include the information that you need (i.e. that the caret is inside a matrix). This is something I've been considering, however so it may get added in a future version.
Thank you for the clarity.
I will try to find a walkaround. Thanks for the support.
Issue
Not getting the exact caret position using mf.position.
Steps that are specific and repeatable
let mf = document.querySelector("math-field")
mf.addEventListener('selection-change', () => { console.log(mf.position, "position") //45 "position" });
console.log("latex extended", mf.getValue("latex-extented")) // \begin{array}{lc}a+1 & b+1\ c & \frac{1}{d}\end{array}\sqrt{asdfasdfsdfsdf}\begin{array}{cc}d & x+y\ p-q & 4\end{array} " console.log(mf.getValue(0, 45, "latex")) // "\begin{array}{lc}a+1 & b+1\ c & \frac{1}{d}\end{array}\sqrt{asdfasdfsdfsdf}dx+yp-q4"
console.log(mf.value.substring(0, 113)) " // \begin{array}{lc}a+1 & b+1\ c & \frac{1}{d}\end{array}\sqrt{asdfasdfsdfsdf}\begin{array}{cc}d & x+y\ p-q & 4"
This is my first post here, Sorry, If I missed following any guidelines.