Closed panoschal closed 9 months ago
Ye i agree with @arnog 2 many modes gonna provide many bugs it would be great if u add configuration to config that allows open only one mode many users like the multi line feature and complain that was missing regarding to other editors.
Changing the title from "Multiline support is not user-friendly" to "Feature: multiline input".
I agree this would be an interesting feature to add. Regarding the implementation, I think you would need to do the following:
root
atom be an array, with each row of the array corresponding to a line. This can leverage the existing mechanics in place to support multiline environments, with the minimum amount of code changes@arnog Benetech also votes for this feature! We played around a bit on our side with intercepting key input and trying to manipulate the underlying LaTex on the fly - but it wasnt very stable.
Maybe it's also worth considering adding the \substack{}
command for multiple lines.
Maybe it's also worth considering adding the
\substack{}
command for multiple lines.
don't work yet
Is there any way to add content across multiple lines right now?
I wonder if multiline support has been added
@elisaado Thank you for your interest in this feature.
I am not actively working on it right now, so if someone else want to pick it up, let me know.
The status of this issue will be updated once the feature has been implemented.
This is pretty big for high school math and would be very useful to have. GitHub needs a "Star issue" feature!
Pasting \begin{multiline} ... \end{multiline}
into a mathlive input doesn't work right now on the website or the latest npm version, FWIW.
I can attest \begin{multiline} ... \end{multiline}
its not working.
This is how I've seen it in other editors (like microsoft Word): each time you go to a new line (by pressing the return key), a new math container is created for that line, so in this case it would be
<math-field>f(x)=...</math-field>
<br>
<math-field>g(x)=...</math-field>
(well don't use br but some css to make each math-field span a new line)
We are using Mathlive to embed a virtual keyboard that enable users edit math path solutions,for this one mathfield,the desired output is to move the cursor to the next column on pressing enter.The same is achieved but horizontally,kindly assist.
Over 3 years since the original request was created, any updates on this issue? Can we achieve any sort of line breaking (and height increase) in latest version, either manual or by automatic wrapping?
@evyatarbh no one has expressed interest in working on or sponsoring this feature at this point. I think it would be cool, although that's quite a bit of work to implement.
Pasting
\begin{multiline} ... \end{multiline}
into a mathlive input doesn't work right now on the website or the latest npm version, FWIW.
The name of the environment is multline
not multiline
. It's the LaTeX spelling 🤷 and it's working right now.
I've been playing a little bit with this... And I've succeeded only by changing the CSS a little bit... Although this was tried out in a browser so I don't know how realistic it is.
Long story short:
The math-field object has roughly these children: ML_container > ML_content > ML_mathlive > ML_base
where all the content is rendered inside ML_base. Where each character or set of characters is a child of ML_base. What I've done is this:
display: flex
instead of display: inline-block
so that we can add this property flex-wrap: wrap;
And that's basically it... I needed to do some additional css settings like max-width, but now whenever it reaches the end of the container the next character goes into the newline.
Like I said this was hastily tested so I don't know if this can even work or if it's any good. Hope someone can approve and or disagree 👍
And short update - no it doesn't work if you just do the same thing in my CSS file because the math-field is inside the shadow DOM.
Another update. After some digging I found out you COULD style a shadow DOM element, however that element needs to have an exposed attribute part
like in this example.
If you inspect the example you can see that the example component has a wrapper div which has the exposed attribute part="box"
.
Using that attribute you can style the component like so:
example-component::part(box) {
background-color: pink;
}
However when you look at the math-field component you can see that the wrapper div has no classes and no exposed attributes (because of which you cannot style it - as far as I know for now)
@zanzlender I actually succeeded styling the textarea in a somewhat hacky way as follows - `this.mathField = new MathfieldElement();
this.mathField.shadowRoot.innerHTML +=
"";`
Some of it was needed for our E2E tests to be able to edit the inner text (I couldn't set focus to the textarea at first) and some was to conform with our UI/UX requirements.
@zanzlender it's a good start, but there would be more work needed. For example, the selection across multiple lines doesn't work: put the caret in the middle of the first line, then shift click in the middle of the second line: the entire mathfield appears selected, although only a portion of it is). Also, the cuts are not done in the right place, for examples multi-digits numbers can get cut in half.
Also, it's true that there's no way to style the "root" <div>
inside the shadow DOM. I could add a part for it, but I'm not sure why you need it?
@evyatarbh that's a creative approach, although it's not supported and might break in the future. I assume that for .ML__fieldcontainer
you meant .ML__container
? Note that this is addressable using math-field::part(container)
. The <textarea>
component inside the mathfield is not addressable. Note also that it's not always present (it's not present on touch-enabled devices, for example). And I'm not clear what you were trying to do. For E2E tests, you can set the focus on the <math-field>
directly and send it keydown events directly.
@arnog will try to think about it :) However, I would say although it may have some broken use cases for me it's better to have it like that than to have the formula disappear when it gets too big. E.g. I was trying to add a way to enter a formula inside of EditorJS by creating a plugin with Mathlive. In that case the width of the Editor can vary depending on the size of the screen, meaning that the math-field is also restrained by that. In that sense a formula that is normally visible on desktop may not be entirely visible on mobile.
And regarding the styling part... It was just my thought on how I could get around this and make it easier to style however you want. But as @evyatarbh said, it can be done without it.
You can now enter multiple lines by typing alt+return.
Great work Mr.Arno Gourdol. I'm glad to hear that!.
On Sat, Dec 9, 2023 at 4:43 AM Arno Gourdol @.***> wrote:
You can now enter multiple lines by typing alt+return.
— Reply to this email directly, view it on GitHub https://github.com/arnog/mathlive/issues/224#issuecomment-1847959223, or unsubscribe https://github.com/notifications/unsubscribe-auth/BAK3I3B66L6PGQDH26443Z3YIONJTAVCNFSM4H4NMRT2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBUG44TKOJSGIZQ . You are receiving this because you commented.Message ID: @.***>
This is great! We're going to update and do some testing soon.
@arnog Thank you for adding this feature but it not working on text mode. I am working on a exam project this library save my life. I need something like textarea behavior because question's description is long. I have solved this problem for now by adding overflow: scroll to content part but it is not good approach. please add this feature.
@molaei2000 This may help solve your problem: if you press enter, you will get a new line to continue typing (either math or text):
<script type="text/javascript">
mf = document.getElementById('math-Q1-Answer');
mf.addEventListener('beforeinput', (ev) => {
//console.log(ev.inputType, ev.target);
let imf = ev.target;
let mode = imf.mode;
if(ev.inputType === 'insertLineBreak') {
imf.executeCommand(["switchMode", "math"]);
const cursor = "thecursor";
const magic = `\\placeholder[${cursor}]{}`;
const groupstt = "\\placeholder[cursorgroupstt]{}";
const groupend = "\\placeholder[cursorgroupend]{}";
//side-effect: break text into two parts
imf.executeCommand(["insert", magic]);
imf.executeCommand(["moveToGroupStart"]);
imf.executeCommand(["insert", groupstt]);
imf.executeCommand(["moveToGroupEnd"]);
imf.executeCommand(["insert", groupend]);
let value = imf.value;
const dslash = "\\\\ ";
const displn = "\\displaylines";
if (value.includes(dslash+groupstt)||value.includes(displn+groupstt)){
value = value.replace(groupstt, " ");
value = value.replace(groupend, "");
}else{
value = value.replace(groupstt, `{${displn} `);
value = value.replace(groupend, "}");
}
value = value.replace(magic, dslash + magic);
imf.value = value;
console.log(value);
imf.executeCommand(["moveToMathfieldStart"]);
for(let ph in imf.getPrompts()){
imf.executeCommand(["moveToNextPlaceholder"]);
if (ph == cursor) break;
}
imf.executeCommand(["moveToNextChar"]);
imf.executeCommand(["deleteBackward"]);
if(mode=='text') imf.executeCommand(["switchMode", mode]);
ev.preventDefault();} });
</script>
The idea is to insert special placeholders for changing the latex value as needed, hope it helps.
For those who are interested, this example code supports both insert and delete of newlines:
<math-field id="math-Q1-Answer" style="display: block"> </math-field>
<script type="text/javascript">
mf = document.getElementById('math-Q1-Answer');
mf.addEventListener('beforeinput', (ev) => {
// console.log(ev.inputType);
let imf = ev.target;
let mode = imf.mode;
function restore_cursor(value) {
imf.value = value;
console.log(value);
imf.executeCommand(["moveToMathfieldStart"]);
for(let ph in imf.getPrompts()){
imf.executeCommand(["moveToNextPlaceholder"]);
if (ph == cursor) break;
}
imf.executeCommand(["moveToNextChar"]);
imf.executeCommand(["deleteBackward"]);
if(mode=='text') imf.executeCommand(["switchMode", mode]);
}
const cursor = "thecursor";
const magic = `\\placeholder[${cursor}]{}`;
const groupstt = "\\placeholder[cursorgroupstt]{}";
const groupend = "\\placeholder[cursorgroupend]{}";
const dslash = "\\\\ ";
const displn = "\\displaylines";
if(ev.inputType === 'insertLineBreak') {
imf.executeCommand(["switchMode", "math"]);
//side-effect: break text into two parts
imf.executeCommand(["insert", magic]);
imf.executeCommand(["moveToGroupStart"]);
imf.executeCommand(["insert", groupstt]);
imf.executeCommand(["moveToGroupEnd"]);
imf.executeCommand(["insert", groupend]);
let value = imf.value;
if (value.includes(dslash+groupstt)||value.includes(displn+groupstt)){
value = value.replace(groupstt, " ");
value = value.replace(groupend, "");
}else{
value = value.replace(groupstt, `{${displn} `);
value = value.replace(groupend, "}");
}
value = value.replace(magic, dslash + magic);
restore_cursor(value);
ev.preventDefault();
}else if(ev.inputType === 'deleteContentBackward'){
imf.executeCommand(["switchMode", "math"]);
//side-effect: break text into two parts
imf.executeCommand(["insert", magic]);
let value = imf.value;
if (value.includes(dslash+magic)){
value = value.replace(dslash+magic, magic);
ev.preventDefault();
}
restore_cursor(value);
}else if(ev.inputType === 'deleteContentForward'){
imf.executeCommand(["switchMode", "math"]);
//side-effect: break text into two parts
imf.executeCommand(["insert", magic]);
let value = imf.value;
if (value.includes(magic+dslash)){
value = value.replace(magic+dslash, magic);
ev.preventDefault();
}
restore_cursor(value);
}
});
</script>
Cheers!
Description
In order to be able to type content across multiple lines, you must add
\begin{multiline} ... \end{multiline}
(#190). I think it would be better if there were an option to specify if you want to enable the multiline environment natively. In Katex, just adding\\
without any environment, specifies a newline.Actual behavior
The problem is that if you go to mathlive.io and paste
\begin{multiline} \end{multiline}
, you must press the left arrow in order to move the cursor in the right position. This could be solved by usingmf.perform(['insert', '\\begin{multiline} #0 \\end{multiline}']);
but again, if the user clicks at the right blank side of the mathfield, they would focus outside the multiline environment.Expected Behavior
I think that allowing both multiline and regular input side to side, is of no use, so it would make sense if only one mode was allowed, for the whole mathfield, without the need for the user to manually add
\begin{multiline} ... \end{multiline}
.