This page will become a collection of user scripts which provides additional features that are to special to be implemented in the binary itself.
A description of the scripting language can be found in the User Manual. Notice that the available javascript functions may change in later TeXstudio releases.
Feel free to add your own scripts.
This example shows how you can write a simple script that executes the current editor text as another script. It can also be used when writing new scripts, because it is faster than opening the user macro dialog for every change.
%SCRIPT //app.fileSave(); // Enable this option if you want to autosave // the macro document before you run it. // So your data will be secured, // even if your script will crash TeXStudio. eval(editor.text());
Tested with: TMX 2.12.6
Copy the current file name, opened in the editor, to the clipboard.
%SCRIPT app.clipboard = editor.fileName();
Tested with: TXS 2.3
Remove all empty lines from a file.
%SCRIPT var tl = editor.document().textLines(); for (var i=tl.length-1;i>=0;i--) if (tl[i]=="") tl.splice(i, 1); editor.setText(tl.join("\n"));
Tested with: TXS 2.3
Remove all duplicated lines from a file.
%SCRIPT var tl = editor.document().textLines(); for (var i=tl.length-1;i>=0;i--) { var found = false; if (tl[i] != "") for (var j=i-1;j>=0;j--) if (tl[i] == tl[j]) { found = true; break; } if (found) tl.splice(i, 1); } editor.setText(tl.join("\n"));
Tested with: TXS 2.3
%SCRIPT var tl = editor.document().textLines(); for (var i=tl.length-1;i>=0;i--) tl[i] = tl[i].replace(/\s+$/, ''); editor.setText(tl.join("\n"));
Tested with: TXS 2.8.0
%SCRIPT editor.replace(/[0-9A-Fa-f]{2}/, "g", function(c){ return String.fromCharCode(1*("0x"+c.selectedText())); })
Tested with: TXS 2.3
This is a calculator evaluates a mathematical expression on the current line, like %sin(3.1415)=
.
%SCRIPT currentLine=editor.text(cursor.lineNumber()); from=currentLine.lastIndexOf("%")+1; to=currentLine.lastIndexOf("="); if (from>=0 && to > from) { toEvaluate = currentLine.substring(from, to); with (Math) { value = eval(toEvaluate);} cursor.eraseLine(); cursor.insertText(currentLine.substring(0, from)+toEvaluate+"="+value); cursor.insertLine(); cursor.movePosition(1,cursorEnums.Left ); }
Tested with: TMX 1.9.9 or later
Copy it at the beginning of a tex file and it will copy itself.
% !TeX TXS-SCRIPT = macrovirus % //Trigger: ?load-file | ?new-file | ?new-from-template %var self; %if (hasGlobal("macrovirus")) self = getGlobal("macrovirus"); %else { % var l1, l2 = -1; % editor.search(/% *!TeX *TXS-SCRIPT *= *macrovirus/, function(c){l1 = c.lineNumber();}); % editor.search(/% *TXS-SCRIPT-END/, function(c){if (l2 != -1 || l1 > c.lineNumber()) return; l2 = c.lineNumber();}); % self = ""; % for (var l=l1;l<=l2;l++) % self = self + editor.text(l) + "\n"; % setGlobal("macrovirus", self); %} % %for (var i=0;i<documents.length;i++) %if (documents[i].editorView.editor.search( /% *!TeX *TXS-SCRIPT *= *macrovirus/ ) == 0) { %documents[i].cursor(0).insertText(self); %} % TXS-SCRIPT-END
This script adds to all coordinate pairs in the currently selected text the offset of the first pair, which translates all pairs in a given direction. E.g. if you have (1 + 1, 2 - 1.5) (3, 4)
it will be changed to (2, 0.5) (4, 2.5)
.
%SCRIPT var doit = function(){ var mytext=cursor.selectedText(); var regExNumberPre = " *[0-9]+([.][0-9]*)? *"; var regExDigit = /[0-9]/; var regExSpace = / /g; var regExPairPre = " *(-?"+regExNumberPre+")"; var regExPair = new RegExp("()[(]"+regExPairPre+","+regExPairPre+"[)]"); ; //read first coordinate pair var regExFirstPairPre = regExPairPre + " *([+-]"+regExNumberPre+")?"; var regExFirstPair = new RegExp("()[(]"+regExFirstPairPre+","+regExFirstPairPre+"[)]"); //extract offsets (start regex search from first digit, to allow -x - y) var matches = regExFirstPair.exec(mytext); if (matches == null) throw "missing"; //throw matches; var offsetXPre = matches[4]; var offsetYPre = matches[8]; if (offsetXPre == "" && offsetYPre == "") throw "abc"; var offsetX = offsetXPre == ""?0.0:offsetXPre.replace(regExSpace, "")*1.0; var offsetY = offsetYPre == ""?0.0:offsetYPre.replace(regExSpace, "")*1.0; //move first pair var matchpos = mytext.search(regExFirstPair); editor.write(mytext.slice(0,matchpos)); editor.write("("+(matches[2].replace(regExSpace, "")*1.0+offsetX)); editor.write(", "+(matches[6].replace(regExSpace, "")*1.0+offsetY)+")"); //move other pairs var remaining = mytext.slice(matchpos+matches[0].length); while (remaining != ""){ matches = regExPair.exec(remaining); if (matches == null) break; matchpos = remaining.search(regExPair); editor.write(remaining.slice(0,matchpos)); remaining = remaining.slice(matchpos+matches[0].length); editor.write("(" + ((matches[2].replace(regExSpace, "")*1.0)+offsetX) + ", "+ ((matches[4].replace(regExSpace, "")*1.0)+offsetY) + ")"); } editor.write(remaining); } doit();
Tested with: TMX 1.9.9
Count how often every letter in the selection/document is used.
%SCRIPT var s = cursor.hasSelection()?cursor.selectedText():editor.text(); var hash = {}; for (var i=0; i < s.length; i++ ) hash[s[i]] = (hash[s[i]]==null?0:hash[s[i]]) + 1; cursor.movePosition(cursorEnums.End); for (var k in hash) cursor.insertText(k+": "+hash[k]+"\n");
Tested with: TMX 2.1
Sorts all lines in the document
%SCRIPT var a = new Array(); for (var i=0;i<editor.document().lineCount();i++) a.push(editor.text(i)); a.sort(); var t = ""; for (var l in a) t+= a[l]+"\n"; editor.setText(t);
Tested with: TMX 2.1
This script creates a random text with LaTeX-commands. This is not much useful for itself, but it can be used to find bugs/crashes of TeXstudio. Notice that it is quite slow (\~1 min) and that the generated text does not actually compile.
%SCRIPT var characters=" ,.,.,,.,.;:;.+_^-.;/()[]{}[],aabcdeeeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzzABCDEFGHIJKLMNOPQRSTUVWXYZäöüÄÖÜÖÄÖÄÜ1234567890"; var charactersSafe=" ,.,.,,.,.;:;.+-.;/()[][],aabcdeeeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzzABCDEFGHIJKLMNOPQRSTUVWXYZäöüÄÖÜÖÄÖÄÜ1234567890"; var cid1 = "aB"; var cid2 = "abcdefghij"; function randUntil(i) { return Math.floor(Math.random()*i); } function insertRandomString(cs){ for (var j=randUntil(100);j>0;j--) editor.insertText(cs[Math.floor(Math.random()*cs.length)]); } function insertRandomId(){ switch (randUntil(2)) { case 0: for (var i=4+randUntil(5);i>0;i--) editor.insertText(cid1[randUntil(cid1.length)]); break; case 1: for (var i=2;i>0;i--) editor.insertText(cid2[randUntil(cid2.length)]); break; } } totalLoopCutOff = 1500; function insertRandomLaTeX(deep){ for (var i=50+deep*10;i>0;i--) { totalLoopCutOff--; if (totalLoopCutOff<0) return; switch (Math.floor(Math.random()*16)) { case 0: editor.insertText(Math.random()); break; case 1: case 2: insertRandomString(characters); break; case 3: editor.insertText("$"); if (deep>0) insertRandomLaTeX(deep-1); editor.insertText("$"); break; case 4: editor.insertText("\\chapter{");insertRandomString(charactersSafe); editor.insertText("}"); break; case 5: editor.insertText("\\section{");insertRandomString(charactersSafe); editor.insertText("}"); break; case 6: editor.insertText("\\");editor.insertText("sectio");editor.insertText("n");editor.insertText("{");insertRandomString(charactersSafe); editor.insertText("}"); break; case 7: case 8: case 9: editor.insertText("\n"); break; case 10: editor.insertText("\\label{"); insertRandomId(); editor.insertText("}"); break; case 11: editor.insertText("\\ref{"); insertRandomId(); editor.insertText("}"); break; case 12: editor.insertText("\\cite{"); insertRandomId(); editor.insertText("}"); break; case 13: editor.insertText("\\include{"); insertRandomId(); editor.insertText("}"); break; case 14: if (Math.random() < 0.5) editor.insertText("%TODO"); insertRandomString(characters); break; case 15: editor.insertText("\\begin{block}"); if (deep>0) insertRandomLaTeX(deep-2); editor.insertText("\\end{block}"); break; } } } editor.insertText("\\documentclass[12pt,letterpaper]{report}\n"); editor.insertText("\\begin{document}\n"); insertRandomLaTeX(4); editor.insertText("\\end{document}\n"); //alert("insert complete"); cursor.movePosition(1, cursorEnums.End); var lineCount = cursor.lineNumber(); for (var i=1; i<10000;i++){ cursor.setLineNumber(randUntil(lineCount)); cursor.movePosition(1, cursorEnums.EndOfLine); var lineLength = cursor.columnNumber()+1; cursor.setColumnNumber(randUntil(lineLength)); if (Math.random()<0.75) cursor.insertText(characters[randUntil(characters.length)]); else cursor.deleteChar(); }
Tested with: TMX 2.0
%SCRIPT //Set the search panel of the editor editor.searchPanel.findChild("cbCase").checked = true; //Set the search panel of the pdf viewer pdfs[0].search.findChild("cbCase").checked = true;
Tested with: TXS 2.4
Note: From version 2.7 on, there is native support for changing case at Edit -> Text Operations. You won't need this script anymore. However we'll leave it here as example code.
%SCRIPT // Converts selected text to uppercase cursor.replaceSelectedText(cursor.selectedText().toUpperCase())
Tested with: TXS 2.5
Auto-correct multiple capital letters at the start of a word while typing. All characters except the first are converted to lowercase. Words consisting only of capital letters are not affected by the auto-correction.
Trigger: [a-z]
%SCRIPT typedChar = triggerMatches[0] cursor.movePosition(1, cursorEnums.StartOfWord, cursorEnums.KeepAnchor) lastWord = cursor.selectedText() re = /^[A-Z]{2,}/g if (lastWord.match(re)) { cursor.movePosition(1, cursorEnums.NextCharacter, cursorEnums.KeepAnchor) cursor.replaceSelectedText(cursor.selectedText().toLowerCase()) } cursor.movePosition(1, cursorEnums.EndOfWord) cursor.clearSelection() cursor.insertText(typedChar)
Tested with: TXS 2.9.4
When you copy multiple rows and/or columns from a spreadsheet application, columns are usually separated by tabs and rows by newline characters. This script takes the text from the clipboard and converts it into the LaTeX table format. The example creates a simple tabular
with left-aligned columns. You are free to adapt it to your needs.
%SCRIPT text = app.clipboard numCols = text.split('\n')[0].split('\t').length colspec = Array(numCols+1).join("l") text = text.replace(/\t/g, " & ") text = text.replace(/\n/g, " \\\\\n") text = "\\begin{tabular}{" + colspec + "}\n" + text + "\\end{tabular}\n" cursor.insertText(text)
Tested with: TXS 2.11.2
Note: Since TeXstudio natively provides word completion, this script mainly serves for demonstration. To use the built-in word completion, simply type the start of the word (at least 3 letters) and then hit Ctrl+Space
.
Having to type long words can be annoying, particularly with technical terms which may appear quite frequently in a text. The below script checks if the already typed characters match with the start of a word from a fixed word list. If so, the word is inserted. It is convenient to assign a handy shortcut such as Shift-Enter
to the script.
%SCRIPT // simple script for automatic word completion var words = ["trans-impedance-amplifier", "Dzyaloshinskii-Moriya interaction"] cursor.movePosition(1, cursorEnums.WordLeft, cursorEnums.KeepAnchor) txt = cursor.selectedText() for (var i=0; i<words.length; i++) { if (words[i].indexOf(txt) == 0) { cursor.removeSelectedText() editor.write(words[i]) break } } if (cursor.hasSelection()) cursor.moveTo(cursor.anchorLineNumber(), cursor.anchorColumnNumber())
Tested with: TXS 2.5
The following script lists all properties of the editor object. Of course, you can adapt it to inspect other objects.
%SCRIPT var pn = Object.getOwnPropertyNames(editor) editor.write(pn.join("\n"))
Tested with: TXS 2.5
The following scripts allows to set the linewrapping of the editor. Note: This only controls the editor. Changes are not reflected in the settings dialog. After accessing the settings dialog, the original value from the settings take over again. See the next example for a way to adjust the settings as well.
%SCRIPT // Set the wrap style of the editor // ***** configuration ***** /* possible wrap styles are 0: None 1: Soft wrap at window edge 2: Soft wrap after lineWidth chars 3: Hard wrap after lineWidth chars */ wrapStyle = 3 /* only relevant for styles 2 and 3 */ lineWidth = 60 // number of chars averageCharWidth = 8 // depends on the actual font being used // ***** code ***** editor.setLineWrapping(wrapStyle > 0); editor.setSoftLimitedLineWrapping(wrapStyle == 2); editor.setHardLineWrapping(wrapStyle > 2); if (wrapStyle > 1) { if (lineWidth < 20) lineWidth = 20; lineWidthInPixels = lineWidth * averageCharWidth editor.setWrapLineWidth(lineWidthInPixels); } else { editor.setWrapLineWidth(0); }
Tested with: TXS 2.5.2
This example shows how to toggle between two ways of wrapping (no wrapping and soft wrapping at the window edge). Settings are updated accordingly.
%SCRIPT if (getPersistent("Editor/WordWrapMode") == "1"){ editor.setLineWrapping(false); setPersistent("Editor/WordWrapMode","0") } else { editor.setLineWrapping(true); setPersistent("Editor/WordWrapMode","1") } editor.setSoftLimitedLineWrapping(false); editor.setHardLineWrapping(false);
Teseted with: TXS 2.10.4
If you are using the ulem package and want to use the command \ulem{}
instead of \underline{}
this little scipt detects, if the package is loaded and inserts the correct command automatically
%SCRIPT packages = editor.document().containedPackages(); usingUlem = false for (i=0; i<packages.length; i++) { if (packages[i] == "ulem") { usingUlem = true break } } if (usingUlem) editor.document().editorView.insertMacro('\\uline{%|}') else editor.document().editorView.insertMacro('\\underline{%|}')
Teseted with: TXS 0.0.0
For languages with accented chars it is convenient to type the chars on the keyboard and have them translated to LaTeX code on the fly. This can be achived by the following script.
Additionally, you have to set the trigger of the script to a regular expression matching all required chars. If there are only a few special chars, a simple or-list is ok: ä|ö|ü
. In case of many replacements the more generic \w
may be used as trigger.
Trigger: ä|ö|u
or
Trigger: \w
%SCRIPT replacements = { "ä": "\\'a", "ö": "\\'o", "ü": "\\'u", } c = triggerMatches if (c in replacements) { c = replacements[c] } editor.write(c)
Teseted with: TXS 0.0.0
This was a request by a user who wished to simultaneouly hide Structure, Log and PDF to have maximal space for editing. Moreover they should be restored afterwards easily.
For convenience, you may assign a shortcut to the macro via Options -> Configure TeXstudio -> Shortcuts.
%SCRIPT visible = app.getManagedAction("main/view/show/outputview").checked app.getManagedAction("main/view/show/outputview").trigger(!visible) app.getManagedAction("main/view/show/structureview").trigger(!visible) if (visible) { if (pdfs.length > 0) pdfs[0].close(); } else { app.getManagedAction("main/tools/view").trigger() }
Teseted with: TXS 0.0.0
Note: As of TXS 2.11.2 there is a built-in function will be a builtin function Idefix -> Toggle Comment
. Therefore this script is obsolete. However it may still serve as an example for similar tasks.
This script toggles the comments on the selected lines. It is a block-wise operation, i.e. all lines are commented/uncommented depending on the first selected line. This allows to properly comment/uncomment larger blocks which already contain comments. The block-operation gracefully handles uncommenting also for lines that do not contain a comment. Additionally, a space is inserted (and removed) after the comment char for better readability.
%SCRIPT startLine = cursor.anchorLineNumber() endLine = cursor.lineNumber() if (endLine < startLine) { tmp = startLine startLine = endLine endLine = tmp } nextChar = function() {return String.fromCharCode(cursor.nextChar())} cursor.beginEditBlock() cursor.moveTo(startLine, 0) line = editor.text(cursor.lineNumber()); hasComment = line.match(/^\s*%/) if (hasComment) { // uncomment for (l=startLine; l<=endLine; l++) { cursor.moveTo(l, 0) while (nextChar() in [' ', '\t']) cursor.movePosition(1, cursorEnums.NextCharacter); if (nextChar() == '%') cursor.deleteChar(); if (nextChar() == ' ') { cursor.movePosition(1, cursorEnums.NextCharacter); if (nextChar() != ' ') { // not an indentation cursor.deletePreviousChar(); } } } } else { // comment for (l=startLine; l<=endLine; l++) { cursor.moveTo(l, 0) cursor.insertText('% ') } } cursor.endEditBlock()
Takes a list of times (e.g. 13:14-15:16 or 52m, each on a separate line) and calculates the total time.
%SCRIPT //alert(editor.document().lineCount()); var r = /^ *([0-9]+):([0-9]+) *- *([0-9]+)+:([0-9]+)/; var r2 = /([0-9]+) *m *$/; var nt = ""; var totald = 0; for (var i=0;i<editor.document().lineCount();i++) { var e = r.exec(editor.text(i)); if (e) { var fh = e[1] * 1; var fm = e[2] * 1; var th = e[3] * 1; var tm = e[4] * 1; var d = 0; if (fh == th) d += tm - fm + 1; else if (fh < th) { d += 60 - fm + tm + 60 * (th - fh - 1) + 1; } else alert("daybreak!"); nt += e[0]+" => "+d+"m"; totald += d; } else { nt += editor.text(i); e = r2.exec(editor.text(i)); if (e) { totald += e[1] * 1; } } nt += "\n"; } nt += "\n\n ==> "+ totald + " = " + Math.floor(totald / 60) +":"+ (totald % 60); alert(nt);
Tested with: TXS 2.6.6
This example shows how you can time track using WakaTime.
https://github.com/wakatime/texstudio-wakatime
Tested with: TMX 2.6.6 or later
Mark the word "under the cursor" as an indexentry with \index{foo}foo
. Use it with a Hotkey like Shift-F1
for a faster running.
%SCRIPT cursor.select(cursorEnums.WordUnderCursor) idx = cursor.selectedText() cursor.movePosition(0,cursorEnums.StartOfWord) editor.setCursor(cursor) editor.write("\\index{"+idx+"}") cursor.movePosition(0,cursorEnums.EndOfWord) editor.setCursor(cursor) cursor.clearSelection()
Tested with: TXS 2.8.0
Simple Git commit and push support. Use it maybe with the ?save-file
trigger. Needs privileged write mode to run! It will ask for it.
%SCRIPT choisedialog = UniversalInputDialog(["Commit","Commit with Push"],"Git","choiseGIT") choisedialog.setWindowTitle("Git") choise = choisedialog.get("comment") if (choisedialog.exec() != null) { if (choisedialog.get("choiseGIT") == "Commit") { dialog = new UniversalInputDialog() dialog.setWindowTitle("Git commit / push") dialog.add("Committed by TeXstudio", "Comment", "comment") dialog.add(true, "Commit all Files","allfiles") if (dialog.exec() != null) { comment = dialog.get("comment") if ((dialog.get("allfiles")) == true){ buildManager.runCommand("git commit -a -m \"" + comment + "\"", editor.fileName()) }else{ buildManager.runCommand("git commit " + editor.fileName() + " -m \"" + comment + "\"", editor.fileName()) } } } else if (choisedialog.get("choiseGIT") == "Commit with Push") { dialog = new UniversalInputDialog() dialog.setWindowTitle("Git commit / push") dialog.add("Committed by TeXstudio", "Comment", "comment") dialog.add("master", "Branch", "branch") dialog.add(true, "Commit all Files","allfiles") if (dialog.exec() != null) { comment = dialog.get("comment") branch = dialog.get("branch") if ((dialog.get("allfiles")) == true){ buildManager.runCommand("git commit -a -m \"" + comment + "\"", editor.fileName()) }else{ buildManager.runCommand("git commit " + editor.fileName() + " -m \"" + comment + "\"", editor.fileName()) } buildManager.runCommand("git push origin \"" + branch +"\"", editor.fileName()) } } }
Tested with: TXS 2.6.6
Simply pressing the Home key moves the cursor to the start of the line. There is no native functionality to go to the start of the text (i.e. after the indentation). This can be accomplished with the following script. Pressing Home again, move it to the default beginning of the line.
%SCRIPT pos = cursor.columnNumber(); cursor.movePosition(1, cursorEnums.StartOfLine); i = 0; while (cursor.nextChar()==' '.charCodeAt(0) || cursor.nextChar()=='\t'.charCodeAt(0)) { cursor.movePosition(1, cursorEnums.NextCharacter); i++; } if (pos == i) { cursor.movePosition(1, cursorEnums.StartOfLine); }
As a second step, go to Options -> Configure... -> Shortcuts and assign Home to that new script.
Tested with: TXS 2.9.4
This script periodically saves all open documents under a new name (uses the _bak suffix). Use the ?txs-start
trigger to activate the script upon TXS launch.
%SCRIPT var Debug = false; //default = false var DoSave = true; //default = true var Interval = 60000;// set the time in milliseconds. 60000=1mins registerAsBackgroundScript("auto_save"); setTimeout(TimedFunction,Interval); function TimedFunction() { if (Debug) { alert('timer expired') }; SaveAllDocuments(); setTimeout(TimedFunction,Interval); //rearm the timed function } function SaveAllDocuments(){ if (Debug) { alert('SaveAllDocuments called') }; var NumOfDocs = documents.length; if (Debug) { alert('NumOfDocs='+NumOfDocs) }; for (var i = 0; i < NumOfDocs; i++) { SaveDocument(i, documents[i]); }; }; function SaveDocument(i, Document) { var CurEditor = Document.editorView.editor; var CurFileName = CurEditor.fileName(); if (Debug) { alert('i='+i+' FileName='+CurFileName) }; var newName = CurFileName.replace(/.tex$/, '_bak.tex'); if (Debug) { alert('i='+i+' newName='+newName) }; if (DoSave) { writeFile(newName, CurEditor.text()); }; };
Tested with: TXS 2.7
Bibtex automatically changes the capitalization of titles according to the settings in the bibtex style. Sometimes it is necessary to protect capital letters to prevent bibtex changing their case; e.g.
title = "Pascal, {C}, {Java}: were they all conceived in {ETH}?"
The following script capitalizes and protects the first letter of the word under the cursor:
%SCRIPT c = cursor c.movePosition(1, cursorEnums.StartOfWord) c.insertText('{') c.movePosition(1, cursorEnums.NextCharacter, cursorEnums.KeepAnchor) c.replaceSelectedText(c.selectedText().toUpperCase()) c.clearSelection() c.insertText('}')
Tested with: TXS 2.7.0
If you always want to have a space between your text and a comment, you may let TXS automatically insert a space if you type a comment sign (%) right behind a non-space. To do so, you can use a positive lookbehind regular expression as a trigger:
Trigger: (?language:latex)(?<=\\S)%
Type: normal
Text: Note: the first character is a space
. The %
is doubled for escaping.
%%
<space>
after a structure commandIf you want a label created for any section, subsection, chapter, etc. that you add, this script auto-generates a label after pressing <space>
behind the structure command (e.g. \chapter{Foo bar}<space>
). The label is preceded by a corresponding prefix and the title is sanitized (e.g. \chapter{Foo bar}\label{ch:foo-bar}
). TXS provides label generation through the right-click menu in the structure view, but this is IMHO quicker and provides different prefixes for different types of structures.
How to use it:
Create a macro and use the following as trigger: (?<=\\((sub)*section|chapter|part|paragraph)\{([^}]*)\})[ ]
As LaTeX content use:
%SCRIPT // all matches matches = triggerMatches; // the structure title title = matches[matches.length-1]; // shorten to three words title = title.match(/^([^ ]+ ){0,2}([^ ]+)?/i)[0]; // sanetize title title = title.replace(/[äàáâã]/gi,"a"); title = title.replace(/[ëèéêẽ]/gi,"e"); title = title.replace(/[ïìíîĩ]/gi,"i"); title = title.replace(/[öòóôõ]/gi,"o"); title = title.replace(/[üùúûũ]/gi,"u"); title = title.replace(/[ç]/gi,"c"); title = title.replace(/\W/gi,"-").toLowerCase(); // get long type type = matches[2]; prefixes = { "subsubsection": "sec", "subsection": "sec", "section": "sec", "chapter": "ch", "part": "part", "paragraph": "pg" } // replace type by short type if (type in prefixes) { type = prefixes[type]; } // output editor.write("\\label{"+type+":"+title+"}");
Adjust the prefixes to your likings.
Tested with: TXS 2.9.4
Question: I want to find the local line number within a verbatim environment, because I want to reference it in the surrounding text.
Solution: Place the cursor at the desired line and run the following script (it's convenient to assign a shortcut for running the script):
%SCRIPT lines = editor.document().textLines(); for (var i=cursor.lineNumber(); i>=0; i--) { l = lines[i] if (l.indexOf("\\begin{verbatim}") >= 0) { ln = cursor.lineNumber() - i app.setClipboardText(ln) alert('Local line number in itemize:\n' + ln + '\n(Copied to clipboard)'); } }
This can easily adapted for other environments like minted or listings.
Tested with: TXS 2.9.4
This script moves the cursor to the next sectioning command. It's just a demonstration and easily adaptable for other commands.
%SCRIPT commands = ["\\part", "\\chapter", "\\section", "\\subsection", "\\subsubsection", "\\paragraph"] while (!cursor.atEnd()) { cursor.movePosition(1, cursorEnums.NextWord) if (cursor.nextChar() != '\\'.charCodeAt(0)) continue; cursor.movePosition(1, cursorEnums.NextCharacter, cursorEnums.KeepAnchor); cursor.movePosition(1, cursorEnums.EndOfWord, cursorEnums.KeepAnchor); if (commands.indexOf(cursor.selectedText()) >= 0) { cursor.setColumnNumber(cursor.anchorColumnNumber()) break; } }
Tested with: TXS 2.9.4
This simple script fills in the latex citation command and opens the completion menu so that you can choose the correct reference. You can replace \autocite{} with other latex commands, i.e. \cite{}.
%SCRIPT editor.write("\\autocite{}"); cursor.shift(-1); app.normalCompletion()
Tested with: TXS 2.10.6
Return
and the cursor is behind \begin{env}This script is somewhat similar to Idefix -> Complete -> Close latest open environment
. However it's specifically intend as an auto-completion when hitting Return
. To achive this, bind the Return
key to the macro using Options -> Shortcuts
.
%SCRIPT previousChar = function() {return String.fromCharCode(cursor.previousChar())} nextChar = function() {return String.fromCharCode(cursor.nextChar())} String.prototype.startsWith = function(searchString, position) { position = position || 0; return this.indexOf(searchString, position) === position; }; getClosingEnvironment = function() { // returns \end{env} if the cursor is at the end of \begin{env} // returns undefined otherwise if (previousChar() == '}') cursor.movePosition(1, cursorEnums.Left, cursorEnums.KeepAnchor); while (nextChar() != '{') { if (cursor.atLineStart()) break; cursor.movePosition(1, cursorEnums.Left, cursorEnums.KeepAnchor); } cursor.movePosition(1, cursorEnums.Left, cursorEnums.KeepAnchor); cursor.movePosition(1, cursorEnums.StartOfWordOrCommand, cursorEnums.KeepAnchor); var result; if (cursor.selectedText().startsWith("\\begin")) result = cursor.selectedText().replace("\\begin", "\\end"); cursor.flipSelection(); cursor.clearSelection(); return result; } var env = getClosingEnvironment() cursor.insertLine(); if (env !== undefined) { cursor.insertLine(); cursor.insertText(env); cursor.movePosition(1, cursorEnums.PreviousLine) }
Tested with: TXS 2.11.0
Assume that you would like to put double quotes around a word or a group of words. This script simplifies the process: Simply select the group of words and type a double quote. The trigger defined here is for single quotes, double quotes and $, but it can be adapted to other chars as well.
Trigger: "|'|\$
%SCRIPT c = triggerMatches if (editor.cutBuffer.length) { editor.insertText(c + editor.cutBuffer + c) } else { editor.insertText(c) }
Tested with: TXS 2.12.6
UniversalInputDialog
Put the code into a UniversalInputDialog.js file.
Run it with the first example on this site "Trivial eval example".
If you like to run it from the macro editor, replace //SCRIPT
with %SCRIPT"
.
This is every thing a UniversalInputDialog can do.
Checkbox (true or false)
Selextbox (String \n
with linebreak)
Textbox (no multiline)
Numberbox (numbers up and down)
Each box can have a label that fully supports \n
linebreaks,
The box will return an array with the content of the box or false when aborted.
//SCRIPT var metaData = { "Name" : "UniversalInputDialog", "Description" : "UniversalInputDialog()", "Author" : "NöTiger", "Date" : "03.02.2018", "Version" : "1.0", "License" : "Public Domain", "FilesToOpen" : "./UniversalInputDialog.js" }; // Create a dialog but do not show it for now. dlg = new UniversalInputDialog(); // Set the title of the dialog. dlg.setWindowTitle( metaData.Name ); // Create a checbox for true/false input, describe it as "checkbox", give the internal ID "checkbox". dlg.add( true, "A\ncheckbox", "checkbox" ); // Create a selectbox to take a selection out of a list, describe it as "selectbox", give the internal ID "selectbox". dlg.add( [ "Value 1", "Value\nNumber 2" ], "A\nselectbox", "selectbox" ); // Create a textbox for text input, describe it as "textbox", give the internal ID "textbox". dlg.add( "Text", "A\ntextbox", "textbox" ); // Create a numberbox for numeric input, describe it as "numberbox", give the internal ID "numberbox". dlg.add( 0, "A\nnumberbox", "numberbox" ); // Show the newly created and populatet dialog, in front of TexStudio, keep it in front until it gets closed. //dlg.exec(); if ( dlg.exec() != false ) { // Get the values after the dialog has been closed. alert( dlg.get( "checkbox" ) ); alert( dlg.get( "selectbox" ) ); alert( dlg.get( "textbox" ) ); alert( dlg.get( "numberbox" ) ); };
Tested with: TeXstudio 2.12.6
Open this script in the editor as "CrazySelectedObjectBrowser.js".
Select a script object in the editor, in example "app" or "cursor" or "Object.getOwnPropertyNames".
Run it with the first example on this site "Trivial eval example".
If you like to run it from the macro editor, replace "//SCRIPT" with "%SCRIPT".
The script will return a error if the object is not valid.
It works also on commentet selections
Triggers: none
//SCRIPT var metaData = { "Name" : "Crazy selected object browser", "Description" : "Open a *.js file in TeXStudio, or create one.\nSelect a TxTStudio macro Object as \"app\" or \"cursor\" and so on.\nRun this script, and all object properties will get shown to you.\nOtherwise a natural error message will be returned.", "Author" : "NöTiger", "Date" : "0.0.2018", "Version" : "1.2", "License" : "Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)", "FilesToOpen" : "CrazySelectedObjectBrowser.js", "Trigger" : "eval(readFile('X:/Y/Z/CrazySelectedObjectBrowser.js'));" }; // Open a *.js file in TeXStudio, or create one. // Select a TxTStudio macro object as "app" or "cursor" or "Object.getOwnPropertyNames" and so on. // Run this script, and all object properties will get shown to you. // Otherwise a natural error message will be returned. // You can select a property and click OK, it will be in your clipboard. // You can click on abort and your clipboard will stay as it is. // VARIABLES // This is a variable to keep a value. var arrayOfProperties = [ "" ]; // Clear variable. var stringProperties = ""; // Clear variable. // FUNCTIONS // This is a function. function funcGetProperties( obj ) { var getting = ""; var getting = Object.getOwnPropertyNames( obj ).sort(); return getting; }; // PROGRAM // If nothing is selected, get properties from "app" object. if ( cursor.selectedText() != "" ) { try { var arrayOfProperties = funcGetProperties( eval( "(" + cursor.selectedText() + ")" ) ); var stringProperties = String( cursor.selectedText() ); } catch ( e ) { if ( e instanceof EvalError ) { alert( e.name + ": " + e.message ); var arrayOfProperties = funcGetProperties( this ); var stringProperties = "this"; } else if ( e instanceof RangeError ) { alert(e.name + ": " + e.message ); var arrayOfProperties = funcGetProperties( this ); var stringProperties = "this"; } else if ( e instanceof ReferenceError ) { alert( e.name + ": " + e.message ); var arrayOfProperties = funcGetProperties( this ); var stringProperties = "this"; } else if ( e instanceof SyntaxError ) { alert( e.name + ": " + e.message ); var arrayOfProperties = funcGetProperties( this ); var stringProperties = "this"; } else if ( e instanceof TypeError ) { alert( e.name + ": " + e.message ); var arrayOfProperties = funcGetProperties( this ); var stringProperties = "this"; } else if ( e instanceof URIError ) { alert( e.name + ": " + e.message ); var arrayOfProperties = funcGetProperties( this ); var stringProperties = "this"; //} else if ( e instanceof CustomError ) { //alert( e.name + ": " + e.message ); } else { alert( e.name + ": " + e.message ); var arrayOfProperties = funcGetProperties( this ); var stringProperties = "this"; }; }; } else { var arrayOfProperties = funcGetProperties( this ); var stringProperties = "this"; }; // Create a dialog. dlg = new UniversalInputDialog(); // Set dialog name dlg.setWindowTitle( "Crazy selected object browser" ); // Add a selectbox with all the properties in a list to stelect one out of them. dlg.add( arrayOfProperties, "Tatarata...\nhere are the properties of ...\n\"" + stringProperties + "\"", "selectbox" ); // EXIT // If the dialog was not aborted, put the selected propertie into the clipboard. if ( dlg.exec() != false ) { // Put some thing into the clipboard. app.clipboard = dlg.get( "selectbox" ); };
Tested with: TeXstudio 2.12.6
Copy, Paste and Cut lines like in Visual Studio. If no text is selected the whole line will be copied/cut to the clipboard. If text is selected, then only the selection is copied/cut to the clipboard. If a line is pasted, it is iunserted bevor the current line.
Triggers: None
Bind to Keyboard Shutcuts Ctrl-C, Ctrl-V, Ctrl-X
Copy Line:
%SCRIPT var text=cursor.selectedText() if(text.length>0) { app.clipboard = text }else{ //no text selected => copy line app.clipboard = editor.text(cursor.lineNumber())+"\n"; }
Cut Line:
%SCRIPT var text=cursor.selectedText() if(text.length>0) { //cut selected text app.clipboard = text cursor.removeSelectedText() }else{ //no text selected => cut whole line app.clipboard = editor.text(cursor.lineNumber())+"\n"; cursor.eraseLine() }
Paste Line:
%SCRIPT var text = app.clipboard if(text.lastIndexOf("\n") == text.length-1){ cursor.movePosition(1, cursorEnums.StartOfLine); editor.write(text) }else{ editor.write(text) }
Tested with: TXS 2.12.14
Shortcut that puts \item on the current or next line, depending upon the position the cursor. Disable the built-in \item shortcut (Options>Configure TeXstudio...>Shortcuts>Menus>LaTeX>List Environ...) and create a macro with the shortcut Ctrl+Shift+I.
Triggers:None
%SCRIPT while(cursor.previousChar()==" ".charCodeAt(0)){ cursor.movePosition(1, op = cursorEnums.Left, m = cursorEnums.MoveAnchor)}; //move to start of line or previous character if(cursor.nextChar()=="}".charCodeAt(0)){ cursor.movePosition(1, op = cursorEnums.Right, m = cursorEnums.MoveAnchor)}; // allows to press shortcut when cursor between "itemize" and "}" if(cursor.atLineStart()==false && cursor.previousChar()!="\t".charCodeAt(0)){ cursor.insertLine(keepAnchor = false); editor.write("\t\\item ") } // if the cursor is not at the start of a line and not preceded by a tab, // jump to the next line and insert <tab>\item else{ if(cursor.atLineStart()==true){ editor.write("\t\\item ") } // if the cursor is at the start of the line insert <tab>\item else{ editor.write("\\item ") } // if the cursor is preceded by a tab insert \item }
Tested with: TXS 2.12.22
Do not forget to describe your code.
Triggers: Example
You can add your own script or snipet code here.
Tested with: TXS 0.0.0
I'm trying to use the Periodic script to auto-save all documents under a new name, but some errors occur. For example, the word "função" is written as "função", the same occurs with other words (words of the Portuguese language). Is it possible to correct this?
The script Finding the next sectioning command moves the cursor to the correct position, but does not change the view to the line automatically, is it possible to do this?
These scripts are amazing!
I was having some problems in the "Automatic Label" and tweaked it a little bit:
Automatic Label Creation (Supports International Characters)
Trigger:
(?<=\\((sub)*section|chapter|part|paragraph)\{([^}]*)\})[ ]
(I removed the '^' after the '=', as it was causing some sort of problem)
Last edit: Rafael M Santos 2017-08-11
Thanks. I've put the changes in the above entry.
Hi,
I am completely new the scripting.
I want to write a script to remove whitespaces before punctuation marks in sentences.
Based on the above examples, I tried
code:
Output:
This is a long sentence. I have to remove the space .
It removes only the first occurence.
How to get multiple occurences in the sentence replaced at once?
Is there a way to generalize for all the punctuation marks and to have only once space after the punctuation?
Thank you dor the help
Last edit: Tim Hoffmann 2017-10-28
Note: This is a pure javascript/regexp question. Neither is this our core competency nor do we have the time to answer such questions. You'll get better help at sites such as https://stackoverflow.com/
Without explaination, this is the solution for multiple occurences and different punctuation marks:
var replaced = text.replace(/\s+([\.,;])/g, '$1')
I don't think there's an as simple solution for "only once space after the punctuation" within the same expression. Probably it's easiest to do a separate replace for these. For further questions, please check stackoverflow.
Thank you very much for the answer. Sorry, for posting the question here. I am doing any thing related to java for the first time.
Please help me!
How to create macros in TexStudio to press Ctrl + Alt + M?
Thank you!
Last edit: Dương Phước Sang 2019-05-18
..
Last edit: Dani 2020-04-16
development has moved to github.com/texstudio-org/texstudio, you might
be interested to put the content there.
Am 16.04.20 um 04:19 schrieb Daniel Cotton:
Hi, very simple script that adds the last citation you used. I just use "xx" to trigger as I use this alot.
you probably want to publish it on github (texstudio-org)
Hi,
I'm interested in the script "Periodic auto-save all documents under a new name" but I don't understand how to use the ?txs-start trigger to activate the script upon TXS launch as suggested!
I read the manual but I couldn't find a clear explanation!
development has moved to https://github.com/texstudio-org/texstudio
please discuss there.