Path: blob/main/assets/scripts/runlatex.js
3170 views
// runlatex.js for TeXLive.net and Overleaf1// Copyright 2020 2021 David Carlisle2// MIT Licence34// set here but local versions can be redefined after5// loading this file67// runlatex configuration object8var runlatex={}910runlatex.texts ={11"Open in Overleaf": "Open in Overleaf",12"TeXLive.net": "run at TeXLive.net", // or "run latex" or whatever13"Delete Output": "Delete Output",14"Compiling PDF": "Compiling PDF",15// The following not used on learnlatex.org16"edit": "edit",17"copy": "copy",18"Added Code": "Added code",19"End Added Code": "End Added code",20"Top Caption": "Edit and run this example:"21}2223runlatex.editorlines=100;24runlatex.adddefaultpreamble=false;25runlatex.adddefaultengine=false;26runlatex.usecaptions=false;27runlatex.minrunlines=0;28runlatex.completionsURI="";2930// debug by using https://httpbin.org/post31// set to null to omit from interface32runlatex.latexcgiURI="https://texlive.net/cgi-bin/latexcgi";33runlatex.overleafURI="https://www.overleaf.com/docs";3435// per page setup36runlatex.preincludes={};3738// Disable all use of cookies39// No cookies are set by this file even when true.40runlatex.usecookies=true;4142// end of configuration4344var editors=[];4546const noeditregex = /^\s*[/%#\*]+ *!TEX.*[^a-zA-Z]noedit *(\n|$)/i;47const norunregex = /^\s*([/%#\*]+ *!TEX.*[^a-zA-Z]none *|[^% \t\\][^\\]*)(\n|$)/i;48const commentregex = / %.*/;49const engineregex = /% *!TEX.*[^a-zA-Z](((pdf|xe|lua|u?p)?latex(-dev)?)|context|(pdf|xe|lua|u?p)?tex) *\n/i;50const returnregex = /% *!TEX.*[^a-zA-Z](pdfjs|pdf|log|make4ht|latexml|lwarp) *\n/i;51const makeindexregex = /% *!TEX.*[^a-zA-Z]makeindex( [a-z0-9\.\- ]*)\n/ig;5253var packageregex = [54[ /\\includegraphics/, "\\usepackage[demo]{graphicx}\n"],55[ /\\begin{equation|align|gather|flalign/,"\\usepackage{amsmath}\n" ],56[ /tikz|pgf/, "\\usepackage{tikz}\n" ],57[ /fancy/, "\\usepackage{fancyhdr}\n" ],58[ /addplot|axis/, "\\usepackage{pgfplots}\n" ],59[ /hyper|href|bookmark|\\url/, "\\usepackage{hyperref}\n" ],60[ /\\newcolumntype/, "\\usepackage{array}\n" ],61[ /listing/, "\\usepackage{listings}\n" ],62[ /\\blind/, "\\usepackage{blindtext}\n" ],63[ /\\lipsum/, "\\usepackage{lipsum}\n" ],64[ /color/, "\\usepackage{xcolor}\n" ],65[ /pspicture/, "\\usepackage{pstricks}\n" ]66];676869var latexcompetions="";707172var customCompleter = {73getCompletions: function(editor, session, pos, prefix, callback) {74var startToken = session.getTokenAt(pos.row, pos.column).value;75if (startToken.startsWith("\\")){76var cmplts=[];77var s=0;78for (let pkg in latexcompletions) {79var cs=latexcompletions[pkg];80s=s-1;81for(let i=0;i<cs.length;i++){82if(cs[i].startsWith(prefix)){83cmplts.push({name: cs[i], value:cs[i],score: s, meta: pkg});84}85}86}87callback(null, cmplts);88} else {89callback(null, []);90return91}92}93}9495function llexamples() {96if(runlatex.completionsURI != ""){97let request = new XMLHttpRequest();98request.open('GET', runlatex.completionsURI);99request.responseType = 'json';100request.onload = function() {101latexcompletions = request.response;102}103request.send();104}105var p = document.getElementsByTagName("pre");106var editor;107var acemode;108for(var i=0;i<p.length;i++) {109acemode="ace/mode/latex";110p[i].setAttribute("id","pre" + i);111var pretext=p[i].innerText;112if(!pretext.match(noeditregex) && !p[i].classList.contains('noedit')) {113if((runlatex.adddefaultpreamble &&114(pretext.match(norunregex) || (pretext.match(/\n[^\n]/g) || '').length + 1 < runlatex.minrunlines )) ||115(!runlatex.adddefaultpreamble &&116pretext.indexOf("\\documentclass") == -1 && !pretext.match(engineregex)) ||117p[i].classList.contains('norun')) {118if(pretext.match(norunregex)) {119acemode="ace/mode/text";120}121} else {122// caption123if(runlatex.usecaptions && runlatex.texts["Top Caption"]) {124var cpt = document.createElement("div");125cpt.setAttribute("class",'lltopcaption');126cpt.innerHTML=runlatex.texts["Top Caption"];127p[i].parentNode.insertBefore(cpt, p[i]);128}129// space130var s = document.createElement("div");131s.setAttribute("class",'ace-spacer');132p[i].parentNode.insertBefore(s, p[i].nextSibling);133if(runlatex.latexcgiURI){134// texlive.net135var r = document.createElement("button");136r.innerText=runlatex.texts["TeXLive.net"];137r.setAttribute("class","llbutton");138r.setAttribute("onclick",'latexcgi("pre' + i + '")');139r.setAttribute("id","lo-pre" + i);140p[i].parentNode.insertBefore(r, p[i].nextSibling);141var f2=document.createElement("span");142f2.innerHTML="<form style=\"display:none\" id=\"form2-pre" + i +143"\" name=\"form2-pre" + i +144"\" enctype=\"multipart/form-data\" action=\"" +145runlatex.latexcgiURI +146"\" method=\"post\" target=\"pre" + i +147"ifr\"></form>";148p[i].parentNode.insertBefore(f2, p[i].nextSibling);149}150if(runlatex.overleafURI){151// overleaf152var o = document.createElement("button");153o.innerText=runlatex.texts["Open in Overleaf"];154o.setAttribute("class","llbutton");155o.setAttribute("onclick",'openinoverleaf("pre' + i + '")');156p[i].parentNode.insertBefore(o, p[i].nextSibling);157var f=document.createElement("span");158f.innerHTML="<form style=\"display:none\" id=\"form-pre" + i +159"\" action=\"" +160runlatex.overleafURI +161"\" method=\"post\" target=\"_blank\"></form>";162p[i].parentNode.insertBefore(f, p[i].nextSibling);163}164}165if(runlatex.adddefaultpreamble) {166pretext=pretext.replace(/^[ \t\u00A0]+$/gm,'');167}168p[i].textContent=pretext.replace(/\s+$/,'');169p[i].style.height="1em"; // force redisplay in Opera zoom170ace.config.set('basePath', 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12') ;171editor = ace.edit(p[i]);172editor.setTheme(rlacetheme);173editor.getSession().setMode(acemode);174editor.setOption("minLines",runlatex);175editor.setOption("maxLines",runlatex.editorlines);176editor.setShowPrintMargin(false);177if(runlatex.completionsURI != ""){178langTools=ace.require("ace/ext/language_tools");179langTools.setCompleters([customCompleter]);180editor.setOptions({181enableBasicAutocompletion: true,182enableLiveAutocompletion: true183});184}185editor.resize();186editors["pre" + i]=editor;187}188}189}190191192function addinput(f,n,v) {193var inp=document.createElement("input");194inp.setAttribute("type","text");195inp.setAttribute("name",n);196inp.value =encodeURIComponent(v);197f.appendChild(inp);198}199200function addinputnoenc(f,n,v) {201var inp=document.createElement("input");202inp.setAttribute("type","text");203inp.setAttribute("name",n);204inp.value =v;205f.appendChild(inp);206}207208function addtextarea(f,n,v) {209var inp=document.createElement("textarea");210inp.setAttribute("type","text");211inp.setAttribute("name",n);212inp.textContent=v;213f.appendChild(inp);214}215216function openinoverleaf(nd) {217var fm = document.getElementById('form-' + nd);218fm.innerHTML="";219var p = document.getElementById(nd);220var t = editors[nd].getValue();221222var engv=rldefaultengine;223var eng=t.match(engineregex);224if(runlatex.adddefaultpreamble) {225if(t.indexOf("\\documentclass") == -1 && ( eng == null)) {226t=generatepreamble(t,editors[nd]);227}228}229if(eng != null) {230engv=eng[1].toLowerCase();231if(engv == "pdftex" || engv == "luatex" || engv == "xetex" || engv == "ptex" || engv == "uptex") {232addinput(fm,"main_document","document.tex");233}234}235addinput(fm,"encoded_snip[]","\n" + t);236addinput(fm,"snip_name[]","document.tex");237if(typeof(runlatex.preincludes) == "object") {238if(typeof(runlatex.preincludes[nd]) == "object") {239var incl=runlatex.preincludes[nd];240for(prop in incl) {241if(editors[prop]==null) {242addinput(fm,"encoded_snip[]",document.getElementById(prop).textContent);243} else {244addinput(fm,"encoded_snip[]",editors[prop].getValue());245}246addinput(fm,"snip_name[]",incl[prop]);247}248}249}250if(eng != null) {251if(engv.indexOf("platex") != -1 || engv.indexOf("ptex") != -1 || engv=="tex") {252addinput(fm,"encoded_snip[]","$latex = '" + engv + "';\n$bibtex = 'pbibtex';\n$dvipdf = 'dvipdfmx %O -o %D %S';");253addinput(fm,"snip_name[]","latexmkrc");254engv="latex_dvipdf";255} else if(engv == "pdftex" || engv == "luatex" || engv == "xetex") {256addinput(fm,"encoded_snip[]","$pdflatex = '" + engv + "';");257addinput(fm,"snip_name[]","latexmkrc");258engv=rldefaultengine;259}260261}262addinput(fm,"engine",engv);263fm.submit();264}265266function copytoclipboard(nd){267var p = document.getElementById(nd);268var nn=document.createElement("textarea");269nn.value=p.innerText;270document.body.appendChild(nn);271nn.select();272document.execCommand("copy");273document.body.removeChild(nn);274}275276277function allowedit(nd){278var p = document.getElementById(nd);279p.contentEditable="true";280p.setAttribute("spellcheck","false");281p.innerHTML=p.innerText;282p.style.border="solid thin green";283}284285function deleteoutput(nd){286var b = document.getElementById('del-' + nd);287var ifr = document.getElementById(nd + 'ifr');288b.parentNode.removeChild(b);289ifr.parentNode.removeChild(ifr);290}291292function generatepreamble(t,e) {293e.navigateFileStart();294if(t.match(/koma|KOMA|addsec|\\scr|scrheadings/)){295e.insert("\n% " + runlatex.texts["Added Code"] + "\n\\documentclass{scrartcl}\n");296} else {297e.insert("\n% " + runlatex.texts["Added Code"] + "\n\\documentclass{article}\n");298}299for(var i=0;i<packageregex.length; i++){300if(t.match(packageregex[i][0])) e.insert(packageregex[i][1]);301}302e.insert("\n\\begin{document}\n% " + runlatex.texts["End Added Code"] + "\n\n");303e.navigateFileEnd();304e.insert("\n\n% " +305runlatex.texts["Added Code"] +306"\n\\end{document}\n% " +307runlatex.texts["End Added Code"] +308"\n");309return e.getValue();310}311312function defaultengine(t) {313if ((t.indexOf("\\usepackage{lua") !== -1) || (t.indexOf("\\directlua") !== -1) ){314return "lualatex";315} else if (t.indexOf("fontspec") !== -1) {316return "xelatex";317} else if (t.indexOf("pstricks") !==-1) {318return "latex";319} else return rldefaultengine;320}321322function latexcgi(nd) {323var fm = document.getElementById('form2-' + nd);324fm.innerHTML="";325var p = document.getElementById(nd);326var t = editors[nd].getValue();327var engv=rldefaultengine;328var eng=t.match(engineregex);329if(runlatex.adddefaultpreamble) {330if(t.indexOf("\\documentclass") == -1 && ( eng == null)) {331t=generatepreamble(t,editors[nd]);332}333}334addtextarea(fm,"filecontents[]",t);335addinputnoenc(fm,"filename[]","document.tex");336if(typeof(runlatex.preincludes) == "object") {337if(typeof(runlatex.preincludes[nd]) == "object") {338var incl=runlatex.preincludes[nd];339for(prop in incl) {340if(editors[prop]==null) {341addtextarea(fm,"filecontents[]",document.getElementById(prop).textContent);342} else {343addtextarea(fm,"filecontents[]",editors[prop].getValue());344}345addinputnoenc(fm,"filename[]",incl[prop]);346}347}348}349if(eng != null) {350engv=eng[1].toLowerCase();351} else if(runlatex.adddefaultengine) {352engv=defaultengine(t);353}354addinput(fm,"engine",engv);355var rtn = t.match(returnregex);356var rtnv = "";357if(rtn == null) {358// ES6 / IE359if (typeof Symbol == "undefined") {360addinput(fm,"return","pdf");361} else {362addinput(fm,"return",rldefaultreturn);363}364} else {365rtnv=rtn[1].toLowerCase();366addinput(fm,"return",rtnv);367}368var mki = makeindexregex.exec(t);369while (mki != null) {370addinputnoenc(fm,"makeindex[]",mki[1]);371mki = makeindexregex.exec(t);372}373var b = document.getElementById('lo-' + nd);374var ifr= document.getElementById(nd + "ifr");375if(ifr == null) {376ifr=document.createElement("iframe");377ifr.setAttribute("width","100%");378ifr.setAttribute("height","500em");379ifr.setAttribute("id",nd + "ifr");380ifr.setAttribute("name",nd + "ifr");381p.parentNode.insertBefore(ifr, b.nextSibling);382d=document.createElement("button");383d.innerText=runlatex.texts["Delete Output"];384d.setAttribute("class","llbutton");385d.setAttribute("id","del-" + nd);386d.setAttribute("onclick",'deleteoutput("' + nd + '")');387p.parentNode.insertBefore(d, b.nextSibling);388}389var loading=document.createElement("div");390loading.id=nd+"load";391loading.textContent=runlatex.texts["Compiling PDF"] + " . . .";392p.parentNode.insertBefore(loading, ifr);393// scroll only if really close to the bottom394var rect = b.getBoundingClientRect();395if(document.documentElement.clientHeight - rect.bottom < 50){396window.scrollBy(0,150);397}398setTimeout(function () {399p.parentNode.removeChild(document.getElementById(nd+"load"));400}, 1000);401fm.submit();402}403404405406407408var createCookie = function(name, value, days) {409if(runlatex.usecookies){410var expires;411if (days) {412var date = new Date();413date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));414expires = "; expires=" + date.toGMTString();415}416else {417expires = "";418}419document.cookie = name + "=" + value + expires + "; path=/" + "; SameSite=Lax";420}421}422423function getCookie(c_name) {424if (runlatex.usecookies && document.cookie.length > 0) {425c_start = document.cookie.indexOf(c_name + "=");426if (c_start != -1) {427c_start = c_start + c_name.length + 1;428c_end = document.cookie.indexOf(";", c_start);429if (c_end == -1) {430c_end = document.cookie.length;431}432return unescape(document.cookie.substring(c_start, c_end));433}434}435return "";436}437438function rlSetReturn(n) {439createCookie('runlatex-return',n,100);440}441442var rldefaultreturn=getCookie('runlatex-return');443if(rldefaultreturn=="") rldefaultreturn="pdfjs";444445function rlSetEngine(n) {446createCookie('runlatex-engine',n,100);447}448449var rldefaultengine=getCookie('runlatex-engine');450if(rldefaultengine=="") rldefaultengine="pdflatex";451452453var rlacetheme=getCookie('runlatex-acetheme');454if(rlacetheme=="") rlacetheme="ace/theme/textmate";455456function rlAllowCookies() {457createCookie('runlatex-cookies',"true",100);458window.location.reload(false);459}460461function rlDeleteCookies() {462createCookie('runlatex-cookies',"",-999);463createCookie('runlatex-return',"",-999);464createCookie('runlatex-engine',"",-999);465createCookie('runlatex-acetheme',"",-999);466window.location.reload(false);467}468469var rlallowcookies=getCookie('runlatex-cookies')=="true";470471window.addEventListener('load', llexamples, false);472473474