Use with care a write or system call could damage a User's system.
TW.system(cmdLine : string [, waitForResult : bool]) : object;
This was previously placed as a command requiring no User set permissions directly under TW.app. and was moved to be immediately under TW. in November 2010, and User permissions necessitated. This move requires any existing scripts that used TW.system(...) to be redrafted to meet the new requirements.
There are two arguments, the first one is compulsory, a command line string to be executed by the OS system, and secondly optionally whether to wait for the command to finish and furnish out put from the the command line string that was executed.
User permissions must be set in Tw Edit/Preferences/Scripts
tick -> "Allow Scrips to Run System Commands"
Similar to file access functions, this function elegantly returns an object with result member values.
This result object may be accessed either in dot notation or in the apparent form of an associative array.
E.g. getting a directory listing on windows
var retVal = TW.system("cmd /c dir c:\*.* /ad", true);
Access results (see )
retVal.status
or
retVal["status"]
The form of the command string is entirely operating system dependant.
Generally use what ever would return a string from the shell command line.
(We use command line php to retrieve citation key entries from an MySql database that has been exported from JabRef. See php example)
Windows Users, note Jonathan Kew's remark:—
"NB: Windows users will need to use "cmd /c ..."
The "cmd /c " preface to any other commands is essential.
From dos help "cmd /c Carries out the command specified by string and then terminates"
Termination is needed so that Tw knows that the job is done and especially if waitForResult = true, stops Tw hanging around waiting not knowing what is going on.
Member |
Purpose |
retVal["status"] |
Indicating a successful attempt or otherwise |
retVal["result"] |
Any code returned by the command line executed |
retVal["message"] |
Indication of what happened on failure |
retVal["output"] |
Any String returned by the (even partially) executed command line |
"status" ( = integer ) |
"message" |
"result" |
"output" String |
SystemAccess_OK = 0 a) waitForResult = true b) waitForResult = false |
a) blank b) blank |
a) Available b) Empty |
a) Available b) Empty |
SystemAccess_Failed = 1 |
c) "Failed to execute system command: [cmd line details] d) "Error executing system command: [cmd line details] |
c) Empty d) Available |
c) Empty d) Available |
SystemAccess_PermissionDenied = 2 |
"System command execution is disabled (see Preferences)" |
Empty |
Empty |
Example:
[edit:]
Getting Cite Keys from and MySql database (exported from JabRef)
Tw Script: 'insertCitation.js'
// TeXworksScript
// Title: \cite from JabRef -> MySql
// Description: Make other Scripts
// Author: Paul A. Norman
// Version: 0.3
// Date: 2010-07-16
// Script-Type: standalone
// Context: TeXDocument
// Shortcut: Alt+B, Alt+C
// see http://twscript.paulanorman.com/docs/html/files/pan_Twmod.html
// see internally: helper_twPan.mod
eval(TW.app.getGlobal("helper_twPan")); // Comment if NOT Needed - This includes PhpJs ($P), twConst, msgBox, twPan ($tw), string.toTitleCase()
function makeSpace(howMuch)
{
var space = new String("");
for (x = 0; x < howMuch +7; x++) // +7 as we are dealing on Win at least with a proportional font in dropdown
{
space += " ";
}
return space;
}
var citationType = twPan.citationType;
var insertCite = twPan.insertCite;
var citationOrder = twPan.citationOrder;
var orderBy = twPan.citeOrderBy;
var reBuildDisplayText = [];
var phpScript = __FILE__.substr(0,__FILE__.lastIndexOf("/") +1) + 'getCiteKeys.php';
var chosenOrderBy = twPan.select("Please Choose A Citation Order: ", citationOrder) ; // first and third options probably mostly do the same - for completness
if (chosenOrderBy == undefined){chosenOrderBy = "By Citation Key";}
for (i = 0; i < citationOrder.length; i++)
{
if (chosenOrderBy == citationOrder[i])
{var citeOrderNum = i;
break;
}
}
// Non-windows OSes won't need the cmd /c
var citeKeysAndTitle = twPan.osCmd('cmd /c php ' + phpScript + ' ' + orderBy[citeOrderNum], true).split("\n");
var maxCiteKeyLength = 0;
for (descript =0; descript < citeKeysAndTitle.length; descript++) // add padding to move start point for title away from cite_key in drop down immediately below
{
thisDescript = citeKeysAndTitle[descript];
test = thisDescript.indexOf(', ');
maxCiteKeyLength = (test > maxCiteKeyLength) ? test : maxCiteKeyLength;
reBuildDisplayText.push(
[
citeKeysAndTitle[descript].substr(0,test +1),
citeKeysAndTitle[descript].substr(test +1)
]
);
}
for (descript = 0; descript < citeKeysAndTitle.length; descript++)
{
citeKeysAndTitle[descript] = reBuildDisplayText[descript][0]
+ makeSpace(maxCiteKeyLength - reBuildDisplayText[descript][0].length)
+ reBuildDisplayText[descript][1]
}
var chosenCitation = TW.getItem( null, "Insert Citation", "Please Choose A Citation Key: ", citeKeysAndTitle , 0, true ) ;
if (chosenCitation != undefined)
{
var pageRange = TW.getText( null, "Page Range", "Please enter A Page Range etc.\n\nE.g.> 123-127\n\nOr Cancel for None - OK to fill out later", "");
if (pageRange == undefined)
{
pageRange = "";
}
else
{
pageRange = '[P.~'+ pageRange + ']';
}
var citeTypeChosen = TW.getItem( null, "Citation Style", "(In Preamble, Place: \\usepackage{natbib})\n\n\nChoose A Citation Type: ",
citationType , 0, true ) ;
if (citeTypeChosen != undefined)
{
for (find =0; find < citationType.length; find++)
{
if (citationType[find] == citeTypeChosen)
{
citeType = insertCite[find];
break;
}
}
chosenCitation = chosenCitation.substr(0, chosenCitation.indexOf(", "));
TW.target.insertText('\\'+citeType+pageRange+'{'+chosenCitation+'}');
TW.target.statusTip = 'In Preamble, Need to Place: \\usepackage{natbib} ?';
}// /End. IF citeType != undefined
} // /End. IF chosenCitation != undefined
null;
// Thanks to http://www.andy-roberts.net/misc/latex/latextutorial3.html
// Thanks to http://www.ctan.org/tex-archive/macros/latex/contrib/natbib/natbib.pdf
Php file: 'getCiteKeys.php'
<?php
//$orderBy = 'title';
//$orderBy = 'cite_key';
$orderBy = $argv[1];
// Connecting, selecting database
$link = mysql_connect('localhost', 'root', '')
or die('Could not connect: ' . mysql_error());
mysql_set_charset('utf8');
// echo 'Connected successfully';
mysql_select_db('jabref') or die('Could not select database');
// Performing SQL query
// $query = 'SELECT cite_key title FROM entries';
$query = 'SELECT CONCAT(cite_key, \', \', title) FROM entries order by ' . $orderBy ;
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
$build = "";
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
foreach ($line as $col_value) {
$build .= $col_value . "\n";
}
}
// Free resultset
mysql_free_result($result);
// Closing connection
mysql_close($link);
$build = trim($build); // clean off last linefeed else blank option in dropdown results
echo $build;
// Thanks to http://www.tech-recipes.com/rx/2059/mysql_use_concat_to_include_text_in_select_results/
?>
Note: Pulled these TW.system() notes out form here ...
QMap<QString, QVariant> TWScriptAPI::system(const QString& cmdline, bool waitForResult)
{
QMap<QString, QVariant> retVal;
retVal["status"] = SystemAccess_PermissionDenied;
retVal["result"] = QVariant();
retVal["message"] = QVariant();
retVal["output"] = QVariant();
// Paranoia
if (!m_script) {
retVal["message"] = tr("Internal error");
return retVal;
}
if (m_script->mayExecuteSystemCommand(cmdline, m_target)) {
TWSystemCmd *process = new TWSystemCmd(this, waitForResult, !waitForResult);
if (waitForResult) {
process->setProcessChannelMode(QProcess::MergedChannels);
process->start(cmdline);
// make sure events (in particular GUI update events that should
// inform the user of the progress) are processed before we make a
// call that possibly blocks for a considerable amount of time
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 100);
if (!process->waitForStarted()) {
retVal["status"] = SystemAccess_Failed;
retVal["message"] = tr("Failed to execute system command: %1").arg(cmdline);
process->deleteLater();
return retVal;
}
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 100);
if (!process->waitForFinished()) {
retVal["status"] = SystemAccess_Failed;
retVal["result"] = process->exitCode();
retVal["output"] = process->getResult();
retVal["message"] = tr("Error executing system command: %1").arg(cmdline);
process->deleteLater();
return retVal;
}
retVal["status"] = SystemAccess_OK;
retVal["result"] = process->exitCode();
retVal["output"] = process->getResult();
process->deleteLater();
}
else {
process->closeReadChannel(QProcess::StandardOutput);
process->closeReadChannel(QProcess::StandardError);
process->start(cmdline);
retVal["status"] = SystemAccess_OK;
}
}
else
retVal["message"] = tr("System command execution is disabled (see Preferences)");
return retVal;
}
Created with the Personal Edition of HelpNDoc: Easily create HTML Help documents