View Issue Details

IDProjectCategoryView StatusLast Update
0013311ScribusIntegrationpublic2015-11-22 13:52
Reporterberteh Assigned Tocbradney  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version1.5.1svn 
Fixed in Version1.5.1svn 
Summary0013311: support for command line arguments to be passed on to python script (-py option)
Descriptionadding 1 option to pass arguments to python script run in Scribus from command line (to be used with -py and -g), after discussions and testing with a-l-e and luzpaz.


     -py, --python-script <filename> Run filename in Python scripter
       --python-arg-<argumentname> [value] Argument passed on to python script, with an optional value, no effect without -py
     -g, --no-gui Do not start GUI
     -- Explicit end of command line options
Steps To Reproduce[New : edited the 4th of sept 2015]

apply "cmdline_--python-arg_name_value__clean.patch", compile, then call any scribus python script that will get the additional arguments passed from the command line:

simple use:
./scribus -g -py ~/cmdtest.py --python-arg -someflag1 --python-arg --somearg1 value1 ~/some1.sla

or more complex (with -- to distinguish that last parameter(s) are file(s) to be opened by scribus before running the script, and not arguments to be passed to the script.)

./scribus -g -py ~/cmdtest.py --python-arg -somearg1 value1 --python-arg --someflag1 -- ~/some1.sla



help is in the standard usage info:

./scribus -h

Usage: scribus [options] [files]

Options:
(...)
     -py, --python-script <filename> Run filename in Python scripter
     -pa, --python-arg <name> [value] Argument passed on to python script, with an optional value, no effect without -py
     -- Explicit end of command line options
TagsNo tags attached.
PatchYes

Relationships

has duplicate 0008968 closedcbradney [patch] add getArgv(num) and getArgc() api : Access the scribus started argument to do custom procesing 
related to 0000238 assignedcbradney New CL option: scribus --to-pdf <scribus-file> <output.pdf> 

Activities

berteh

2015-08-19 15:22

reporter  

command-line-arguments-for-python-script.patch (30,923 bytes)   
From d019992c0798595d3d422672a21e3441b3cc6838 Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Wed, 5 Aug 2015 16:00:45 +0200
Subject: [PATCH 1/7] added command-line arguments to be passed to python
 script, some fix needed in scriptercore.cpp#283.

---
 scribus/plugins/scriptplugin/scriptercore.cpp | 30 +++++++++++++++++++++++----
 scribus/plugins/scriptplugin/scriptercore.h   |  3 ++-
 scribus/scribusapp.cpp                        | 22 ++++++++++++++++++--
 scribus/scribusapp.h                          |  2 ++
 4 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index 3903617..c27517b 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -9,6 +9,7 @@ for which a new license (GPL+exception) is in place.
 #include <QGlobalStatic>
 #include <QWidget>
 #include <QString>
+#include <QStringList>
 #include <QApplication>
 #include <QMessageBox>
 #include <QTextCodec>
@@ -37,7 +38,7 @@ for which a new license (GPL+exception) is in place.
 #include "prefscontext.h"
 #include "prefstable.h"
 #include "prefsmanager.h"
