I'm actually working on a markdown+mathjax editor (that also compiles to LaTeX) that has this kind of functionality. It is very buggy and not ready to be tested yet, but if you are little bit comfortable with bookmarklets (and maybe a little bit of coding experience), you could make you're own solution. The script you see below gives some very basis autocorrect functionality which you can try to customize if you want. What it does now is converting \align
to \begin{align*} \end{align*}
where the caret is correctly placed so that you can directly start typing.
- Copy the script below to the input box at this website.
- Customize the shortcuts if you want to.
- Press Get Bookmarklet
- Select the code in the output field (press ctrl+a or command+a).
- Drag the selected code to your bookmark bar (press ctrl+shift+b if you don't have a bookmark bar).
- Click the bookmarklet when you are typing a question answer at MSE.
The script:
jQuery.fn.autocorrect = function(options)
{
if ("text" != jQuery(this).attr("type") && !jQuery(this).is("textarea"))
{
return;
}
var defaults = {
corrections: {
f: "\\frac{}{}",
t: "\\text{}",
align: "\\begin{align*}\n{}\\end{align*}\n",
M22 : "\\begin{pmatrix}\n{} & \\\\\n & \n\\end{pmatrix}\n"
}
};
if (options && options.corrections)
{
options.corrections = jQuery.extend(defaults.corrections, options.corrections);
}
var opts = jQuery.extend(defaults, options);
getCaretPosition = function(oField)
{
var iCaretPos = 0;
if (document.selection)
{
var oSel = document.selection.createRange();
oSel.moveStart("character", 0 - oField.value.length);
iCaretPos = oSel.text.length;
}
else if (oField.selectionStart || oField.selectionStart == "0")
{
iCaretPos = oField.selectionStart;
}
return (iCaretPos);
}
function setCaretPosition (oField, iCaretPos)
{
if (document.selection)
{
var oSel = document.selection.createRange();
oSel.moveStart("character", 0 - oField.value.length);
oSel.moveStart("character", iCaretPos);
oSel.moveEnd("character", 0);
}
else if (oField.selectionStart || oField.selectionStart == "0")
{
oField.selectionStart = iCaretPos;
oField.selectionEnd = iCaretPos;
}
}
this.keyup(function(e)
{
if (32 != e.keyCode)
{
return;
}
var caretPosition = (getCaretPosition(this) - 1);
if (1 > caretPosition)
{
return;
}
var valueOfField = this.value;
var stringUptoCaretPosition = (valueOfField).substr(0, caretPosition);
if (" " == stringUptoCaretPosition.charAt(caretPosition - 1))
{
return;
}
var beginIndex = stringUptoCaretPosition.lastIndexOf('\\');
if (beginIndex < stringUptoCaretPosition.lastIndexOf(' '))
{
return;
}
var stringToSearch = stringUptoCaretPosition.substring(beginIndex+1);
var stringNotToSearch = stringUptoCaretPosition.substring(0, beginIndex);
if (!opts.corrections[stringToSearch])
{
return;
}
var stringToReplace = opts.corrections[stringToSearch];
stringUptoCaretPosition = stringNotToSearch+ stringToReplace;
var stringFromCaretPositionUptoEnd = (valueOfField).substr(caretPosition+1);
this.value = (stringUptoCaretPosition + stringFromCaretPositionUptoEnd);
if (stringToReplace.indexOf("{}")!=-1 )
{
setCaretPosition(this, stringUptoCaretPosition.indexOf("{}")+1);
}
else { setCaretPosition(this, stringUptoCaretPosition.length);}
});
};
$(document).ready(function()
{
$("textarea").autocorrect();
$("input").autocorrect();
});