-#include "scribusapp.h" // need it to acces ScQApp->pythonScript
+#include "scribusapp.h" // need it to acces ScQApp->pythonScript & ScQApp->pythonScriptArgs
 
 ScripterCore::ScripterCore(QWidget* parent)
 {
@@ -228,6 +229,12 @@ void ScripterCore::RecentScript(QString fn)
 
 void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 {
+	QStringList arguments = QStringList();
+	slotRunScriptFileArgs(fileName, arguments, inMainInterpreter);
+}
+
+void ScripterCore::slotRunScriptFileArgs(QString fileName, QStringList arguments, bool inMainInterpreter)
+{
 	// Prevent two scripts to be run concurrently or face crash!
 	if (ScCore->primaryMainWindow()->scriptIsRunning())
 		return;
@@ -252,16 +259,31 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 		// Init the scripter module in the sub-interpreter
 		initscribus(ScCore->primaryMainWindow());
 	}
+
+	// handle additional arguments
+	bool argsExtra = !(arguments.isEmpty());	
+	int argsc = 0;
+	if (argsExtra) 
+	{
+		argsc = arguments.size();
+		//std::cout << tr("running script with %1 arguments").arg(argsc).toLocal8Bit().data() << std::endl;
+	}
 	// Make sure sys.argv[0] is the path to the script
-	char* comm[2];
+	char* comm[2+argsc];
 	comm[0] = na.data();
+	
 	// and tell the script if it's running in the main intepreter or
 	// a subinterpreter using the second argument, ie sys.argv[1]
 	if (inMainInterpreter)
 		comm[1] = const_cast<char*>("ext");
 	else
 		comm[1] = const_cast<char*>("sub");
-	PySys_SetArgv(2, comm);
+	for (int j = 0; j < argsc; ++j)
+	{
+		comm[2+j] = arguments.at(j).toLocal8Bit().data()  ; // TODO fix here: some copy is needed, otherwise all comm[>2] point to same (last) value for j.
+	}
+	PySys_SetArgv(2+argsc, comm);
+	
 	// call python script
 	PyObject* m = PyImport_AddModule((char*)"__main__");
 	if (m == NULL)
@@ -357,7 +379,7 @@ void ScripterCore::slotRunPythonScript()
 {
 	if (!ScQApp->pythonScript.isNull())
 	{
-		slotRunScriptFile(ScQApp->pythonScript, true);
+		slotRunScriptFileArgs(ScQApp->pythonScript, ScQApp->pythonScriptArgs, true);
 		FinishScriptRun();
 	}
 }
diff --git a/scribus/plugins/scriptplugin/scriptercore.h b/scribus/plugins/scriptplugin/scriptercore.h
index 1e929f4..b8e2edf 100644
--- a/scribus/plugins/scriptplugin/scriptercore.h
+++ b/scribus/plugins/scriptplugin/scriptercore.h
@@ -39,8 +39,9 @@ public slots:
 	void StdScript(QString filebasename);
 	void RecentScript(QString fn);
 	void slotRunScriptFile(QString fileName, bool inMainInterpreter = false);
+	void slotRunScriptFileArgs(QString fileName, QStringList arguments, bool inMainInterpreter = false);
 	void slotRunPythonScript(); // needed for running python script from CLI
-	void slotRunScript(const QString Script);
+	void slotRunScript(const QString script);
 	void slotInteractiveScript(bool);
 	void slotExecute();
 	/*! \brief Show docstring of the script to the user.
diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index fec4055..9c52c04 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -32,6 +32,7 @@ for which a new license (GPL+exception) is in place.
 #include <QLibraryInfo>
 #include <QLocale>
 #include <QString>
+#include <QStringList>
 #include <QTextCodec>
 #include <QTextStream>
 #include <QTranslator>
@@ -71,6 +72,8 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK "--upgradecheck"
 #define ARG_TESTS "--tests"
 #define ARG_PYTHONSCRIPT "--python-script"
+#define ARG_SCRIPTARG_PREFIX "--python-arg"   // directly followed by <param name> <param value>
+#define ARG_SCRIPTFLAG_PREFIX "--python-flag" // directly followed by <param name>
 
 #define ARG_VERSION_SHORT "-v"
 #define ARG_HELP_SHORT "-h"
@@ -108,6 +111,7 @@ ScribusQApp::ScribusQApp( int & argc, char ** argv ) : QApplication(argc, argv),
 	m_scDLMgr = 0;
 	m_ScCore = NULL;
 	initDLMgr();
+
 }
 
 ScribusQApp::~ScribusQApp()
@@ -213,6 +217,8 @@ void ScribusQApp::parseCommandLine()
 		std::exit(EXIT_SUCCESS);
 	useGUI = true;
 	//We are going to run something other than command line help
+	QString qtARG_SCRIPTARG_PREFIX = QString(ARG_SCRIPTARG_PREFIX);
+	QString qtARG_SCRIPTFLAG_PREFIX = QString(ARG_SCRIPTFLAG_PREFIX);
 	for(int i = 1; i < argsc; i++) {
 		arg = args[i];
 
@@ -267,7 +273,17 @@ void ScribusQApp::parseCommandLine()
 			} else {
 				++i;
 			}
-		} else {
+		} else if (arg.startsWith(qtARG_SCRIPTARG_PREFIX)) {
+	 		QString arg_name = arg.mid(qtARG_SCRIPTARG_PREFIX.size());
+	 		QString arg_value = QFile::decodeName(args[++i].toLocal8Bit());
+	 		//std::cout << tr("got one script argument: %1 with value %2").arg(arg_name).arg(arg_value).toLocal8Bit().data() << std::endl;				
+	 		pythonScriptArgs.append(arg_name);
+	 		pythonScriptArgs.append(arg_value);
+		} else if (arg.startsWith(qtARG_SCRIPTFLAG_PREFIX)) {
+	 		QString arg_name = arg.mid(qtARG_SCRIPTFLAG_PREFIX.size());
+	 		//std::cout << tr("got one script flag: %1 ").arg(arg_name).toLocal8Bit().data() << std::endl;
+	 		pythonScriptArgs.append(arg_name);	 		
+		} else { // (last) positional argument
 			fileName = QFile::decodeName(args[i].toLocal8Bit());
 			if (!QFileInfo(fileName).exists()) {
 				showHeader();
@@ -498,7 +514,9 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
-	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
+	ts << (QString("     %1<%2> <%3>    ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
+	ts << (QString("     %1<%2>               ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
+ 	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
 	
 #if defined(_WIN32) && !defined(_CONSOLE)
 	printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") );
diff --git a/scribus/scribusapp.h b/scribus/scribusapp.h
index 2857306..7fc9f7f 100644
--- a/scribus/scribusapp.h
+++ b/scribus/scribusapp.h
@@ -23,6 +23,7 @@ for which a new license (GPL+exception) is in place.
 #define SCRIBUSAPP_H
 #include <QApplication>
 #include <QString>
+#include <QStringList>
 
 #include "scribusapi.h"
 
@@ -71,6 +72,7 @@ class SCRIBUS_API ScribusQApp : public QApplication
 		const QString& currGUILanguage() { return GUILang; }
 		ScDLManager* dlManager() { return m_scDLMgr; }
 		QString pythonScript; // script to be run in python from CLI
+		QStringList pythonScriptArgs; // command line arguments and flags for script from CLI
 
 	private:
 		ScribusCore* m_ScCore;

From f4c7e635c738fb35114f9ffd6112c0e38990d55a Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Wed, 5 Aug 2015 17:05:56 +0200
Subject: [PATCH 2/7] help message layout

---
 scribus/scribusapp.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 9c52c04..77be088 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -514,8 +514,8 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
-	ts << (QString("     %1<%2> <%3>    ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
-	ts << (QString("     %1<%2>               ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
+	ts << (QString("       %1<%2> <%3>   ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
+	ts << (QString("       %1<%2>              ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
  	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
 	
 #if defined(_WIN32) && !defined(_CONSOLE)

From 35e17efbc051678d5d78f4958a08ac6bc7079bc0 Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Wed, 5 Aug 2015 17:07:11 +0200
Subject: [PATCH 3/7] use QStringList to call python script with arguments

---
 scribus/plugins/scriptplugin/scriptercore.cpp | 26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index c27517b..f6456c4 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -234,6 +234,7 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 }
 
 void ScripterCore::slotRunScriptFileArgs(QString fileName, QStringList arguments, bool inMainInterpreter)
+/** run "filename" python script with the additional arguments provided in "arguments" */
 {
 	// Prevent two scripts to be run concurrently or face crash!
 	if (ScCore->primaryMainWindow()->scriptIsRunning())
@@ -260,29 +261,24 @@ void ScripterCore::slotRunScriptFileArgs(QString fileName, QStringList arguments
 		initscribus(ScCore->primaryMainWindow());
 	}
 
-	// handle additional arguments
-	bool argsExtra = !(arguments.isEmpty());	
-	int argsc = 0;
-	if (argsExtra) 
-	{
-		argsc = arguments.size();
-		//std::cout << tr("running script with %1 arguments").arg(argsc).toLocal8Bit().data() << std::endl;
-	}
 	// Make sure sys.argv[0] is the path to the script
-	char* comm[2+argsc];
-	comm[0] = na.data();
+	arguments.prepend(na.data());
 	
 	// and tell the script if it's running in the main intepreter or
 	// a subinterpreter using the second argument, ie sys.argv[1]
 	if (inMainInterpreter)
-		comm[1] = const_cast<char*>("ext");
+		arguments.insert(1,QString("ext"));
 	else
-		comm[1] = const_cast<char*>("sub");
-	for (int j = 0; j < argsc; ++j)
+		arguments.insert(1,QString("sub"));
+
+	//convert arguments (QListString) to char** for Python bridge
+	/* typically arguments == ['path/to/script.py','ext','--argument1','valueforarg1','--flag']*/
+	char *comm[arguments.size()];
+	for (int i = 0; i < arguments.size(); i++)
 	{
-		comm[2+j] = arguments.at(j).toLocal8Bit().data()  ; // TODO fix here: some copy is needed, otherwise all comm[>2] point to same (last) value for j.
+		comm[i] = arguments.at(i).mid(0).toLocal8Bit().data(); // TODO fix here: unexpected border effects. all comm[*] point to same (last) value for i... despite mid() that should create a copy.
 	}
-	PySys_SetArgv(2+argsc, comm);
+	PySys_SetArgv(arguments.size(), comm);
 	
 	// call python script
 	PyObject* m = PyImport_AddModule((char*)"__main__");

From 50fca9e4feffa2337a1c8de5f0e99f9bf23bb248 Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Wed, 5 Aug 2015 18:31:30 +0200
Subject: [PATCH 4/7] fix arguments passing from command line to python script

---
 scribus/plugins/scriptplugin/scriptercore.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index f6456c4..41b2949 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -276,7 +276,8 @@ void ScripterCore::slotRunScriptFileArgs(QString fileName, QStringList arguments
 	char *comm[arguments.size()];
 	for (int i = 0; i < arguments.size(); i++)
 	{
-		comm[i] = arguments.at(i).mid(0).toLocal8Bit().data(); // TODO fix here: unexpected border effects. all comm[*] point to same (last) value for i... despite mid() that should create a copy.
+		comm[i] = new char[arguments.at(i).toLocal8Bit().size()+1]; //+1 to allow adding '\0'. may be useless, don't know how to check.
+		strcpy(comm[i],arguments.at(i).toLocal8Bit().data()+'\0');
 	}
 	PySys_SetArgv(arguments.size(), comm);
 	

From b90f29c7bdb9908c4addb31b8486c8ec8197650d Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Thu, 6 Aug 2015 11:32:17 +0200
Subject: [PATCH 5/7] add dash to prefix for command line arguments to python
 script

---
 scribus/scribusapp.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 77be088..46b7508 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -72,8 +72,8 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK "--upgradecheck"
 #define ARG_TESTS "--tests"
 #define ARG_PYTHONSCRIPT "--python-script"
-#define ARG_SCRIPTARG_PREFIX "--python-arg"   // directly followed by <param name> <param value>
-#define ARG_SCRIPTFLAG_PREFIX "--python-flag" // directly followed by <param name>
+#define ARG_SCRIPTARG_PREFIX "--python-arg-"   // directly followed by <param name> <param value>
+#define ARG_SCRIPTFLAG_PREFIX "--python-flag-" // directly followed by <param name>
 
 #define ARG_VERSION_SHORT "-v"
 #define ARG_HELP_SHORT "-h"
@@ -274,13 +274,13 @@ void ScribusQApp::parseCommandLine()
 				++i;
 			}
 		} else if (arg.startsWith(qtARG_SCRIPTARG_PREFIX)) {
-	 		QString arg_name = arg.mid(qtARG_SCRIPTARG_PREFIX.size());
+	 		QString arg_name = arg.mid(qtARG_SCRIPTARG_PREFIX.size()-1); //-1 to get the dash from prefix
 	 		QString arg_value = QFile::decodeName(args[++i].toLocal8Bit());
 	 		//std::cout << tr("got one script argument: %1 with value %2").arg(arg_name).arg(arg_value).toLocal8Bit().data() << std::endl;				
 	 		pythonScriptArgs.append(arg_name);
 	 		pythonScriptArgs.append(arg_value);
 		} else if (arg.startsWith(qtARG_SCRIPTFLAG_PREFIX)) {
-	 		QString arg_name = arg.mid(qtARG_SCRIPTFLAG_PREFIX.size());
+	 		QString arg_name = arg.mid(qtARG_SCRIPTFLAG_PREFIX.size()-1); //-1 to get the dash from prefix
 	 		//std::cout << tr("got one script flag: %1 ").arg(arg_name).toLocal8Bit().data() << std::endl;
 	 		pythonScriptArgs.append(arg_name);	 		
 		} else { // (last) positional argument
@@ -514,8 +514,8 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
-	ts << (QString("       %1<%2> <%3>   ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
-	ts << (QString("       %1<%2>              ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
+	ts << (QString("       %1<%2> <%3>  ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
+	ts << (QString("       %1<%2>             ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
  	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
 	
 #if defined(_WIN32) && !defined(_CONSOLE)

From 9aa5b6951f2ef8fd187a2c9e99fe491dcb95fffb Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Thu, 6 Aug 2015 15:30:32 +0200
Subject: [PATCH 6/7] command line arguments for script unified into
 --python-arg- ; added command-line double dash for options end

---
 scribus/scribusapp.cpp | 67 +++++++++++++++++++++++++-------------------------
 1 file changed, 34 insertions(+), 33 deletions(-)

diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 46b7508..6be0cbc 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -72,8 +72,8 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK "--upgradecheck"
 #define ARG_TESTS "--tests"
 #define ARG_PYTHONSCRIPT "--python-script"
-#define ARG_SCRIPTARG_PREFIX "--python-arg-"   // directly followed by <param name> <param value>
-#define ARG_SCRIPTFLAG_PREFIX "--python-flag-" // directly followed by <param name>
+#define ARG_SCRIPTARG_PREFIX "--python-arg-" // directly followed by <param name> <param value>
+#define CMD_OPTIONS_END "--"   				 // end of command line options
 
 #define ARG_VERSION_SHORT "-v"
 #define ARG_HELP_SHORT "-h"
@@ -218,8 +218,8 @@ void ScribusQApp::parseCommandLine()
 	useGUI = true;
 	//We are going to run something other than command line help
 	QString qtARG_SCRIPTARG_PREFIX = QString(ARG_SCRIPTARG_PREFIX);
-	QString qtARG_SCRIPTFLAG_PREFIX = QString(ARG_SCRIPTFLAG_PREFIX);
-	for(int i = 1; i < argsc; i++) {
+	int i = 1;
+	for( ; i < argsc; i++) { //handle all options (not positional parameters)
 		arg = args[i];
 
 		if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++i < argsc)) {
@@ -247,7 +247,7 @@ void ScribusQApp::parseCommandLine()
 			if (!QFileInfo(prefsUserFile).exists()) {
 				showHeader();
 				if (prefsUserFile.left(1) == "-" || prefsUserFile.left(2) == "--") {
-					std::cout << tr("Invalid argument: ").toLocal8Bit().data() << prefsUserFile.toLocal8Bit().data() << std::endl;
+					std::cout << tr("Invalid option: ").toLocal8Bit().data() << prefsUserFile.toLocal8Bit().data() << std::endl;
 				} else {
 					std::cout << tr("File %1 does not exist, aborting.").arg(prefsUserFile).toLocal8Bit().data() << std::endl;
 				}
@@ -264,7 +264,7 @@ void ScribusQApp::parseCommandLine()
 			if (!QFileInfo(pythonScript).exists()) {
 				showHeader();
 				if (pythonScript.left(1) == "-" || pythonScript.left(2) == "--") {
-					std::cout << tr("Invalid argument: ").toLocal8Bit().data() << pythonScript.toLocal8Bit().data() << std::endl;
+					std::cout << tr("Invalid option: ").toLocal8Bit().data() << pythonScript.toLocal8Bit().data() << std::endl;
 				} else {
 					std::cout << tr("File %1 does not exist, aborting.").arg(pythonScript).toLocal8Bit().data() << std::endl;
 				}
@@ -273,32 +273,32 @@ void ScribusQApp::parseCommandLine()
 			} else {
 				++i;
 			}
+		} else if (arg == CMD_OPTIONS_END) { //double dash, indicates end of command line options, see http://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash
+			i++;
+			break;
 		} else if (arg.startsWith(qtARG_SCRIPTARG_PREFIX)) {
-	 		QString arg_name = arg.mid(qtARG_SCRIPTARG_PREFIX.size()-1); //-1 to get the dash from prefix
-	 		QString arg_value = QFile::decodeName(args[++i].toLocal8Bit());
-	 		//std::cout << tr("got one script argument: %1 with value %2").arg(arg_name).arg(arg_value).toLocal8Bit().data() << std::endl;				
-	 		pythonScriptArgs.append(arg_name);
-	 		pythonScriptArgs.append(arg_value);
-		} else if (arg.startsWith(qtARG_SCRIPTFLAG_PREFIX)) {
-	 		QString arg_name = arg.mid(qtARG_SCRIPTFLAG_PREFIX.size()-1); //-1 to get the dash from prefix
-	 		//std::cout << tr("got one script flag: %1 ").arg(arg_name).toLocal8Bit().data() << std::endl;
-	 		pythonScriptArgs.append(arg_name);	 		
-		} else { // (last) positional argument
-			fileName = QFile::decodeName(args[i].toLocal8Bit());
-			if (!QFileInfo(fileName).exists()) {
-				showHeader();
-				if (fileName.left(1) == "-" || fileName.left(2) == "--") {
-					std::cout << tr("Invalid argument: %1").arg(fileName).toLocal8Bit().data() << std::endl;
-				} else {
-					std::cout << tr("File %1 does not exist, aborting.").arg(fileName).toLocal8Bit().data() << std::endl;
-				}
-				showUsage();
-				std::exit(EXIT_FAILURE);
+			pythonScriptArgs.append( arg.mid(qtARG_SCRIPTARG_PREFIX.size()-1) ); //-1 to get the dash from prefix
+			if (!args[i+1].startsWith("-")) {
+				pythonScriptArgs.append( QFile::decodeName(args[++i].toLocal8Bit()) );
 			}
-			else
-			{
-				filesToLoad.append(fileName);
+		} else { //argument is not a known option, but either positional parameter or invalid.
+			break;
+		}
+	}
+	//remaining arguments, if any
+	for ( ; i<argsc; i++) {
+		fileName = QFile::decodeName(args[i].toLocal8Bit());
+		if (!QFileInfo(fileName).exists()) {
+			showHeader();
+			if (fileName.left(1) == "-" || fileName.left(2) == "--") {
+				std::cout << tr("Invalid argument: %1").arg(fileName).toLocal8Bit().data() << std::endl;
+			} else {
+				std::cout << tr("File %1 does not exist, aborting.").arg(fileName).toLocal8Bit().data() << std::endl;
 			}
+			showUsage();
+			std::exit(EXIT_FAILURE);
+		} else {
+			filesToLoad.append(fileName);
 		}
 	}
 }
@@ -501,7 +501,7 @@ void ScribusQApp::showUsage()
 	QFile f;
 	f.open(stderr, QIODevice::WriteOnly);
 	QTextStream ts(&f);
-	ts << tr("Usage: scribus [option ... ] [file]") ; endl(ts);
+	ts << tr("Usage: scribus [options] [files]") ; endl(ts); endl(ts);
 	ts << tr("Options:") ; endl(ts);
 	printArgLine(ts, ARG_FONTINFO_SHORT, ARG_FONTINFO, tr("Show information on the console when fonts are being loaded") );
 	printArgLine(ts, ARG_HELP_SHORT, ARG_HELP, tr("Print help (this message) and exit") );
@@ -514,9 +514,10 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
-	ts << (QString("       %1<%2> <%3>  ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
-	ts << (QString("       %1<%2>             ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
- 	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
+	ts << (QString("       %1<%2> [%3]  ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script, with an optional value, no effect without -py"); endl(ts);
+	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
+	ts << (QString("     %1").arg(CMD_OPTIONS_END,-39)) << tr("Explicit end of command line options"); endl(ts);
+ 	
 	
 #if defined(_WIN32) && !defined(_CONSOLE)
 	printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") );

From 6752a35215de21ff5b0b1e3530245f55c43bb655 Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Wed, 19 Aug 2015 17:09:19 +0200
Subject: [PATCH 7/7] polishing code for command line arguments for python
 script: overloading

---
 scribus/plugins/scriptplugin/scriptercore.cpp |  6 ++---
 scribus/plugins/scriptplugin/scriptercore.h   |  2 +-
 scribus/scribusapp.cpp                        | 32 +++++++++++++--------------
 3 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index 41b2949..f1f4594 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -230,10 +230,10 @@ void ScripterCore::RecentScript(QString fn)
 void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 {
 	QStringList arguments = QStringList();
-	slotRunScriptFileArgs(fileName, arguments, inMainInterpreter);
+	slotRunScriptFile(fileName, arguments, inMainInterpreter);
 }
 
-void ScripterCore::slotRunScriptFileArgs(QString fileName, QStringList arguments, bool inMainInterpreter)
+void ScripterCore::slotRunScriptFile(QString fileName, QStringList arguments, bool inMainInterpreter)
 /** run "filename" python script with the additional arguments provided in "arguments" */
 {
 	// Prevent two scripts to be run concurrently or face crash!
@@ -376,7 +376,7 @@ void ScripterCore::slotRunPythonScript()
 {
 	if (!ScQApp->pythonScript.isNull())
 	{
-		slotRunScriptFileArgs(ScQApp->pythonScript, ScQApp->pythonScriptArgs, true);
+		slotRunScriptFile(ScQApp->pythonScript, ScQApp->pythonScriptArgs, true);
 		FinishScriptRun();
 	}
 }
diff --git a/scribus/plugins/scriptplugin/scriptercore.h b/scribus/plugins/scriptplugin/scriptercore.h
index b8e2edf..72e5461 100644
--- a/scribus/plugins/scriptplugin/scriptercore.h
+++ b/scribus/plugins/scriptplugin/scriptercore.h
@@ -39,7 +39,7 @@ public slots:
 	void StdScript(QString filebasename);
 	void RecentScript(QString fn);
 	void slotRunScriptFile(QString fileName, bool inMainInterpreter = false);
-	void slotRunScriptFileArgs(QString fileName, QStringList arguments, bool inMainInterpreter = false);
+	void slotRunScriptFile(QString fileName, QStringList arguments, bool inMainInterpreter = false);
 	void slotRunPythonScript(); // needed for running python script from CLI
 	void slotRunScript(const QString script);
 	void slotInteractiveScript(bool);
diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 6be0cbc..8870934 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -218,11 +218,11 @@ void ScribusQApp::parseCommandLine()
 	useGUI = true;
 	//We are going to run something other than command line help
 	QString qtARG_SCRIPTARG_PREFIX = QString(ARG_SCRIPTARG_PREFIX);
-	int i = 1;
-	for( ; i < argsc; i++) { //handle all options (not positional parameters)
-		arg = args[i];
+	int argi = 1;
+	for( ; argi < argsc; argi++) { //handle options (not positional parameters)
+		arg = args[argi];
 
-		if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++i < argsc)) {
+		if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++argi < argsc)) {
 			continue;
 		} else if ( arg == ARG_CONSOLE || arg == ARG_CONSOLE_SHORT ) {
 			continue;
@@ -238,12 +238,12 @@ void ScribusQApp::parseCommandLine()
 			showFontInfo=true;
 		} else if (arg == ARG_PROFILEINFO || arg == ARG_PROFILEINFO_SHORT) {
 			showProfileInfo=true;
-		} else if ((arg == ARG_DISPLAY || arg==ARG_DISPLAY_SHORT || arg==ARG_DISPLAY_QT) && ++i < argsc) {
+		} else if ((arg == ARG_DISPLAY || arg==ARG_DISPLAY_SHORT || arg==ARG_DISPLAY_QT) && ++argi < argsc) {
 			// allow setting of display, QT expect the option -display <display_name> so we discard the
 			// last argument. FIXME: Qt only understands -display not --display and -d , we need to work
 			// around this.
 		} else if (arg == ARG_PREFS || arg == ARG_PREFS_SHORT) {
-			prefsUserFile = QFile::decodeName(args[i + 1].toLocal8Bit());
+			prefsUserFile = QFile::decodeName(args[argi + 1].toLocal8Bit());
 			if (!QFileInfo(prefsUserFile).exists()) {
 				showHeader();
 				if (prefsUserFile.left(1) == "-" || prefsUserFile.left(2) == "--") {
@@ -254,40 +254,40 @@ void ScribusQApp::parseCommandLine()
 				showUsage();
 				std::exit(EXIT_FAILURE);
 			} else {
-				++i;
+				++argi;
 			}
 		} else if (strncmp(arg.toLocal8Bit().data(),"-psn_",4) == 0)
 		{
 			// Andreas Vox: Qt/Mac has -psn_blah flags that must be accepted.
 		} else if (arg == ARG_PYTHONSCRIPT || arg == ARG_PYTHONSCRIPT_SHORT) {
-			pythonScript = QFile::decodeName(args[i + 1].toLocal8Bit());
+			pythonScript = QFile::decodeName(args[argi + 1].toLocal8Bit());
 			if (!QFileInfo(pythonScript).exists()) {
 				showHeader();
 				if (pythonScript.left(1) == "-" || pythonScript.left(2) == "--") {
-					std::cout << tr("Invalid option: ").toLocal8Bit().data() << pythonScript.toLocal8Bit().data() << std::endl;
+					std::cout << tr("Invalid argument: ").toLocal8Bit().data() << pythonScript.toLocal8Bit().data() << std::endl;
 				} else {
 					std::cout << tr("File %1 does not exist, aborting.").arg(pythonScript).toLocal8Bit().data() << std::endl;
 				}
 				showUsage();
 				std::exit(EXIT_FAILURE);
 			} else {
-				++i;
+				++argi;
 			}
 		} else if (arg == CMD_OPTIONS_END) { //double dash, indicates end of command line options, see http://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash
-			i++;
+			argi++;
 			break;
 		} else if (arg.startsWith(qtARG_SCRIPTARG_PREFIX)) {
 			pythonScriptArgs.append( arg.mid(qtARG_SCRIPTARG_PREFIX.size()-1) ); //-1 to get the dash from prefix
-			if (!args[i+1].startsWith("-")) {
-				pythonScriptArgs.append( QFile::decodeName(args[++i].toLocal8Bit()) );
+			if (!args[argi+1].startsWith("-")) {
+				pythonScriptArgs.append( QFile::decodeName(args[++argi].toLocal8Bit()) );
 			}
 		} else { //argument is not a known option, but either positional parameter or invalid.
 			break;
 		}
 	}
-	//remaining arguments, if any
-	for ( ; i<argsc; i++) {
-		fileName = QFile::decodeName(args[i].toLocal8Bit());
+	//remaining (positional) arguments, if any
+	for ( ; argi<argsc; argi++) {
+		fileName = QFile::decodeName(args[argi].toLocal8Bit());
 		if (!QFileInfo(fileName).exists()) {
 			showHeader();
 			if (fileName.left(1) == "-" || fileName.left(2) == "--") {

berteh

2015-08-19 15:23

reporter  

cmdtest.py (1,071 bytes)   
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys

import sys, scribus, traceback

def main(argv):
    print "\nYES! main is reached in cmdtest script\ncheck out the arguments it's got:", " ".join(argv)
    if scribus.haveDoc():
        print "\nthis script could modify the current document ", scribus.getDocName(), " automatically"
    else:
        print "\nno document is currently open in scribus"

def main_wrapper(argv):
    try:
        if scribus.haveDoc():
            scribus.setRedraw(False)
            #scribus.statusMessage("ń•eadless test")
            #scribus.progressReset()
        main(argv)
    except Exception:
        print "error: "+traceback.format_exc()
    finally:
        # Exit neatly even if the script terminated with an exception,
        # so we leave the progress bar and status bar blank and make sure
        # drawing is enabled.
        if scribus.haveDoc():        
            scribus.setRedraw(True)
        scribus.statusMessage('')
        scribus.progressReset()

if __name__ == '__main__':
    main_wrapper(sys.argv)
cmdtest.py (1,071 bytes)   

berteh

2015-08-19 15:24

reporter   ~0036069

History and discussions at https://github.com/scribusproject/scribus/pull/19

Kunda

2015-08-19 20:58

updater   ~0036070

Berteh! Fantastic. I've submitted this to the Mailing list to get more feedback from the community. The more testers the better. Thanks so much for the contribution!

william

2015-08-20 03:29

updater  

storydeptharg.py (2,426 bytes)   
#!/usr/bin/env python
# -*- coding: utf-8 -*-

""" 

Return the depth of the text in the file sample.txt

Run with the command line
	scribus -g -py storydeptharg.py --python-arg-storyfile sample.txt depthtemplate.sla

sample.txt is the text file to measure.
depthtemplate.sla is a document with a single, empty text frame.

Tested with scribus 1.5.0

Author: William Bader

11Aug14 wb initial version
15Dec14 wb get the file name from STORYFILE
19Aug15 wb get the file name from the command line

"""

# check that the script is running from inside scribus

try:
	from scribus import *
    
except ImportError:
	print 'This script only runs from within Scribus.'
	sys.exit(1)

# get the os module

try:
	import os

except ImportError:
	print 'Could not import the os module.'
	sys.exit(1)

# get the sys module

try:
	import sys

except ImportError:
	print 'Could not import the sys module.'
	sys.exit(1)

def main(argv):

	# The first text frame of the current document defines the style

	try:
		storyfile = ""

		i = 1;
		while i < len(argv):
			if argv[i] == "-storyfile":
				storyfile = argv[i+1]
			i = i + 1

		if storyfile == "":
			print 'Warning: -storyfile not given, checking environment'
			storyfile = os.environ['STORYFILE']

	except:
		print 'Error: Pass the story file with the --python-arg-storyfile argument or the STORYFILE environment variable'
		return

	try:
		storytext = open(storyfile, 'r').read()
	except:
		print 'Error: Story file "', storyfile, '" not found.'
		return

	try:
		deselectAll()
		selectObject('Text1')
	except:
		print 'Error: The document does not have an object called Text1.'
		return

	try:
		setText(storytext)
	except:
		print 'Error: The document does not have a text frame.'
		return

	try:
		ov = textOverflows()
		width, depth = getSize()
		if ov:
			baddepth = depth
			gooddepth = 100
		else:
			baddepth = 0
			gooddepth = depth
		while baddepth < gooddepth:
			trydepth = (baddepth + gooddepth) / 2
			sizeObject(width, trydepth)
			tryov = textOverflows()
			if tryov:
				baddepth = trydepth + 0.0001
			else:
				baddepth = baddepth + 0.0001
				gooddepth = trydepth
		sizeObject(width, gooddepth)

		print 'The depth is ', str(gooddepth)
	except:
		print 'Error: not a text frame.'

# start the script

if __name__ == '__main__':
	if haveDoc():
		main(sys.argv)
	else:
		print 'Error: You need to have a document open before you can run this script succesfully.'
storydeptharg.py (2,426 bytes)   

william

2015-08-20 03:41

updater   ~0036071

It works for me. I uploaded a slightly longer test script.
The script calculates the length of text.
Put the text in a normal file.
Create a Scribus document with an empty text frame.
Run the command
scribus -g -py storydeptharg.py --python-arg-storyfile sample.txt depthtemplate.sla

If I print the arguments, I get an extra argv[1] of "ext".
i 0 storydeptharg.py
i 1 ext
i 2 -storyfile
i 3 sample.txt

In an earlier version of the script, I passed arguments through environment variables.

william

2015-08-20 05:34

updater   ~0036072

I read the patches. argv[1] is "ext" when the script is running in the main interpreter and "sub" when the script is running in a subinterpreter.

berteh

2015-08-20 09:40

reporter   ~0036073

indeed william.

that's legacy from scribus and i was not brave enough to remove it in case it was needed elsewhere... My guess is on distinguishing between scripts in scripter consoles and others, but it's only a quick guess.

Shall the script author handle it, or can we safely remove that "artificial" argument addition by scribus?

william

2015-08-20 16:26

updater   ~0036074

I think that it is OK to leave it as long as it is documented. I've never checked the command line on a script, but if that parameter was there before, removing it might break old scripts.

berteh

2015-08-21 10:56

reporter   ~0036075

one way to handle this extra argument in the script is to remove it:

#handle arguments
#discard argv[1] if it is 'ext' or 'sub', that is added by Scribus when calling an external script
if (sys.argv[1] == 'ext' or sys.argv[1] == 'sub'):
    del sys.argv[1]

args = parser.parse_args()

Kunda

2015-08-21 18:11

updater   ~0036076

Any comments from the devs?

Kunda

2015-08-27 22:44

updater   ~0036107

It may be less overwhelming to see the diffs side-by-side: https://github.com/scribusproject/scribus/pull/19/files

Kunda

2015-08-29 13:43

updater   ~0036117

Jean, any comments on this patch ?

berteh

2015-09-02 07:24

reporter   ~0036132

Thanks Kunda for the pushes!
Is there anything I can do to help have this patch accepted?

JLuc

2015-09-02 07:47

developer   ~0036134

berteh : keep your irc client open and connected to #scribus chan on freenode, and talk to jghali or MrB when they're there (in the evening).

berteh

2015-09-02 09:19

reporter   ~0036135

ok, thanks JLuc.

cbradney

2015-09-03 19:24

administrator   ~0036140

Jean and I have reviewed.

Qt doesn't require things like : QStringList arguments = QStringList();

As for the Python side.. we'd prefer syntax of --python-arg name value, instead of --python-arg-name value. Possible?

thanks
Craig

berteh

2015-09-03 20:27

reporter   ~0036143

Last edited: 2015-09-03 20:40

thanks for the review Jean & Craig!

syntax --python-arg name value is indeed possible. It would just prevent to pass some argument with a name that indicates a "header" attribute in Scribus command-line parsing, namely: version, help, availlang, upgradecheck and tests.

indeed: the command below would pass the "-v" to scribus and display it's version, and not pass it to the script (for instance to set some "verbosity" level), as the "-v" is a header argument (scribusapp.cpp l.217).

scribus -g -py ~/myScribusScript.py --python-arg -v 6 -pa --title "title from command line" ~/all*.sla

If that restriction is fine by you, then kindly use the modified patch attached (that adds short "-pa" as well, since it's now easy to handle ;) - cmdline_--python-arg_name_value.patch



The examples provided earlier would become:

simple use:
./scribus -g -py ~/cmdtest.py --python-arg -flag1 --python-arg -arg1 value1 ~/some1.sla

or more complex (with -- to distinguish that last parameter(s) are file(s) to be opened by scribus before running the script, and not arguments to be passed to the script.)

./scribus -g -py ~/cmdtest.py --python-arg -arg1 value1 --python-arg -flag1 -- ~/some1.sla



A possible workaround to that restriction is to assume the argument name must start with a dash at the script call, and omit that dash in the scribus command line, thus not detecting it as a scribus (short) header argument. The dash would then be added automatically before the name that is passed to the script.

scribus -g -py ~/myScribusScript.py --python-arg v 6 -pa -title "title from command line" ~/all*.sla

I like this last option less as it seems not clean, and enforces the use of dashes in the script arguments... but if you want it i can implement that instead.

Berteh.

berteh

2015-09-03 20:36

reporter  

cmdline_--python-arg_name_value.patch (36,615 bytes)   
From d019992c0798595d3d422672a21e3441b3cc6838 Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Wed, 5 Aug 2015 16:00:45 +0200
Subject: [PATCH 1/9] added command-line arguments to be passed to python
 script, some fix needed in scriptercore.cpp#283.

---
 scribus/plugins/scriptplugin/scriptercore.cpp | 30 +++++++++++++++++++++++----
 scribus/plugins/scriptplugin/scriptercore.h   |  3 ++-
 scribus/scribusapp.cpp                        | 22 ++++++++++++++++++--
 scribus/scribusapp.h                          |  2 ++
 4 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index 3903617..c27517b 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -9,6 +9,7 @@ for which a new license (GPL+exception) is in place.
 #include <QGlobalStatic>
 #include <QWidget>
 #include <QString>
+#include <QStringList>
 #include <QApplication>
 #include <QMessageBox>
 #include <QTextCodec>
@@ -37,7 +38,7 @@ for which a new license (GPL+exception) is in place.
 #include "prefscontext.h"
 #include "prefstable.h"
 #include "prefsmanager.h"
-#include "scribusapp.h" // need it to acces ScQApp->pythonScript
+#include "scribusapp.h" // need it to acces ScQApp->pythonScript & ScQApp->pythonScriptArgs
 
 ScripterCore::ScripterCore(QWidget* parent)
 {
@@ -228,6 +229,12 @@ void ScripterCore::RecentScript(QString fn)
 
 void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 {
+	QStringList arguments = QStringList();
+	slotRunScriptFileArgs(fileName, arguments, inMainInterpreter);
+}
+
+void ScripterCore::slotRunScriptFileArgs(QString fileName, QStringList arguments, bool inMainInterpreter)
+{
 	// Prevent two scripts to be run concurrently or face crash!
 	if (ScCore->primaryMainWindow()->scriptIsRunning())
 		return;
@@ -252,16 +259,31 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 		// Init the scripter module in the sub-interpreter
 		initscribus(ScCore->primaryMainWindow());
 	}
+
+	// handle additional arguments
+	bool argsExtra = !(arguments.isEmpty());	
+	int argsc = 0;
+	if (argsExtra) 
+	{
+		argsc = arguments.size();
+		//std::cout << tr("running script with %1 arguments").arg(argsc).toLocal8Bit().data() << std::endl;
+	}
 	// Make sure sys.argv[0] is the path to the script
-	char* comm[2];
+	char* comm[2+argsc];
 	comm[0] = na.data();
+	
 	// and tell the script if it's running in the main intepreter or
 	// a subinterpreter using the second argument, ie sys.argv[1]
 	if (inMainInterpreter)
 		comm[1] = const_cast<char*>("ext");
 	else
 		comm[1] = const_cast<char*>("sub");
-	PySys_SetArgv(2, comm);
+	for (int j = 0; j < argsc; ++j)
+	{
+		comm[2+j] = arguments.at(j).toLocal8Bit().data()  ; // TODO fix here: some copy is needed, otherwise all comm[>2] point to same (last) value for j.
+	}
+	PySys_SetArgv(2+argsc, comm);
+	
 	// call python script
 	PyObject* m = PyImport_AddModule((char*)"__main__");
 	if (m == NULL)
@@ -357,7 +379,7 @@ void ScripterCore::slotRunPythonScript()
 {
 	if (!ScQApp->pythonScript.isNull())
 	{
-		slotRunScriptFile(ScQApp->pythonScript, true);
+		slotRunScriptFileArgs(ScQApp->pythonScript, ScQApp->pythonScriptArgs, true);
 		FinishScriptRun();
 	}
 }
diff --git a/scribus/plugins/scriptplugin/scriptercore.h b/scribus/plugins/scriptplugin/scriptercore.h
index 1e929f4..b8e2edf 100644
--- a/scribus/plugins/scriptplugin/scriptercore.h
+++ b/scribus/plugins/scriptplugin/scriptercore.h
@@ -39,8 +39,9 @@ public slots:
 	void StdScript(QString filebasename);
 	void RecentScript(QString fn);
 	void slotRunScriptFile(QString fileName, bool inMainInterpreter = false);
+	void slotRunScriptFileArgs(QString fileName, QStringList arguments, bool inMainInterpreter = false);
 	void slotRunPythonScript(); // needed for running python script from CLI
-	void slotRunScript(const QString Script);
+	void slotRunScript(const QString script);
 	void slotInteractiveScript(bool);
 	void slotExecute();
 	/*! \brief Show docstring of the script to the user.
diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index fec4055..9c52c04 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -32,6 +32,7 @@ for which a new license (GPL+exception) is in place.
 #include <QLibraryInfo>
 #include <QLocale>
 #include <QString>
+#include <QStringList>
 #include <QTextCodec>
 #include <QTextStream>
 #include <QTranslator>
@@ -71,6 +72,8 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK "--upgradecheck"
 #define ARG_TESTS "--tests"
 #define ARG_PYTHONSCRIPT "--python-script"
+#define ARG_SCRIPTARG_PREFIX "--python-arg"   // directly followed by <param name> <param value>
+#define ARG_SCRIPTFLAG_PREFIX "--python-flag" // directly followed by <param name>
 
 #define ARG_VERSION_SHORT "-v"
 #define ARG_HELP_SHORT "-h"
@@ -108,6 +111,7 @@ ScribusQApp::ScribusQApp( int & argc, char ** argv ) : QApplication(argc, argv),
 	m_scDLMgr = 0;
 	m_ScCore = NULL;
 	initDLMgr();
+
 }
 
 ScribusQApp::~ScribusQApp()
@@ -213,6 +217,8 @@ void ScribusQApp::parseCommandLine()
 		std::exit(EXIT_SUCCESS);
 	useGUI = true;
 	//We are going to run something other than command line help
+	QString qtARG_SCRIPTARG_PREFIX = QString(ARG_SCRIPTARG_PREFIX);
+	QString qtARG_SCRIPTFLAG_PREFIX = QString(ARG_SCRIPTFLAG_PREFIX);
 	for(int i = 1; i < argsc; i++) {
 		arg = args[i];
 
@@ -267,7 +273,17 @@ void ScribusQApp::parseCommandLine()
 			} else {
 				++i;
 			}
-		} else {
+		} else if (arg.startsWith(qtARG_SCRIPTARG_PREFIX)) {
+	 		QString arg_name = arg.mid(qtARG_SCRIPTARG_PREFIX.size());
+	 		QString arg_value = QFile::decodeName(args[++i].toLocal8Bit());
+	 		//std::cout << tr("got one script argument: %1 with value %2").arg(arg_name).arg(arg_value).toLocal8Bit().data() << std::endl;				
+	 		pythonScriptArgs.append(arg_name);
+	 		pythonScriptArgs.append(arg_value);
+		} else if (arg.startsWith(qtARG_SCRIPTFLAG_PREFIX)) {
+	 		QString arg_name = arg.mid(qtARG_SCRIPTFLAG_PREFIX.size());
+	 		//std::cout << tr("got one script flag: %1 ").arg(arg_name).toLocal8Bit().data() << std::endl;
+	 		pythonScriptArgs.append(arg_name);	 		
+		} else { // (last) positional argument
 			fileName = QFile::decodeName(args[i].toLocal8Bit());
 			if (!QFileInfo(fileName).exists()) {
 				showHeader();
@@ -498,7 +514,9 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
-	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
+	ts << (QString("     %1<%2> <%3>    ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
+	ts << (QString("     %1<%2>               ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
+ 	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
 	
 #if defined(_WIN32) && !defined(_CONSOLE)
 	printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") );
diff --git a/scribus/scribusapp.h b/scribus/scribusapp.h
index 2857306..7fc9f7f 100644
--- a/scribus/scribusapp.h
+++ b/scribus/scribusapp.h
@@ -23,6 +23,7 @@ for which a new license (GPL+exception) is in place.
 #define SCRIBUSAPP_H
 #include <QApplication>
 #include <QString>
+#include <QStringList>
 
 #include "scribusapi.h"
 
@@ -71,6 +72,7 @@ class SCRIBUS_API ScribusQApp : public QApplication
 		const QString& currGUILanguage() { return GUILang; }
 		ScDLManager* dlManager() { return m_scDLMgr; }
 		QString pythonScript; // script to be run in python from CLI
+		QStringList pythonScriptArgs; // command line arguments and flags for script from CLI
 
 	private:
 		ScribusCore* m_ScCore;

From f4c7e635c738fb35114f9ffd6112c0e38990d55a Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Wed, 5 Aug 2015 17:05:56 +0200
Subject: [PATCH 2/9] help message layout

---
 scribus/scribusapp.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 9c52c04..77be088 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -514,8 +514,8 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
-	ts << (QString("     %1<%2> <%3>    ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
-	ts << (QString("     %1<%2>               ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
+	ts << (QString("       %1<%2> <%3>   ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
+	ts << (QString("       %1<%2>              ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
  	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
 	
 #if defined(_WIN32) && !defined(_CONSOLE)

From 35e17efbc051678d5d78f4958a08ac6bc7079bc0 Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Wed, 5 Aug 2015 17:07:11 +0200
Subject: [PATCH 3/9] use QStringList to call python script with arguments

---
 scribus/plugins/scriptplugin/scriptercore.cpp | 26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index c27517b..f6456c4 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -234,6 +234,7 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 }
 
 void ScripterCore::slotRunScriptFileArgs(QString fileName, QStringList arguments, bool inMainInterpreter)
+/** run "filename" python script with the additional arguments provided in "arguments" */
 {
 	// Prevent two scripts to be run concurrently or face crash!
 	if (ScCore->primaryMainWindow()->scriptIsRunning())
@@ -260,29 +261,24 @@ void ScripterCore::slotRunScriptFileArgs(QString fileName, QStringList arguments
 		initscribus(ScCore->primaryMainWindow());
 	}
 
-	// handle additional arguments
-	bool argsExtra = !(arguments.isEmpty());	
-	int argsc = 0;
-	if (argsExtra) 
-	{
-		argsc = arguments.size();
-		//std::cout << tr("running script with %1 arguments").arg(argsc).toLocal8Bit().data() << std::endl;
-	}
 	// Make sure sys.argv[0] is the path to the script
-	char* comm[2+argsc];
-	comm[0] = na.data();
+	arguments.prepend(na.data());
 	
 	// and tell the script if it's running in the main intepreter or
 	// a subinterpreter using the second argument, ie sys.argv[1]
 	if (inMainInterpreter)
-		comm[1] = const_cast<char*>("ext");
+		arguments.insert(1,QString("ext"));
 	else
-		comm[1] = const_cast<char*>("sub");
-	for (int j = 0; j < argsc; ++j)
+		arguments.insert(1,QString("sub"));
+
+	//convert arguments (QListString) to char** for Python bridge
+	/* typically arguments == ['path/to/script.py','ext','--argument1','valueforarg1','--flag']*/
+	char *comm[arguments.size()];
+	for (int i = 0; i < arguments.size(); i++)
 	{
-		comm[2+j] = arguments.at(j).toLocal8Bit().data()  ; // TODO fix here: some copy is needed, otherwise all comm[>2] point to same (last) value for j.
+		comm[i] = arguments.at(i).mid(0).toLocal8Bit().data(); // TODO fix here: unexpected border effects. all comm[*] point to same (last) value for i... despite mid() that should create a copy.
 	}
-	PySys_SetArgv(2+argsc, comm);
+	PySys_SetArgv(arguments.size(), comm);
 	
 	// call python script
 	PyObject* m = PyImport_AddModule((char*)"__main__");

From 50fca9e4feffa2337a1c8de5f0e99f9bf23bb248 Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Wed, 5 Aug 2015 18:31:30 +0200
Subject: [PATCH 4/9] fix arguments passing from command line to python script

---
 scribus/plugins/scriptplugin/scriptercore.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index f6456c4..41b2949 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -276,7 +276,8 @@ void ScripterCore::slotRunScriptFileArgs(QString fileName, QStringList arguments
 	char *comm[arguments.size()];
 	for (int i = 0; i < arguments.size(); i++)
 	{
-		comm[i] = arguments.at(i).mid(0).toLocal8Bit().data(); // TODO fix here: unexpected border effects. all comm[*] point to same (last) value for i... despite mid() that should create a copy.
+		comm[i] = new char[arguments.at(i).toLocal8Bit().size()+1]; //+1 to allow adding '\0'. may be useless, don't know how to check.
+		strcpy(comm[i],arguments.at(i).toLocal8Bit().data()+'\0');
 	}
 	PySys_SetArgv(arguments.size(), comm);
 	

From b90f29c7bdb9908c4addb31b8486c8ec8197650d Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Thu, 6 Aug 2015 11:32:17 +0200
Subject: [PATCH 5/9] add dash to prefix for command line arguments to python
 script

---
 scribus/scribusapp.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 77be088..46b7508 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -72,8 +72,8 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK "--upgradecheck"
 #define ARG_TESTS "--tests"
 #define ARG_PYTHONSCRIPT "--python-script"
-#define ARG_SCRIPTARG_PREFIX "--python-arg"   // directly followed by <param name> <param value>
-#define ARG_SCRIPTFLAG_PREFIX "--python-flag" // directly followed by <param name>
+#define ARG_SCRIPTARG_PREFIX "--python-arg-"   // directly followed by <param name> <param value>
+#define ARG_SCRIPTFLAG_PREFIX "--python-flag-" // directly followed by <param name>
 
 #define ARG_VERSION_SHORT "-v"
 #define ARG_HELP_SHORT "-h"
@@ -274,13 +274,13 @@ void ScribusQApp::parseCommandLine()
 				++i;
 			}
 		} else if (arg.startsWith(qtARG_SCRIPTARG_PREFIX)) {
-	 		QString arg_name = arg.mid(qtARG_SCRIPTARG_PREFIX.size());
+	 		QString arg_name = arg.mid(qtARG_SCRIPTARG_PREFIX.size()-1); //-1 to get the dash from prefix
 	 		QString arg_value = QFile::decodeName(args[++i].toLocal8Bit());
 	 		//std::cout << tr("got one script argument: %1 with value %2").arg(arg_name).arg(arg_value).toLocal8Bit().data() << std::endl;				
 	 		pythonScriptArgs.append(arg_name);
 	 		pythonScriptArgs.append(arg_value);
 		} else if (arg.startsWith(qtARG_SCRIPTFLAG_PREFIX)) {
-	 		QString arg_name = arg.mid(qtARG_SCRIPTFLAG_PREFIX.size());
+	 		QString arg_name = arg.mid(qtARG_SCRIPTFLAG_PREFIX.size()-1); //-1 to get the dash from prefix
 	 		//std::cout << tr("got one script flag: %1 ").arg(arg_name).toLocal8Bit().data() << std::endl;
 	 		pythonScriptArgs.append(arg_name);	 		
 		} else { // (last) positional argument
@@ -514,8 +514,8 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
-	ts << (QString("       %1<%2> <%3>   ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
-	ts << (QString("       %1<%2>              ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
+	ts << (QString("       %1<%2> <%3>  ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
+	ts << (QString("       %1<%2>             ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
  	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
 	
 #if defined(_WIN32) && !defined(_CONSOLE)

From 9aa5b6951f2ef8fd187a2c9e99fe491dcb95fffb Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Thu, 6 Aug 2015 15:30:32 +0200
Subject: [PATCH 6/9] command line arguments for script unified into
 --python-arg- ; added command-line double dash for options end

---
 scribus/scribusapp.cpp | 67 +++++++++++++++++++++++++-------------------------
 1 file changed, 34 insertions(+), 33 deletions(-)

diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 46b7508..6be0cbc 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -72,8 +72,8 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK "--upgradecheck"
 #define ARG_TESTS "--tests"
 #define ARG_PYTHONSCRIPT "--python-script"
-#define ARG_SCRIPTARG_PREFIX "--python-arg-"   // directly followed by <param name> <param value>
-#define ARG_SCRIPTFLAG_PREFIX "--python-flag-" // directly followed by <param name>
+#define ARG_SCRIPTARG_PREFIX "--python-arg-" // directly followed by <param name> <param value>
+#define CMD_OPTIONS_END "--"   				 // end of command line options
 
 #define ARG_VERSION_SHORT "-v"
 #define ARG_HELP_SHORT "-h"
@@ -218,8 +218,8 @@ void ScribusQApp::parseCommandLine()
 	useGUI = true;
 	//We are going to run something other than command line help
 	QString qtARG_SCRIPTARG_PREFIX = QString(ARG_SCRIPTARG_PREFIX);
-	QString qtARG_SCRIPTFLAG_PREFIX = QString(ARG_SCRIPTFLAG_PREFIX);
-	for(int i = 1; i < argsc; i++) {
+	int i = 1;
+	for( ; i < argsc; i++) { //handle all options (not positional parameters)
 		arg = args[i];
 
 		if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++i < argsc)) {
@@ -247,7 +247,7 @@ void ScribusQApp::parseCommandLine()
 			if (!QFileInfo(prefsUserFile).exists()) {
 				showHeader();
 				if (prefsUserFile.left(1) == "-" || prefsUserFile.left(2) == "--") {
-					std::cout << tr("Invalid argument: ").toLocal8Bit().data() << prefsUserFile.toLocal8Bit().data() << std::endl;
+					std::cout << tr("Invalid option: ").toLocal8Bit().data() << prefsUserFile.toLocal8Bit().data() << std::endl;
 				} else {
 					std::cout << tr("File %1 does not exist, aborting.").arg(prefsUserFile).toLocal8Bit().data() << std::endl;
 				}
@@ -264,7 +264,7 @@ void ScribusQApp::parseCommandLine()
 			if (!QFileInfo(pythonScript).exists()) {
 				showHeader();
 				if (pythonScript.left(1) == "-" || pythonScript.left(2) == "--") {
-					std::cout << tr("Invalid argument: ").toLocal8Bit().data() << pythonScript.toLocal8Bit().data() << std::endl;
+					std::cout << tr("Invalid option: ").toLocal8Bit().data() << pythonScript.toLocal8Bit().data() << std::endl;
 				} else {
 					std::cout << tr("File %1 does not exist, aborting.").arg(pythonScript).toLocal8Bit().data() << std::endl;
 				}
@@ -273,32 +273,32 @@ void ScribusQApp::parseCommandLine()
 			} else {
 				++i;
 			}
+		} else if (arg == CMD_OPTIONS_END) { //double dash, indicates end of command line options, see http://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash
+			i++;
+			break;
 		} else if (arg.startsWith(qtARG_SCRIPTARG_PREFIX)) {
-	 		QString arg_name = arg.mid(qtARG_SCRIPTARG_PREFIX.size()-1); //-1 to get the dash from prefix
-	 		QString arg_value = QFile::decodeName(args[++i].toLocal8Bit());
-	 		//std::cout << tr("got one script argument: %1 with value %2").arg(arg_name).arg(arg_value).toLocal8Bit().data() << std::endl;				
-	 		pythonScriptArgs.append(arg_name);
-	 		pythonScriptArgs.append(arg_value);
-		} else if (arg.startsWith(qtARG_SCRIPTFLAG_PREFIX)) {
-	 		QString arg_name = arg.mid(qtARG_SCRIPTFLAG_PREFIX.size()-1); //-1 to get the dash from prefix
-	 		//std::cout << tr("got one script flag: %1 ").arg(arg_name).toLocal8Bit().data() << std::endl;
-	 		pythonScriptArgs.append(arg_name);	 		
-		} else { // (last) positional argument
-			fileName = QFile::decodeName(args[i].toLocal8Bit());
-			if (!QFileInfo(fileName).exists()) {
-				showHeader();
-				if (fileName.left(1) == "-" || fileName.left(2) == "--") {
-					std::cout << tr("Invalid argument: %1").arg(fileName).toLocal8Bit().data() << std::endl;
-				} else {
-					std::cout << tr("File %1 does not exist, aborting.").arg(fileName).toLocal8Bit().data() << std::endl;
-				}
-				showUsage();
-				std::exit(EXIT_FAILURE);
+			pythonScriptArgs.append( arg.mid(qtARG_SCRIPTARG_PREFIX.size()-1) ); //-1 to get the dash from prefix
+			if (!args[i+1].startsWith("-")) {
+				pythonScriptArgs.append( QFile::decodeName(args[++i].toLocal8Bit()) );
 			}
-			else
-			{
-				filesToLoad.append(fileName);
+		} else { //argument is not a known option, but either positional parameter or invalid.
+			break;
+		}
+	}
+	//remaining arguments, if any
+	for ( ; i<argsc; i++) {
+		fileName = QFile::decodeName(args[i].toLocal8Bit());
+		if (!QFileInfo(fileName).exists()) {
+			showHeader();
+			if (fileName.left(1) == "-" || fileName.left(2) == "--") {
+				std::cout << tr("Invalid argument: %1").arg(fileName).toLocal8Bit().data() << std::endl;
+			} else {
+				std::cout << tr("File %1 does not exist, aborting.").arg(fileName).toLocal8Bit().data() << std::endl;
 			}
+			showUsage();
+			std::exit(EXIT_FAILURE);
+		} else {
+			filesToLoad.append(fileName);
 		}
 	}
 }
@@ -501,7 +501,7 @@ void ScribusQApp::showUsage()
 	QFile f;
 	f.open(stderr, QIODevice::WriteOnly);
 	QTextStream ts(&f);
-	ts << tr("Usage: scribus [option ... ] [file]") ; endl(ts);
+	ts << tr("Usage: scribus [options] [files]") ; endl(ts); endl(ts);
 	ts << tr("Options:") ; endl(ts);
 	printArgLine(ts, ARG_FONTINFO_SHORT, ARG_FONTINFO, tr("Show information on the console when fonts are being loaded") );
 	printArgLine(ts, ARG_HELP_SHORT, ARG_HELP, tr("Print help (this message) and exit") );
@@ -514,9 +514,10 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
-	ts << (QString("       %1<%2> <%3>  ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script with its value, no effect without -py"); endl(ts);
-	ts << (QString("       %1<%2>             ").arg(ARG_SCRIPTFLAG_PREFIX).arg(tr("flagname"))) << tr("Argument passed on to python script with no value, no effect without -py"); endl(ts);
- 	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
+	ts << (QString("       %1<%2> [%3]  ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script, with an optional value, no effect without -py"); endl(ts);
+	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
+	ts << (QString("     %1").arg(CMD_OPTIONS_END,-39)) << tr("Explicit end of command line options"); endl(ts);
+ 	
 	
 #if defined(_WIN32) && !defined(_CONSOLE)
 	printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") );

From 6752a35215de21ff5b0b1e3530245f55c43bb655 Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Wed, 19 Aug 2015 17:09:19 +0200
Subject: [PATCH 7/9] polishing code for command line arguments for python
 script: overloading

---
 scribus/plugins/scriptplugin/scriptercore.cpp |  6 ++---
 scribus/plugins/scriptplugin/scriptercore.h   |  2 +-
 scribus/scribusapp.cpp                        | 32 +++++++++++++--------------
 3 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index 41b2949..f1f4594 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -230,10 +230,10 @@ void ScripterCore::RecentScript(QString fn)
 void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 {
 	QStringList arguments = QStringList();
-	slotRunScriptFileArgs(fileName, arguments, inMainInterpreter);
+	slotRunScriptFile(fileName, arguments, inMainInterpreter);
 }
 
-void ScripterCore::slotRunScriptFileArgs(QString fileName, QStringList arguments, bool inMainInterpreter)
+void ScripterCore::slotRunScriptFile(QString fileName, QStringList arguments, bool inMainInterpreter)
 /** run "filename" python script with the additional arguments provided in "arguments" */
 {
 	// Prevent two scripts to be run concurrently or face crash!
@@ -376,7 +376,7 @@ void ScripterCore::slotRunPythonScript()
 {
 	if (!ScQApp->pythonScript.isNull())
 	{
-		slotRunScriptFileArgs(ScQApp->pythonScript, ScQApp->pythonScriptArgs, true);
+		slotRunScriptFile(ScQApp->pythonScript, ScQApp->pythonScriptArgs, true);
 		FinishScriptRun();
 	}
 }
diff --git a/scribus/plugins/scriptplugin/scriptercore.h b/scribus/plugins/scriptplugin/scriptercore.h
index b8e2edf..72e5461 100644
--- a/scribus/plugins/scriptplugin/scriptercore.h
+++ b/scribus/plugins/scriptplugin/scriptercore.h
@@ -39,7 +39,7 @@ public slots:
 	void StdScript(QString filebasename);
 	void RecentScript(QString fn);
 	void slotRunScriptFile(QString fileName, bool inMainInterpreter = false);
-	void slotRunScriptFileArgs(QString fileName, QStringList arguments, bool inMainInterpreter = false);
+	void slotRunScriptFile(QString fileName, QStringList arguments, bool inMainInterpreter = false);
 	void slotRunPythonScript(); // needed for running python script from CLI
 	void slotRunScript(const QString script);
 	void slotInteractiveScript(bool);
diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 6be0cbc..8870934 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -218,11 +218,11 @@ void ScribusQApp::parseCommandLine()
 	useGUI = true;
 	//We are going to run something other than command line help
 	QString qtARG_SCRIPTARG_PREFIX = QString(ARG_SCRIPTARG_PREFIX);
-	int i = 1;
-	for( ; i < argsc; i++) { //handle all options (not positional parameters)
-		arg = args[i];
+	int argi = 1;
+	for( ; argi < argsc; argi++) { //handle options (not positional parameters)
+		arg = args[argi];
 
-		if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++i < argsc)) {
+		if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++argi < argsc)) {
 			continue;
 		} else if ( arg == ARG_CONSOLE || arg == ARG_CONSOLE_SHORT ) {
 			continue;
@@ -238,12 +238,12 @@ void ScribusQApp::parseCommandLine()
 			showFontInfo=true;
 		} else if (arg == ARG_PROFILEINFO || arg == ARG_PROFILEINFO_SHORT) {
 			showProfileInfo=true;
-		} else if ((arg == ARG_DISPLAY || arg==ARG_DISPLAY_SHORT || arg==ARG_DISPLAY_QT) && ++i < argsc) {
+		} else if ((arg == ARG_DISPLAY || arg==ARG_DISPLAY_SHORT || arg==ARG_DISPLAY_QT) && ++argi < argsc) {
 			// allow setting of display, QT expect the option -display <display_name> so we discard the
 			// last argument. FIXME: Qt only understands -display not --display and -d , we need to work
 			// around this.
 		} else if (arg == ARG_PREFS || arg == ARG_PREFS_SHORT) {
-			prefsUserFile = QFile::decodeName(args[i + 1].toLocal8Bit());
+			prefsUserFile = QFile::decodeName(args[argi + 1].toLocal8Bit());
 			if (!QFileInfo(prefsUserFile).exists()) {
 				showHeader();
 				if (prefsUserFile.left(1) == "-" || prefsUserFile.left(2) == "--") {
@@ -254,40 +254,40 @@ void ScribusQApp::parseCommandLine()
 				showUsage();
 				std::exit(EXIT_FAILURE);
 			} else {
-				++i;
+				++argi;
 			}
 		} else if (strncmp(arg.toLocal8Bit().data(),"-psn_",4) == 0)
 		{
 			// Andreas Vox: Qt/Mac has -psn_blah flags that must be accepted.
 		} else if (arg == ARG_PYTHONSCRIPT || arg == ARG_PYTHONSCRIPT_SHORT) {
-			pythonScript = QFile::decodeName(args[i + 1].toLocal8Bit());
+			pythonScript = QFile::decodeName(args[argi + 1].toLocal8Bit());
 			if (!QFileInfo(pythonScript).exists()) {
 				showHeader();
 				if (pythonScript.left(1) == "-" || pythonScript.left(2) == "--") {
-					std::cout << tr("Invalid option: ").toLocal8Bit().data() << pythonScript.toLocal8Bit().data() << std::endl;
+					std::cout << tr("Invalid argument: ").toLocal8Bit().data() << pythonScript.toLocal8Bit().data() << std::endl;
 				} else {
 					std::cout << tr("File %1 does not exist, aborting.").arg(pythonScript).toLocal8Bit().data() << std::endl;
 				}
 				showUsage();
 				std::exit(EXIT_FAILURE);
 			} else {
-				++i;
+				++argi;
 			}
 		} else if (arg == CMD_OPTIONS_END) { //double dash, indicates end of command line options, see http://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash
-			i++;
+			argi++;
 			break;
 		} else if (arg.startsWith(qtARG_SCRIPTARG_PREFIX)) {
 			pythonScriptArgs.append( arg.mid(qtARG_SCRIPTARG_PREFIX.size()-1) ); //-1 to get the dash from prefix
-			if (!args[i+1].startsWith("-")) {
-				pythonScriptArgs.append( QFile::decodeName(args[++i].toLocal8Bit()) );
+			if (!args[argi+1].startsWith("-")) {
+				pythonScriptArgs.append( QFile::decodeName(args[++argi].toLocal8Bit()) );
 			}
 		} else { //argument is not a known option, but either positional parameter or invalid.
 			break;
 		}
 	}
-	//remaining arguments, if any
-	for ( ; i<argsc; i++) {
-		fileName = QFile::decodeName(args[i].toLocal8Bit());
+	//remaining (positional) arguments, if any
+	for ( ; argi<argsc; argi++) {
+		fileName = QFile::decodeName(args[argi].toLocal8Bit());
 		if (!QFileInfo(fileName).exists()) {
 			showHeader();
 			if (fileName.left(1) == "-" || fileName.left(2) == "--") {

From 83db1fc71a4ade3cd478c1b762229c9d9be8e6c3 Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Thu, 3 Sep 2015 22:21:32 +0200
Subject: [PATCH 8/9] modified syntax to --python-arg <name> [value], per Craig
 request

---
 scribus/plugins/scriptplugin/scriptercore.cpp |  3 +--
 scribus/scribusapp.cpp                        | 21 +++++++++++----------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index f1f4594..cf41110 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -229,8 +229,7 @@ void ScripterCore::RecentScript(QString fn)
 
 void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 {
-	QStringList arguments = QStringList();
-	slotRunScriptFile(fileName, arguments, inMainInterpreter);
+	slotRunScriptFile(fileName, QStringList(), inMainInterpreter);
 }
 
 void ScripterCore::slotRunScriptFile(QString fileName, QStringList arguments, bool inMainInterpreter)
diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 8870934..951889c 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -72,8 +72,8 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK "--upgradecheck"
 #define ARG_TESTS "--tests"
 #define ARG_PYTHONSCRIPT "--python-script"
-#define ARG_SCRIPTARG_PREFIX "--python-arg-" // directly followed by <param name> <param value>
-#define CMD_OPTIONS_END "--"   				 // end of command line options
+#define ARG_SCRIPTARG "--python-arg"
+#define CMD_OPTIONS_END "--"
 
 #define ARG_VERSION_SHORT "-v"
 #define ARG_HELP_SHORT "-h"
@@ -89,6 +89,7 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK_SHORT "-u"
 #define ARG_TESTS_SHORT "-T"
 #define ARG_PYTHONSCRIPT_SHORT "-py"
+#define ARG_SCRIPTARG_SHORT "-pa"
 
 // Qt wants -display not --display or -d
 #define ARG_DISPLAY_QT "-display"
@@ -217,12 +218,17 @@ void ScribusQApp::parseCommandLine()
 		std::exit(EXIT_SUCCESS);
 	useGUI = true;
 	//We are going to run something other than command line help
-	QString qtARG_SCRIPTARG_PREFIX = QString(ARG_SCRIPTARG_PREFIX);
 	int argi = 1;
 	for( ; argi < argsc; argi++) { //handle options (not positional parameters)
 		arg = args[argi];
 
-		if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++argi < argsc)) {
+		if (arg == ARG_SCRIPTARG || arg == ARG_SCRIPTARG_SHORT) { //needs to be first to give precedence to script argument name over scribus'
+			pythonScriptArgs.append(args[++argi]); // arg name
+			if (!args[argi+1].startsWith("-")) {   // arg value
+				pythonScriptArgs.append( QFile::decodeName(args[++argi].toLocal8Bit()) );
+			}
+		}
+		else if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++argi < argsc)) {
 			continue;
 		} else if ( arg == ARG_CONSOLE || arg == ARG_CONSOLE_SHORT ) {
 			continue;
@@ -276,11 +282,6 @@ void ScribusQApp::parseCommandLine()
 		} else if (arg == CMD_OPTIONS_END) { //double dash, indicates end of command line options, see http://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash
 			argi++;
 			break;
-		} else if (arg.startsWith(qtARG_SCRIPTARG_PREFIX)) {
-			pythonScriptArgs.append( arg.mid(qtARG_SCRIPTARG_PREFIX.size()-1) ); //-1 to get the dash from prefix
-			if (!args[argi+1].startsWith("-")) {
-				pythonScriptArgs.append( QFile::decodeName(args[++argi].toLocal8Bit()) );
-			}
 		} else { //argument is not a known option, but either positional parameter or invalid.
 			break;
 		}
@@ -514,7 +515,7 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
-	ts << (QString("       %1<%2> [%3]  ").arg(ARG_SCRIPTARG_PREFIX).arg(tr("argumentname")).arg(tr("value"))) << tr("Argument passed on to python script, with an optional value, no effect without -py"); endl(ts);
+	printArgLine(ts, ARG_SCRIPTARG_SHORT, qPrintable(QString("%1 <%2> [%3]").arg(ARG_SCRIPTARG).arg(tr("name")).arg(tr("value"))), tr("Argument passed on to python script, with an optional value, no effect without -py") );
 	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
 	ts << (QString("     %1").arg(CMD_OPTIONS_END,-39)) << tr("Explicit end of command line options"); endl(ts);
  	

From 697424b382e8b1eabe485de262573d28d383c46a Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Thu, 3 Sep 2015 22:35:22 +0200
Subject: [PATCH 9/9] revert 'option' to 'argument' in CLI feedback

---
 scribus/scribusapp.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 951889c..21d7ecc 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -253,7 +253,7 @@ void ScribusQApp::parseCommandLine()
 			if (!QFileInfo(prefsUserFile).exists()) {
 				showHeader();
 				if (prefsUserFile.left(1) == "-" || prefsUserFile.left(2) == "--") {
-					std::cout << tr("Invalid option: ").toLocal8Bit().data() << prefsUserFile.toLocal8Bit().data() << std::endl;
+					std::cout << tr("Invalid argument: ").toLocal8Bit().data() << prefsUserFile.toLocal8Bit().data() << std::endl;
 				} else {
 					std::cout << tr("File %1 does not exist, aborting.").arg(prefsUserFile).toLocal8Bit().data() << std::endl;
 				}

berteh

2015-09-03 20:39

reporter   ~0036144

diff view of changes between the 2 patches:
https://github.com/berteh/scribus/commit/83db1fc71a4ade3cd478c1b762229c9d9be8e6c3?diff=split

diff view of the new patch (in full):
https://github.com/scribusproject/scribus/pull/19/files?diff=split

cbradney

2015-09-03 20:40

administrator   ~0036145

Do we need arg and flag types?
+#define ARG_SCRIPTARG_PREFIX "--python-arg" // directly followed by <param name> <param value>
+#define ARG_SCRIPTFLAG_PREFIX "--python-flag" // directly followed by <param name>


I don't get why if we have a flag and an arg command line option, Scribus cannot just use the full values without messing with existing options.
eg when --python-flag is used, the next parameter is the flag, and when --python-arg is used, the next two parameters are the arg/value pair.




Another Qt one: QString qtARG_SCRIPTARG_PREFIX = QString(ARG_SCRIPTARG_PREFIX); should just be QString qtARG_SCRIPTARG_PREFIX(ARG_SCRIPTARG_PREFIX); unless the #define causes issues.

formatting issue:

+ } else if (arg.startsWith(qtARG_SCRIPTFLAG_PREFIX)) {

should be

+ }
+ else if (arg.startsWith(qtARG_SCRIPTFLAG_PREFIX))
+ {

william

2015-09-03 21:24

updater   ~0036148

ghostscript has a similar issue where you sometimes need to pass information to the postscript interpreter. They have a -c option that takes everything that follows until a delimiter (or to the end of the command line if no delimiter is present).
http://ghostscript.com/doc/current/Use.htm#General_switches
It is similar to the --python-arg ... -- suggestion, except that most gs scripts place the -c ... sequence last, so you can usually get away without worrying about the delimiter.

I think that all of the suggestions so far are fine because the arguments will probably be generated by scripts, so the syntax and verbosity is not a big issue.

The syntax "--python-arg -xyz ... --" might be slightly easier to script because it is easier to write "--python-arg $flag --" without worrying if $flag is empty, while "--python-flag$arg" or "--python-flag $flag" both require a conditional in the script to test if $flag is empty.

berteh

2015-09-04 06:09

reporter   ~0036149

Last edited: 2015-09-04 06:15

@cbradney: the 3 items you mention are not in the final code of the patch, but only in its history (they have been changed by later commits in the same patch), I re-up a "clean" patch with only the final changes... or you can see it online at https://github.com/scribusproject/scribus/pull/19/files?diff=split

on 1) only --python-arg, -pa and -- are added, nothing about a "flag" anymore, for the reason you mention.
on 2) and 3) qtARG_SCRIPTFLAG_PREFIX is completely removed from code

nevertheless the issue stands on the "header" arguments: -h, -v (a.o.) get a "preferred" treatment in current code, they are detected before all other command-line arguments, to simply issue a command-line feedback and exit (scribusapp.cpp l.217).

Do you want me to merge all arguments parsing (headers and non headers) into a single loop for parsing arguments? I could then solve "precedence" issues... but then adding "-h" after "--python-arg" would NOT display scribus help.


@william: yes indeed a single combination of "some-args-start" and "some-args-stop" delimiter passing all in-between to the script would be possible, but others (namely aoloe) preferred not having that mechanism, see https://github.com/scribusproject/scribus/pull/19#issuecomment-128313027
(and that would still not solve the issue of "headers" arguments above, by the way)

berteh

2015-09-04 06:09

reporter  

cmdline_--python-arg_name_value__clean.patch (11,126 bytes)   
diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index 3903617..cf41110 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -9,6 +9,7 @@ for which a new license (GPL+exception) is in place.
 #include <QGlobalStatic>
 #include <QWidget>
 #include <QString>
+#include <QStringList>
 #include <QApplication>
 #include <QMessageBox>
 #include <QTextCodec>
@@ -37,7 +38,7 @@ for which a new license (GPL+exception) is in place.
 #include "prefscontext.h"
 #include "prefstable.h"
 #include "prefsmanager.h"
-#include "scribusapp.h" // need it to acces ScQApp->pythonScript
+#include "scribusapp.h" // need it to acces ScQApp->pythonScript & ScQApp->pythonScriptArgs
 
 ScripterCore::ScripterCore(QWidget* parent)
 {
@@ -228,6 +229,12 @@ void ScripterCore::RecentScript(QString fn)
 
 void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 {
+	slotRunScriptFile(fileName, QStringList(), inMainInterpreter);
+}
+
+void ScripterCore::slotRunScriptFile(QString fileName, QStringList arguments, bool inMainInterpreter)
+/** run "filename" python script with the additional arguments provided in "arguments" */
+{
 	// Prevent two scripts to be run concurrently or face crash!
 	if (ScCore->primaryMainWindow()->scriptIsRunning())
 		return;
@@ -252,16 +259,27 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 		// Init the scripter module in the sub-interpreter
 		initscribus(ScCore->primaryMainWindow());
 	}
+
 	// Make sure sys.argv[0] is the path to the script
-	char* comm[2];
-	comm[0] = na.data();
+	arguments.prepend(na.data());
+	
 	// and tell the script if it's running in the main intepreter or
 	// a subinterpreter using the second argument, ie sys.argv[1]
 	if (inMainInterpreter)
-		comm[1] = const_cast<char*>("ext");
+		arguments.insert(1,QString("ext"));
 	else
-		comm[1] = const_cast<char*>("sub");
-	PySys_SetArgv(2, comm);
+		arguments.insert(1,QString("sub"));
+
+	//convert arguments (QListString) to char** for Python bridge
+	/* typically arguments == ['path/to/script.py','ext','--argument1','valueforarg1','--flag']*/
+	char *comm[arguments.size()];
+	for (int i = 0; i < arguments.size(); i++)
+	{
+		comm[i] = new char[arguments.at(i).toLocal8Bit().size()+1]; //+1 to allow adding '\0'. may be useless, don't know how to check.
+		strcpy(comm[i],arguments.at(i).toLocal8Bit().data()+'\0');
+	}
+	PySys_SetArgv(arguments.size(), comm);
+	
 	// call python script
 	PyObject* m = PyImport_AddModule((char*)"__main__");
 	if (m == NULL)
@@ -357,7 +375,7 @@ void ScripterCore::slotRunPythonScript()
 {
 	if (!ScQApp->pythonScript.isNull())
 	{
-		slotRunScriptFile(ScQApp->pythonScript, true);
+		slotRunScriptFile(ScQApp->pythonScript, ScQApp->pythonScriptArgs, true);
 		FinishScriptRun();
 	}
 }
diff --git a/scribus/plugins/scriptplugin/scriptercore.h b/scribus/plugins/scriptplugin/scriptercore.h
index 1e929f4..72e5461 100644
--- a/scribus/plugins/scriptplugin/scriptercore.h
+++ b/scribus/plugins/scriptplugin/scriptercore.h
@@ -39,8 +39,9 @@ public slots:
 	void StdScript(QString filebasename);
 	void RecentScript(QString fn);
 	void slotRunScriptFile(QString fileName, bool inMainInterpreter = false);
+	void slotRunScriptFile(QString fileName, QStringList arguments, bool inMainInterpreter = false);
 	void slotRunPythonScript(); // needed for running python script from CLI
-	void slotRunScript(const QString Script);
+	void slotRunScript(const QString script);
 	void slotInteractiveScript(bool);
 	void slotExecute();
 	/*! \brief Show docstring of the script to the user.
diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index fec4055..21d7ecc 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -32,6 +32,7 @@ for which a new license (GPL+exception) is in place.
 #include <QLibraryInfo>
 #include <QLocale>
 #include <QString>
+#include <QStringList>
 #include <QTextCodec>
 #include <QTextStream>
 #include <QTranslator>
@@ -71,6 +72,8 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK "--upgradecheck"
 #define ARG_TESTS "--tests"
 #define ARG_PYTHONSCRIPT "--python-script"
+#define ARG_SCRIPTARG "--python-arg"
+#define CMD_OPTIONS_END "--"
 
 #define ARG_VERSION_SHORT "-v"
 #define ARG_HELP_SHORT "-h"
@@ -86,6 +89,7 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK_SHORT "-u"
 #define ARG_TESTS_SHORT "-T"
 #define ARG_PYTHONSCRIPT_SHORT "-py"
+#define ARG_SCRIPTARG_SHORT "-pa"
 
 // Qt wants -display not --display or -d
 #define ARG_DISPLAY_QT "-display"
@@ -108,6 +112,7 @@ ScribusQApp::ScribusQApp( int & argc, char ** argv ) : QApplication(argc, argv),
 	m_scDLMgr = 0;
 	m_ScCore = NULL;
 	initDLMgr();
+
 }
 
 ScribusQApp::~ScribusQApp()
@@ -213,10 +218,17 @@ void ScribusQApp::parseCommandLine()
 		std::exit(EXIT_SUCCESS);
 	useGUI = true;
 	//We are going to run something other than command line help
-	for(int i = 1; i < argsc; i++) {
-		arg = args[i];
-
-		if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++i < argsc)) {
+	int argi = 1;
+	for( ; argi < argsc; argi++) { //handle options (not positional parameters)
+		arg = args[argi];
+
+		if (arg == ARG_SCRIPTARG || arg == ARG_SCRIPTARG_SHORT) { //needs to be first to give precedence to script argument name over scribus'
+			pythonScriptArgs.append(args[++argi]); // arg name
+			if (!args[argi+1].startsWith("-")) {   // arg value
+				pythonScriptArgs.append( QFile::decodeName(args[++argi].toLocal8Bit()) );
+			}
+		}
+		else if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++argi < argsc)) {
 			continue;
 		} else if ( arg == ARG_CONSOLE || arg == ARG_CONSOLE_SHORT ) {
 			continue;
@@ -232,12 +244,12 @@ void ScribusQApp::parseCommandLine()
 			showFontInfo=true;
 		} else if (arg == ARG_PROFILEINFO || arg == ARG_PROFILEINFO_SHORT) {
 			showProfileInfo=true;
-		} else if ((arg == ARG_DISPLAY || arg==ARG_DISPLAY_SHORT || arg==ARG_DISPLAY_QT) && ++i < argsc) {
+		} else if ((arg == ARG_DISPLAY || arg==ARG_DISPLAY_SHORT || arg==ARG_DISPLAY_QT) && ++argi < argsc) {
 			// allow setting of display, QT expect the option -display <display_name> so we discard the
 			// last argument. FIXME: Qt only understands -display not --display and -d , we need to work
 			// around this.
 		} else if (arg == ARG_PREFS || arg == ARG_PREFS_SHORT) {
-			prefsUserFile = QFile::decodeName(args[i + 1].toLocal8Bit());
+			prefsUserFile = QFile::decodeName(args[argi + 1].toLocal8Bit());
 			if (!QFileInfo(prefsUserFile).exists()) {
 				showHeader();
 				if (prefsUserFile.left(1) == "-" || prefsUserFile.left(2) == "--") {
@@ -248,13 +260,13 @@ void ScribusQApp::parseCommandLine()
 				showUsage();
 				std::exit(EXIT_FAILURE);
 			} else {
-				++i;
+				++argi;
 			}
 		} else if (strncmp(arg.toLocal8Bit().data(),"-psn_",4) == 0)
 		{
 			// Andreas Vox: Qt/Mac has -psn_blah flags that must be accepted.
 		} else if (arg == ARG_PYTHONSCRIPT || arg == ARG_PYTHONSCRIPT_SHORT) {
-			pythonScript = QFile::decodeName(args[i + 1].toLocal8Bit());
+			pythonScript = QFile::decodeName(args[argi + 1].toLocal8Bit());
 			if (!QFileInfo(pythonScript).exists()) {
 				showHeader();
 				if (pythonScript.left(1) == "-" || pythonScript.left(2) == "--") {
@@ -265,24 +277,29 @@ void ScribusQApp::parseCommandLine()
 				showUsage();
 				std::exit(EXIT_FAILURE);
 			} else {
-				++i;
+				++argi;
 			}
-		} else {
-			fileName = QFile::decodeName(args[i].toLocal8Bit());
-			if (!QFileInfo(fileName).exists()) {
-				showHeader();
-				if (fileName.left(1) == "-" || fileName.left(2) == "--") {
-					std::cout << tr("Invalid argument: %1").arg(fileName).toLocal8Bit().data() << std::endl;
-				} else {
-					std::cout << tr("File %1 does not exist, aborting.").arg(fileName).toLocal8Bit().data() << std::endl;
-				}
-				showUsage();
-				std::exit(EXIT_FAILURE);
-			}
-			else
-			{
-				filesToLoad.append(fileName);
+		} else if (arg == CMD_OPTIONS_END) { //double dash, indicates end of command line options, see http://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash
+			argi++;
+			break;
+		} else { //argument is not a known option, but either positional parameter or invalid.
+			break;
+		}
+	}
+	//remaining (positional) arguments, if any
+	for ( ; argi<argsc; argi++) {
+		fileName = QFile::decodeName(args[argi].toLocal8Bit());
+		if (!QFileInfo(fileName).exists()) {
+			showHeader();
+			if (fileName.left(1) == "-" || fileName.left(2) == "--") {
+				std::cout << tr("Invalid argument: %1").arg(fileName).toLocal8Bit().data() << std::endl;
+			} else {
+				std::cout << tr("File %1 does not exist, aborting.").arg(fileName).toLocal8Bit().data() << std::endl;
 			}
+			showUsage();
+			std::exit(EXIT_FAILURE);
+		} else {
+			filesToLoad.append(fileName);
 		}
 	}
 }
@@ -485,7 +502,7 @@ void ScribusQApp::showUsage()
 	QFile f;
 	f.open(stderr, QIODevice::WriteOnly);
 	QTextStream ts(&f);
-	ts << tr("Usage: scribus [option ... ] [file]") ; endl(ts);
+	ts << tr("Usage: scribus [options] [files]") ; endl(ts); endl(ts);
 	ts << tr("Options:") ; endl(ts);
 	printArgLine(ts, ARG_FONTINFO_SHORT, ARG_FONTINFO, tr("Show information on the console when fonts are being loaded") );
 	printArgLine(ts, ARG_HELP_SHORT, ARG_HELP, tr("Print help (this message) and exit") );
@@ -498,7 +515,10 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
+	printArgLine(ts, ARG_SCRIPTARG_SHORT, qPrintable(QString("%1 <%2> [%3]").arg(ARG_SCRIPTARG).arg(tr("name")).arg(tr("value"))), tr("Argument passed on to python script, with an optional value, no effect without -py") );
 	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
+	ts << (QString("     %1").arg(CMD_OPTIONS_END,-39)) << tr("Explicit end of command line options"); endl(ts);
+ 	
 	
 #if defined(_WIN32) && !defined(_CONSOLE)
 	printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") );
diff --git a/scribus/scribusapp.h b/scribus/scribusapp.h
index 2857306..7fc9f7f 100644
--- a/scribus/scribusapp.h
+++ b/scribus/scribusapp.h
@@ -23,6 +23,7 @@ for which a new license (GPL+exception) is in place.
 #define SCRIBUSAPP_H
 #include <QApplication>
 #include <QString>
+#include <QStringList>
 
 #include "scribusapi.h"
 
@@ -71,6 +72,7 @@ class SCRIBUS_API ScribusQApp : public QApplication
 		const QString& currGUILanguage() { return GUILang; }
 		ScDLManager* dlManager() { return m_scDLMgr; }
 		QString pythonScript; // script to be run in python from CLI
+		QStringList pythonScriptArgs; // command line arguments and flags for script from CLI
 
 	private:
 		ScribusCore* m_ScCore;

berteh

2015-09-04 06:24

reporter   ~0036150

is there anyway someone can edit the "steps to reproduce" of this bug report to the following (I cannot)


apply "cmdline_--python-arg_name_value__clean.patch", compile, then call any scribus python script that will get the additional arguments passed from the command line:

simple use:
./scribus -g -py ~/cmdtest.py --python-arg -someflag1 --python-arg --somearg1 value1 ~/some1.sla

or more complex (with -- to distinguish that last parameter(s) are file(s) to be opened by scribus before running the script, and not arguments to be passed to the script.)

./scribus -g -py ~/cmdtest.py --python-arg -somearg1 value1 --python-arg --someflag1 -- ~/some1.sla



help is in the standard usage info:

./scribus -h

Usage: scribus [options] [files]

Options:
(...)
     -py, --python-script <filename> Run filename in Python scripter
     -pa, --python-arg <name> [value] Argument passed on to python script, with an optional value, no effect without -py
     -- Explicit end of command line options

JLuc

2015-09-04 10:23

developer   ~0036151

Last edited: 2015-09-04 10:23

Done berteh.

I prefer --python-arg arg1 or --python-arg -arg1 to --python-arg-arg1

As for conflicts with standard scribus args, i could very well accept to have to mention these standard options before any python-arg

Thanks MrB and Berteh for all these thoughts and works for improving use.

ale

2015-09-07 14:10

manager   ~0036161

i'm fine with "--python-arg -l --python-arg --items=12".
but i still somehow prefer "--python-arg-h" since it does not seem to have any side effects (except maybe, that it's harder for the user to understand that it's a parameter of the script and not a scribus parameter)

i would indeed avoid a start and stop mechanism.

i'd prefer long, unambiguous, easy to parse commands to short and easy to type ones. (i don't really see those arguments as to typed in a terminal but rather generated by a script)

after having read the comment about GS, i thing that it would not be that bad to just use the same wa other software have already implemented (using solutions that work and possibly already known to our users)

cbradney

2015-09-07 19:49

administrator   ~0036165

It should be --python-arg <argname> <argvalue> (or -pa)

@berteh: Feel free to rewrite the command line parsing to remove precedence. I would not expect -h after --python-arg to show the help (however if after --python-arg, I would also then expect "-h" to be passed in, and not just "h" as both argname and argvalue should not use -).

I don't like start/stop markers (wont accept a patch for that)
I don't like --python-arg-blah (wont accept a patch for that)

I guess we would accept forcing --python-arg to be last and then having all arg/values at the end. scribus -h --python-arg abc 123 should show the help though and ignore --python-arg (or any other parameter passed in)

berteh

2015-09-10 19:09

reporter  

cmdline --python-arg name value__compatible-header-arguments.patch (14,494 bytes)   
diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index 3903617..cf41110 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -9,6 +9,7 @@ for which a new license (GPL+exception) is in place.
 #include <QGlobalStatic>
 #include <QWidget>
 #include <QString>
+#include <QStringList>
 #include <QApplication>
 #include <QMessageBox>
 #include <QTextCodec>
@@ -37,7 +38,7 @@ for which a new license (GPL+exception) is in place.
 #include "prefscontext.h"
 #include "prefstable.h"
 #include "prefsmanager.h"
-#include "scribusapp.h" // need it to acces ScQApp->pythonScript
+#include "scribusapp.h" // need it to acces ScQApp->pythonScript & ScQApp->pythonScriptArgs
 
 ScripterCore::ScripterCore(QWidget* parent)
 {
@@ -228,6 +229,12 @@ void ScripterCore::RecentScript(QString fn)
 
 void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 {
+	slotRunScriptFile(fileName, QStringList(), inMainInterpreter);
+}
+
+void ScripterCore::slotRunScriptFile(QString fileName, QStringList arguments, bool inMainInterpreter)
+/** run "filename" python script with the additional arguments provided in "arguments" */
+{
 	// Prevent two scripts to be run concurrently or face crash!
 	if (ScCore->primaryMainWindow()->scriptIsRunning())
 		return;
@@ -252,16 +259,27 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 		// Init the scripter module in the sub-interpreter
 		initscribus(ScCore->primaryMainWindow());
 	}
+
 	// Make sure sys.argv[0] is the path to the script
-	char* comm[2];
-	comm[0] = na.data();
+	arguments.prepend(na.data());
+	
 	// and tell the script if it's running in the main intepreter or
 	// a subinterpreter using the second argument, ie sys.argv[1]
 	if (inMainInterpreter)
-		comm[1] = const_cast<char*>("ext");
+		arguments.insert(1,QString("ext"));
 	else
-		comm[1] = const_cast<char*>("sub");
-	PySys_SetArgv(2, comm);
+		arguments.insert(1,QString("sub"));
+
+	//convert arguments (QListString) to char** for Python bridge
+	/* typically arguments == ['path/to/script.py','ext','--argument1','valueforarg1','--flag']*/
+	char *comm[arguments.size()];
+	for (int i = 0; i < arguments.size(); i++)
+	{
+		comm[i] = new char[arguments.at(i).toLocal8Bit().size()+1]; //+1 to allow adding '\0'. may be useless, don't know how to check.
+		strcpy(comm[i],arguments.at(i).toLocal8Bit().data()+'\0');
+	}
+	PySys_SetArgv(arguments.size(), comm);
+	
 	// call python script
 	PyObject* m = PyImport_AddModule((char*)"__main__");
 	if (m == NULL)
@@ -357,7 +375,7 @@ void ScripterCore::slotRunPythonScript()
 {
 	if (!ScQApp->pythonScript.isNull())
 	{
-		slotRunScriptFile(ScQApp->pythonScript, true);
+		slotRunScriptFile(ScQApp->pythonScript, ScQApp->pythonScriptArgs, true);
 		FinishScriptRun();
 	}
 }
diff --git a/scribus/plugins/scriptplugin/scriptercore.h b/scribus/plugins/scriptplugin/scriptercore.h
index 1e929f4..72e5461 100644
--- a/scribus/plugins/scriptplugin/scriptercore.h
+++ b/scribus/plugins/scriptplugin/scriptercore.h
@@ -39,8 +39,9 @@ public slots:
 	void StdScript(QString filebasename);
 	void RecentScript(QString fn);
 	void slotRunScriptFile(QString fileName, bool inMainInterpreter = false);
+	void slotRunScriptFile(QString fileName, QStringList arguments, bool inMainInterpreter = false);
 	void slotRunPythonScript(); // needed for running python script from CLI
-	void slotRunScript(const QString Script);
+	void slotRunScript(const QString script);
 	void slotInteractiveScript(bool);
 	void slotExecute();
 	/*! \brief Show docstring of the script to the user.
diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index fec4055..6a43590 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -32,6 +32,7 @@ for which a new license (GPL+exception) is in place.
 #include <QLibraryInfo>
 #include <QLocale>
 #include <QString>
+#include <QStringList>
 #include <QTextCodec>
 #include <QTextStream>
 #include <QTranslator>
@@ -71,6 +72,8 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK "--upgradecheck"
 #define ARG_TESTS "--tests"
 #define ARG_PYTHONSCRIPT "--python-script"
+#define ARG_SCRIPTARG "--python-arg"
+#define CMD_OPTIONS_END "--"
 
 #define ARG_VERSION_SHORT "-v"
 #define ARG_HELP_SHORT "-h"
@@ -86,6 +89,7 @@ for which a new license (GPL+exception) is in place.
 #define ARG_UPGRADECHECK_SHORT "-u"
 #define ARG_TESTS_SHORT "-T"
 #define ARG_PYTHONSCRIPT_SHORT "-py"
+#define ARG_SCRIPTARG_SHORT "-pa"
 
 // Qt wants -display not --display or -d
 #define ARG_DISPLAY_QT "-display"
@@ -108,6 +112,7 @@ ScribusQApp::ScribusQApp( int & argc, char ** argv ) : QApplication(argc, argv),
 	m_scDLMgr = 0;
 	m_ScCore = NULL;
 	initDLMgr();
+
 }
 
 ScribusQApp::~ScribusQApp()
@@ -151,18 +156,30 @@ void ScribusQApp::parseCommandLine()
 	int testargsc;
 #endif
 	showFontInfo=false;
-	showProfileInfo=false;
+	showProfileInfo=false;	
+	bool neversplash = false;
 
-	//Parse for command line information options, and lang
+	//Parse for command line options
 	// Qt5 port: do this in a Qt compatible manner
 	QStringList args = arguments();
 	int argsc = args.count();
-	for(int i = 1; i < argsc; i++)
-	{
-		arg = args[i];
 
-		if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++i < argsc)) {
-			lang = args[i];
+	//Init translations
+	initLang();
+	
+	useGUI = true;
+	int argi = 1;
+	for( ; argi < argsc; argi++) { //handle options (not positional parameters)
+		arg = args[argi];
+
+		if (arg == ARG_SCRIPTARG || arg == ARG_SCRIPTARG_SHORT) { //needs to be first to give precedence to script argument name over scribus' options
+			pythonScriptArgs.append(args[++argi]); // arg name
+			if (!args[argi+1].startsWith("-")) {   // arg value
+				pythonScriptArgs.append( QFile::decodeName(args[++argi].toLocal8Bit()) );
+			}
+		}
+		else if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++argi < argsc)) {
+			lang = args[argi];
 		}
 		else if (arg == ARG_VERSION || arg == ARG_VERSION_SHORT) {
 			header=true;
@@ -175,8 +192,8 @@ void ScribusQApp::parseCommandLine()
 		else if (arg == ARG_TESTS || arg == ARG_TESTS_SHORT) {
 			header=true;
 			runtests=true;
-			testargsc = argc() - i;
-			testargsv = argv() + i;
+			testargsc = argc() - argi;
+			testargsv = argv() + argi;
 			break;
 		}
 #endif
@@ -187,104 +204,94 @@ void ScribusQApp::parseCommandLine()
 			header=true;
 			runUpgradeCheck=true;
 		}
-	}
-	//Init translations
-	initLang();
-	//Show command line help
-	if (header)
-		showHeader();
-	if (version)
-		showVersion();
-	if (availlangs)
-		showAvailLangs();
-	if (usage)
-		showUsage();
-#ifdef WITH_TESTS
-	if (runtests)
-		RunTests::runTests(testargsc, testargsv);
-#endif
-	if (runUpgradeCheck)
-	{
-		UpgradeChecker uc;
-		uc.fetch();
-	}
-	//Dont run the GUI init process called from main.cpp, and return
-	if (header)
-		std::exit(EXIT_SUCCESS);
-	useGUI = true;
-	//We are going to run something other than command line help
-	for(int i = 1; i < argsc; i++) {
-		arg = args[i];
-
-		if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++i < argsc)) {
+		else if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++argi < argsc)) {
 			continue;
-		} else if ( arg == ARG_CONSOLE || arg == ARG_CONSOLE_SHORT ) {
+		} 
+		else if ( arg == ARG_CONSOLE || arg == ARG_CONSOLE_SHORT ) {
 			continue;
 		} else if (arg == ARG_NOSPLASH || arg == ARG_NOSPLASH_SHORT) {
 			showSplash = false;
 		}
 		else if (arg == ARG_NEVERSPLASH || arg == ARG_NEVERSPLASH_SHORT) {
 			showSplash = false;
-			neverSplash(true);
+			neversplash = true;
 		} else if (arg == ARG_NOGUI || arg == ARG_NOGUI_SHORT) {
 			useGUI=false;
 		} else if (arg == ARG_FONTINFO || arg == ARG_FONTINFO_SHORT) {
 			showFontInfo=true;
 		} else if (arg == ARG_PROFILEINFO || arg == ARG_PROFILEINFO_SHORT) {
 			showProfileInfo=true;
-		} else if ((arg == ARG_DISPLAY || arg==ARG_DISPLAY_SHORT || arg==ARG_DISPLAY_QT) && ++i < argsc) {
+		} else if ((arg == ARG_DISPLAY || arg==ARG_DISPLAY_SHORT || arg==ARG_DISPLAY_QT) && ++argi < argsc) {
 			// allow setting of display, QT expect the option -display <display_name> so we discard the
 			// last argument. FIXME: Qt only understands -display not --display and -d , we need to work
 			// around this.
 		} else if (arg == ARG_PREFS || arg == ARG_PREFS_SHORT) {
-			prefsUserFile = QFile::decodeName(args[i + 1].toLocal8Bit());
+			prefsUserFile = QFile::decodeName(args[argi + 1].toLocal8Bit());
 			if (!QFileInfo(prefsUserFile).exists()) {
-				showHeader();
-				if (prefsUserFile.left(1) == "-" || prefsUserFile.left(2) == "--") {
-					std::cout << tr("Invalid argument: ").toLocal8Bit().data() << prefsUserFile.toLocal8Bit().data() << std::endl;
-				} else {
-					std::cout << tr("File %1 does not exist, aborting.").arg(prefsUserFile).toLocal8Bit().data() << std::endl;
-				}
-				showUsage();
+				showError(prefsUserFile);
 				std::exit(EXIT_FAILURE);
 			} else {
-				++i;
+				++argi;
 			}
 		} else if (strncmp(arg.toLocal8Bit().data(),"-psn_",4) == 0)
 		{
 			// Andreas Vox: Qt/Mac has -psn_blah flags that must be accepted.
 		} else if (arg == ARG_PYTHONSCRIPT || arg == ARG_PYTHONSCRIPT_SHORT) {
-			pythonScript = QFile::decodeName(args[i + 1].toLocal8Bit());
+			pythonScript = QFile::decodeName(args[argi + 1].toLocal8Bit());
 			if (!QFileInfo(pythonScript).exists()) {
-				showHeader();
-				if (pythonScript.left(1) == "-" || pythonScript.left(2) == "--") {
-					std::cout << tr("Invalid argument: ").toLocal8Bit().data() << pythonScript.toLocal8Bit().data() << std::endl;
-				} else {
-					std::cout << tr("File %1 does not exist, aborting.").arg(pythonScript).toLocal8Bit().data() << std::endl;
-				}
-				showUsage();
+				showError(pythonScript);
 				std::exit(EXIT_FAILURE);
 			} else {
-				++i;
+				++argi;
 			}
+		} else if (arg == CMD_OPTIONS_END) { //double dash, indicates end of command line options, see http://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash
+			argi++;
+			break;
+		} else { //argument is not a known option, but either positional parameter or invalid.
+			break;
+		}
+	}
+	// parse for remaining (positional) arguments, if any
+	for ( ; argi<argsc; argi++) {
+		fileName = QFile::decodeName(args[argi].toLocal8Bit());
+		if (!QFileInfo(fileName).exists()) {
+			showError(fileName);
+			std::exit(EXIT_FAILURE);
 		} else {
-			fileName = QFile::decodeName(args[i].toLocal8Bit());
-			if (!QFileInfo(fileName).exists()) {
-				showHeader();
-				if (fileName.left(1) == "-" || fileName.left(2) == "--") {
-					std::cout << tr("Invalid argument: %1").arg(fileName).toLocal8Bit().data() << std::endl;
-				} else {
-					std::cout << tr("File %1 does not exist, aborting.").arg(fileName).toLocal8Bit().data() << std::endl;
-				}
-				showUsage();
-				std::exit(EXIT_FAILURE);
-			}
-			else
-			{
-				filesToLoad.append(fileName);
-			}
+			filesToLoad.append(fileName);
 		}
 	}
+
+	
+	//Show command line info
+	if (header) {
+		useGUI = false;
+		showHeader();
+	}
+	if (version)
+		showVersion();
+	if (availlangs)
+		showAvailLangs();
+	if (usage)
+		showUsage();
+#ifdef WITH_TESTS
+	if (runtests)
+		RunTests::runTests(testargsc, testargsv);
+#endif
+	if (runUpgradeCheck)
+	{
+		UpgradeChecker uc;
+		uc.fetch();
+	}
+	//Dont run the GUI init process called from main.cpp, and return
+	if (header) {		
+		std::exit(EXIT_SUCCESS);
+	}
+	//proceed
+	if(neversplash) {
+		neverSplash(true);
+	}
+	
 }
 
 int ScribusQApp::init()
@@ -485,7 +492,7 @@ void ScribusQApp::showUsage()
 	QFile f;
 	f.open(stderr, QIODevice::WriteOnly);
 	QTextStream ts(&f);
-	ts << tr("Usage: scribus [option ... ] [file]") ; endl(ts);
+	ts << tr("Usage: scribus [options] [files]") ; endl(ts); endl(ts);
 	ts << tr("Options:") ; endl(ts);
 	printArgLine(ts, ARG_FONTINFO_SHORT, ARG_FONTINFO, tr("Show information on the console when fonts are being loaded") );
 	printArgLine(ts, ARG_HELP_SHORT, ARG_HELP, tr("Print help (this message) and exit") );
@@ -498,7 +505,10 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
+	printArgLine(ts, ARG_SCRIPTARG_SHORT, qPrintable(QString("%1 <%2> [%3]").arg(ARG_SCRIPTARG).arg(tr("name")).arg(tr("value"))), tr("Argument passed on to python script, with an optional value, no effect without -py") );
 	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
+	ts << (QString("     %1").arg(CMD_OPTIONS_END,-39)) << tr("Explicit end of command line options"); endl(ts);
+ 	
 	
 #if defined(_WIN32) && !defined(_CONSOLE)
 	printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") );
@@ -558,6 +568,18 @@ void ScribusQApp::showHeader()
 	endl(ts);
 }
 
+void ScribusQApp::showError(QString arg)
+{
+	showHeader();
+	if (arg.left(1) == "-" || arg.left(2) == "--") {
+		std::cout << tr("Invalid argument: %1").arg(arg).toLocal8Bit().data() << std::endl;
+	} else {
+		std::cout << tr("File %1 does not exist, aborting.").arg(arg).toLocal8Bit().data() << std::endl;
+	}
+	showUsage();
+	std::cout << tr("Scribus Version").toLocal8Bit().data() << " " << VERSION << std::endl;
+}
+
 void ScribusQApp::neverSplash(bool splashOff)
 {
 	QString prefsDir = ScPaths::getApplicationDataDir();
diff --git a/scribus/scribusapp.h b/scribus/scribusapp.h
index 2857306..0add48f 100644
--- a/scribus/scribusapp.h
+++ b/scribus/scribusapp.h
@@ -23,6 +23,7 @@ for which a new license (GPL+exception) is in place.
 #define SCRIBUSAPP_H
 #include <QApplication>
 #include <QString>
+#include <QStringList>
 
 #include "scribusapi.h"
 
@@ -71,10 +72,12 @@ class SCRIBUS_API ScribusQApp : public QApplication
 		const QString& currGUILanguage() { return GUILang; }
 		ScDLManager* dlManager() { return m_scDLMgr; }
 		QString pythonScript; // script to be run in python from CLI
+		QStringList pythonScriptArgs; // command line arguments and flags for script from CLI
 
 	private:
 		ScribusCore* m_ScCore;
 		void showHeader();
+		void showError(QString arg);
 		void showVersion();
 		/*!
 		\author Franz Schmid

berteh

2015-09-10 19:15

reporter   ~0036184

@cbradney new patch (cmdline --python-arg name value__compatible-header-arguments.patch) includes the removal of precedence of header arguments.

It supports --python-arg <name> <value> (or -pa), and indeed if you pass "-h" as <name>, the script receives "-h".

scribus -h --python-arg abc 123 does indeed show scribus help and exit (precedence is only removed in the parsing, not in the effect of the argument itself)

online view at https://github.com/scribusproject/scribus/pull/19/files?diff=split

thanks for your guidance.

cbradney

2015-09-10 20:08

administrator   ~0036185

Thanks, resolved in r20372 :)

JLuc

2015-09-13 08:00

developer   ~0036203

Last edited: 2015-09-13 08:00

Hello

i've documented the command-line scripting option along with this argument passing feature.
Can you have a look and correct mistakes when necessary ?

http://wiki.scribus.net/canvas/Command_line_scripts

JLuc

2015-09-13 08:01

developer   ~0036204

BTW i dont understand the 'depth computation' example. What is that 'depth' exactly ? maybe the heigth of the actual text, whether it fits or not in the frame ?

JLuc

2015-09-13 08:16

developer   ~0036205

It think i've understood. See
http://wiki.scribus.net/canvas/Command_line_scripts

Kunda

2015-09-13 13:05

updater   ~0036206

Lets make a super sexy and practical page showing great usecases for this function.

william

2015-09-13 15:10

updater   ~0036207

The documentation at http://wiki.scribus.net/canvas/Command_line_scripts looks good. I didn't realize that you would use the script. It is not the most common use case. To explain, I am trying to build pages from blocks of text. Each block is in a text file. First I run each block of text through the script to find the depth, then I do some calculations with the depths to position the blocks to fill pages, and then I build a document.
The command line option lets you do things similar to the Scribus Generator http://wiki.scribus.net/canvas/Scribus_Generator . The Scribus Generator is easier if you are doing text replacement (like making form letters). The command line is easier if you are performing actions that need to be scripted (like assembling a document or exporting a document to PDF).

berteh

2015-09-13 19:37

reporter   ~0036208

Thanks JLuc for the doc.

the usage of the argument is different though: you've got to repeat "-pa" or "--python-arg" for each argument, such as in:

scribus -py somescript.py --python-arg -v -pa -w 500 -pa -h 200 mydoc.sla

Sorry if that was not clear before.

I'll apply for a wiki access to updated this... and the Scribus Generator page too, to add about the new functions (advanced tweaks & merge all pages).

JLuc

2015-09-13 20:00

developer   ~0036209

It works fine when there is exactly 2 command line arguments after -pa but there 2 issues.

1) when -pa is used with 0 or 1 argument, an assert happens :

ASSERT failure in QList<T>::operator[]: "index out of range", file /localbin/Qt5.5.0/5.5/gcc_64/include/QtCore/qlist.h, line 518
Plantage de Scribus
-------------
Plantage de Scribus suite au signal 0000006

2) when -pa is used with 3 or more than 3 arguments, no assert but a scribus error message : it misses a filename on the command line
("Le fichier 3 n'existe pas, annulation. Usage: scribus [options] [files]...")


scribus151svn -ns -g -py hello_or_not.py --python-arg --> assert
scribus151svn -ns -g -py hello_or_not.py --python-arg first --> assert
scribus151svn -ns -g -py hello_or_not.py --python-arg first hello --> OK !
scribus151svn -ns -g -py hello_or_not.py --python-arg first hello third --> scribus error
etc

These tests are made with the "conditional hello world" script on the wiki page : http://wiki.scribus.net/canvas/Command_line_scripts#Hello_world_script_with_arguments

JLuc

2015-09-13 20:35

developer   ~0036210

Last edited: 2015-09-13 20:36

Beside : your script expects a filename to be opened to be able to work, but there is no command to open the document in the script : scribus opens it, not the script.

How can scribus know where do the arguments for the script stop ?
How can a script tell scribus "i've finished with my arguments and i dont need the following one which are filenames to open" ?

I wonder all the more when there is no -- separator.

berteh

2015-09-13 20:56

reporter   ~0036211

Hi JLuc.

the 1 assert you spotted should generate a nice error message. I'll correct it, thanks.
the 2d assert you spotted should be valid, it's a bug, I'll correct it, thanks.

the 4th test is the (expected) standard scribus error message, no change from the current behaviour, nothing to do with the script args parsing... but I agree with you that this message could use a better wording, and even more so in the french translation seemingly.

On your last matter of the filename: it is indeed scribus that should open the sla if you provide it in this way, and that's the purpose (so you can use the same script via the command-line and via the script menu). If you want the script to get a document, you pass it using a "-pa"... but then don't expect scribus to open it!

Scribus knows where the last argument for the script stops either because you provide a name *and value* for the last -pa... or by using an explicit "--" if you provide no value for your last -pa. This double dash is explained in http://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash and requested by aoloe in https://github.com/scribusproject/scribus/pull/19#issuecomment-128341739 . It basically marks the end of the options and the beginning of the positional arguments.

so, all of the following are valid:

scribus151svn -ns -g -py hello_or_not.py -pa first hello -pa --second hello2 file-to-open-in-scribus.sla
scribus151svn -ns -g -py hello_or_not.py -pa first hello -pa --second -- file-to-open-in-scribus.sla
scribus151svn -ns -g -py hello_or_not.py -pa first hello -pa --input file-the script-gets-not-opened-in-scribus.sla file-to-open-in-scribus.sla

and even (if you make a script that works on all documents currently open in scribus):

scribus151svn -ns -g -py hello_or_not.py -pa first hello -pa --second -- files-to-open-in-scribus/*.sla

JLuc

2015-09-13 21:34

developer   ~0036212

OK fine ! (i previously wrongly understood that the code for -- wasnt merged)

I think i got the whole picture and will improve the wiki page accordingly.

berteh

2015-09-14 08:39

reporter   ~0036213

kindly re-open to fix bug detected by JLuc.

correcting patch is at https://github.com/scribusproject/scribus/commit/e93952802113a2f86ddeb86e99e360a7a34b90cc.patch

jghali

2015-09-14 14:57

administrator   ~0036217

Applied with some changes: fyi "and" in an "if" condition is not accepted by all compilers. Probably a typedef specific to gcc.

william

2015-09-15 01:21

updater  

export_to_pdf.py (2,522 bytes)   
#!/usr/bin/env python
# -*- coding: utf-8 -*-

""" 

Convert a document to a PDF

Run with a command like
	scribus -g -py export_to_pdf.py -pa -version 13 -pa -bleedr 2 -pa -compress 1 -pa -info 'test title' -pa -file 'test.pdf' -- testdoc.sla

You can set any "pdf" attribute with "-pa -attribute value".

Tested with scribus 1.5.1 r20382

Author: William Bader, Director of Research and Development, SCS, http://www.newspapersystems.com
15Sep15 wb initial version

"""

# check that the script is running from inside scribus

try:
	from scribus import *
    
except ImportError:
	print 'This script only runs from within Scribus.'
	sys.exit(1)

# get the os module

try:
	import os

except ImportError:
	print 'Could not import the os module.'
	sys.exit(1)

def main(argv):
	pdf = scribus.PDFfile()
	pdf.pages=[1]
	pdf.version = 13
	pdf.file = 'newfile.pdf'

	i = 1
	while i < len(argv):
		if (len(argv[i]) > 0) and (argv[i][0] == '-'):
			name = argv[i][1:]
			try:
				pdf_attr = getattr(pdf, name)
				if i < len(argv):
					i = i + 1
					value = argv[i]
				else:
					value = ''
				if callable(pdf_attr):
					print 'Error: "', name, '" is not a settable attribute.'
				else:
					if isinstance(pdf_attr, float):
						try:
							setattr(pdf, name, float(value))
						except:
							print 'Error: Could not set "', name, '", "', value, '" is not a valid real number.'
					elif isinstance(pdf_attr, int):
						# Integers and booleans
						try:
							if value.lower() in [ 'true', 't', 'yes', 'y', 'si', 's' ]:
								setattr(pdf, name, 1)
							elif value.lower() in [ 'false', 'f', 'no', 'n' ]:
								setattr(pdf, name, 0)
							else:
								setattr(pdf, name, int(value))
						except:
							print 'Error: Could not set "', name, '", "', value, '" is not a valid integer.'
					elif isinstance(pdf_attr, basestring):
						# Should this differentiate str and unicode, or will the assignment do the conversion?
						try:
							setattr(pdf, name, value)
						except:
							print 'Error: Could not set "', name, '", "', value, '" is not a valid string.'
					else:
						print 'Error: Could not set "', name, ', type "', type(pdf_attr), '" not supported.'
					print name, ' is ', str(getattr(pdf, name)), '.'
			except:
				print 'Error: Ignoring unrecognized pdf attribute "', name, '".'
		i = i + 1

	pdf.save()

# start the script

if __name__ == '__main__':
	if haveDoc():
		main(sys.argv)
	else:
		print 'Error: You need to have a document open before you can run this script successfully.'
export_to_pdf.py (2,522 bytes)   

william

2015-09-15 01:35

updater   ~0036239

I attached an export_to_pdf.py script that I think is a good example of something useful.
It exports a document to a PDF, and you can specify settings for "pdf" class attributes on the command line, for example,
  scribus -g -py export_to_pdf.py -pa -version 13 -pa -bleedr 2 -pa -compress 1 -pa -info 'test title' -pa -file 'test.pdf' -- testdoc.sla
It uses getattr(), isinstance() and setattr() to access pdf class variables by their string name, so it does not need a hard-coded list of names.

ale

2015-09-15 06:15

manager   ~0036240

hi william

i guess it was in the air :-)

i created a very similar script yesterday evening:

https://github.com/aoloe/scribus-script-sample/blob/master/to-pdf-with-placeholder/to-pdf-with-placeholder.py

also, as written above, jluc is collecting samples and drafting a documentation in the wiki:
http://wiki.scribus.net/canvas/Command_line_scripts

berteh

2015-09-15 06:53

reporter   ~0036241

Thanks Jean for the patch.

Thanks William & Ale for the nice scripts.

and most of all thanks JLuc for the extensive documentation! I added a few lines in the wiki to highlight (and get rid) of the "parasite" arguments Scribus introduces, so that getops or other argparse can be used:

if __name__ == '__main__':
    if (sys.argv[1] == 'ext' or sys.argv[1] == 'sub'): #discard argv[1] if it is 'ext' or 'sub', that is added by Scribus when calling an external script
        del sys.argv[1]
    main(sys.argv)

Would be useful if you handle them explicitely in your "example" scripts so that they don't come as a surprise to the next one.

ale

2015-09-15 07:08

manager   ~0036242

hi berteh,

i'm no python expert, but from what i've seen, the standard way of getting rid of extra arguments in argv seems to be sys.argv[1:] (normally used for removing the scrip name).

in our case we should probably pass sys.argv[2:] to main.

on the other hand, i have opened a ticket (0013351) for getting rid of the extra argument before the new functionality starts to be used.

if nobody knows what the sub/ext is good for, i really think that we should drop it.

berteh

2015-09-17 07:42

reporter  

detect-missing-arg_bug-fix.patch (2,501 bytes)   
From e93952802113a2f86ddeb86e99e360a7a34b90cc Mon Sep 17 00:00:00 2001
From: berteh <berteh@gmail.com>
Date: Mon, 14 Sep 2015 10:35:18 +0200
Subject: [PATCH] detect missing argument

---
 scribus/scribusapp.cpp | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 6a43590..a1f4c52 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -173,9 +173,15 @@ void ScribusQApp::parseCommandLine()
 		arg = args[argi];
 
 		if (arg == ARG_SCRIPTARG || arg == ARG_SCRIPTARG_SHORT) { //needs to be first to give precedence to script argument name over scribus' options
-			pythonScriptArgs.append(args[++argi]); // arg name
-			if (!args[argi+1].startsWith("-")) {   // arg value
-				pythonScriptArgs.append( QFile::decodeName(args[++argi].toLocal8Bit()) );
+			if (++argi<argsc and (args[argi] != CMD_OPTIONS_END)) {
+				pythonScriptArgs.append(args[argi]); // script argument
+			} else {
+				std::cout << tr("Invalid argument use: '%1' requires to be followed by <argument> [value]").arg(arg).toLocal8Bit().data() << std::endl;
+				showUsage();
+				std::exit(EXIT_FAILURE);
+			}
+			if (++argi<argsc and !args[argi].startsWith("-")) {   // arg value
+				pythonScriptArgs.append( QFile::decodeName(args[argi].toLocal8Bit()) );
 			}
 		}
 		else if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++argi < argsc)) {
@@ -505,7 +511,7 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
 	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, qPrintable(QString("%1 <%2>").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") );
-	printArgLine(ts, ARG_SCRIPTARG_SHORT, qPrintable(QString("%1 <%2> [%3]").arg(ARG_SCRIPTARG).arg(tr("name")).arg(tr("value"))), tr("Argument passed on to python script, with an optional value, no effect without -py") );
+	printArgLine(ts, ARG_SCRIPTARG_SHORT, qPrintable(QString("%1 <%2> [%3]").arg(ARG_SCRIPTARG).arg(tr("argument")).arg(tr("value"))), tr("Argument passed on to python script, with an optional value, no effect without -py") );
 	printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") );
 	ts << (QString("     %1").arg(CMD_OPTIONS_END,-39)) << tr("Explicit end of command line options"); endl(ts);
  	

berteh

2015-09-17 07:44

reporter   ~0036252

uploaded patch to fix the bug detecte by JLuc (detect-missing-arg_bug-fix.patch), as it main not stay available on github. No need to do anything with it, as jghali kindly applied alreay.

Issue History

Date Modified Username Field Change
2015-08-19 15:22 berteh New Issue
2015-08-19 15:22 berteh File Added: command-line-arguments-for-python-script.patch
2015-08-19 15:23 berteh File Added: cmdtest.py
2015-08-19 15:24 berteh Note Added: 0036069
2015-08-19 20:58 Kunda Note Added: 0036070
2015-08-20 03:29 william File Added: storydeptharg.py
2015-08-20 03:41 william Note Added: 0036071
2015-08-20 05:34 william Note Added: 0036072
2015-08-20 09:40 berteh Note Added: 0036073
2015-08-20 16:26 william Note Added: 0036074
2015-08-21 10:56 berteh Note Added: 0036075
2015-08-21 18:11 Kunda Note Added: 0036076
2015-08-25 01:18 Kunda Summary add support for command line arguments to be passed on to python script (-py option) => [PATCH] support for command line arguments to be passed on to python script (-py option)
2015-08-27 22:44 Kunda Note Added: 0036107
2015-08-29 13:43 Kunda Note Added: 0036117
2015-08-31 00:32 Kunda Relationship added related to 0000238
2015-09-01 12:33 Kunda Sticky Issue No => Yes
2015-09-02 07:24 berteh Note Added: 0036132
2015-09-02 07:47 JLuc Note Added: 0036134
2015-09-02 09:19 berteh Note Added: 0036135
2015-09-03 19:24 cbradney Note Added: 0036140
2015-09-03 20:27 berteh Note Added: 0036143
2015-09-03 20:28 berteh File Added: cmdline_--python-arg_name_value.patch
2015-09-03 20:28 berteh Note Edited: 0036143
2015-09-03 20:36 berteh File Deleted: cmdline_--python-arg_name_value.patch
2015-09-03 20:36 berteh File Added: cmdline_--python-arg_name_value.patch
2015-09-03 20:39 berteh Note Added: 0036144
2015-09-03 20:40 berteh Note Edited: 0036143
2015-09-03 20:40 cbradney Note Added: 0036145
2015-09-03 21:24 william Note Added: 0036148
2015-09-04 06:09 berteh Note Added: 0036149
2015-09-04 06:09 berteh File Added: cmdline_--python-arg_name_value__clean.patch
2015-09-04 06:12 berteh Note Edited: 0036149
2015-09-04 06:12 berteh Note Edited: 0036149
2015-09-04 06:15 berteh Note Edited: 0036149
2015-09-04 06:24 berteh Note Added: 0036150
2015-09-04 10:20 JLuc Steps to Reproduce Updated
2015-09-04 10:23 JLuc Note Added: 0036151
2015-09-04 10:23 JLuc Note Edited: 0036151
2015-09-07 14:10 ale Note Added: 0036161
2015-09-07 19:49 cbradney Note Added: 0036165
2015-09-10 19:09 berteh File Added: cmdline --python-arg name value__compatible-header-arguments.patch
2015-09-10 19:15 berteh Note Added: 0036184
2015-09-10 20:08 cbradney Note Added: 0036185
2015-09-10 20:08 cbradney Status new => resolved
2015-09-10 20:08 cbradney Fixed in Version => 1.5.1svn
2015-09-10 20:08 cbradney Resolution open => fixed
2015-09-10 20:08 cbradney Assigned To => cbradney
2015-09-11 11:42 Kunda Sticky Issue Yes => No
2015-09-13 08:00 JLuc Note Added: 0036203
2015-09-13 08:00 JLuc Note Edited: 0036203
2015-09-13 08:01 JLuc Note Added: 0036204
2015-09-13 08:16 JLuc Note Added: 0036205
2015-09-13 13:05 Kunda Note Added: 0036206
2015-09-13 15:10 william Note Added: 0036207
2015-09-13 19:37 berteh Note Added: 0036208
2015-09-13 20:00 JLuc Note Added: 0036209
2015-09-13 20:35 JLuc Note Added: 0036210
2015-09-13 20:35 JLuc Note Edited: 0036210
2015-09-13 20:36 JLuc Note Edited: 0036210
2015-09-13 20:56 berteh Note Added: 0036211
2015-09-13 21:34 JLuc Note Added: 0036212
2015-09-14 08:39 berteh Note Added: 0036213
2015-09-14 08:39 berteh Status resolved => feedback
2015-09-14 08:39 berteh Resolution fixed => reopened
2015-09-14 14:57 jghali Note Added: 0036217
2015-09-14 14:57 jghali Status feedback => resolved
2015-09-14 14:57 jghali Resolution reopened => fixed
2015-09-15 01:21 william File Added: export_to_pdf.py
2015-09-15 01:35 william Note Added: 0036239
2015-09-15 06:15 ale Note Added: 0036240
2015-09-15 06:53 berteh Note Added: 0036241
2015-09-15 07:08 ale Note Added: 0036242
2015-09-17 07:42 berteh File Added: detect-missing-arg_bug-fix.patch
2015-09-17 07:44 berteh Note Added: 0036252
2015-09-17 18:50 cbradney Relationship added has duplicate 0008968
2015-10-03 20:18 cbradney Status resolved => closed
2015-11-22 13:52 jghali Summary [PATCH] support for command line arguments to be passed on to python script (-py option) => support for command line arguments to be passed on to python script (-py option)