[Sciviews-commits] r241 - komodo/SciViews-K komodo/SciViews-K/content/js pkg/svIDE/R pkg/svIDE/man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Tue Dec 29 21:05:42 CET 2009


Author: phgrosjean
Date: 2009-12-29 21:05:42 +0100 (Tue, 29 Dec 2009)
New Revision: 241

Modified:
   komodo/SciViews-K/content/js/interpolate.js
   komodo/SciViews-K/content/js/misc.js
   komodo/SciViews-K/content/js/r.js
   komodo/SciViews-K/content/js/sciviews.js
   komodo/SciViews-K/sciviewsk-0.9.9-ko.xpi
   pkg/svIDE/R/kpfTranslate.R
   pkg/svIDE/man/kpfTranslate.Rd
Log:
More changes to kpfTranslate in svIDE and several bug corrections in r.js and misc.js

Modified: komodo/SciViews-K/content/js/interpolate.js
===================================================================
--- komodo/SciViews-K/content/js/interpolate.js	2009-12-29 11:14:28 UTC (rev 240)
+++ komodo/SciViews-K/content/js/interpolate.js	2009-12-29 20:05:42 UTC (rev 241)
@@ -48,19 +48,21 @@
 	log.info("interpolate.interpolate(editor, strings=["+strings+
                           "], bracketedStrings=["+bracketedStrings+"], queryTitle='"+
                           queryTitle+"', viewData)");
-    viewData = ko.interpolate.getViewData(editor, viewData);
+	viewData = ko.interpolate.getViewData(editor, viewData);
 
     var lastErrorSvc = Components.classes["@activestate.com/koLastErrorService;1"]
                        .getService(Components.interfaces.koILastErrorService);
 
     // PhG: interpolation step 0: eliminate [[%tr:...]] used to tag strings
 	// to be translated
-	var brStr = bracketedStrings[0];
-	// Replace [[%tr:some string]] by some string
-	brStr = brStr.replace(/\[\[%tr:([^\]\]]+)\]\]/g, "$1");
-	// Replace [[%ask:x:%tr:x-value]] by [[%ask:x:x-value]]
-	brStr = brStr.replace(/%tr:/g, "");
-	bracketedStrings[0] = brStr;
+	try {
+		var brStr = bracketedStrings[0];
+		// Replace [[%tr:some string]] by some string
+		brStr = brStr.replace(/\[\[%tr:([^\]\]]+)\]\]/g, "$1");
+		// Replace [[%ask:x:%tr:x-value]] by [[%ask:x:x-value]]
+		brStr = brStr.replace(/%tr:/g, "");
+		bracketedStrings[0] = brStr;
+	} catch(e) {}
 	
 	// Interpolation step 1: get queries.
     var queriesCountObj = new Object();

Modified: komodo/SciViews-K/content/js/misc.js
===================================================================
--- komodo/SciViews-K/content/js/misc.js	2009-12-29 11:14:28 UTC (rev 240)
+++ komodo/SciViews-K/content/js/misc.js	2009-12-29 20:05:42 UTC (rev 241)
@@ -1,21 +1,21 @@
 // SciViews-K miscellaneous functions
 // Define the 'sv.misc' namespace
-// Copyright (c) 2008-2009, Ph. Grosjean (phgrosjean at sciviews.org)
+// Copyright (c) 2008-2009, Ph. Grosjean (phgrosjean at sciviews.org) & K. Barton
 // License: MPL 1.1/GPL 2.0/LGPL 2.1
 ////////////////////////////////////////////////////////////////////////////////
-// sv.misc.sessionData(data);     // Create or open a .csv dataset from session
-// sv.misc.sessionScript(script); // Create or open a .R script from session
-// sv.misc.sessionReport(rep);    // Create or open a .odt report from session
-// sv.misc.closeAllOthers();      // Close all buffer except current one
-// sv.misc.colorPicker();         // Invoke a color picker dialog box
-// sv.misc.moveLineDown();        // Move current line down
-// sv.misc.moveLineUp();          // Move current line up
-// sv.misc.searchBySel();         // Search next using current selection
-// sv.misc.showConfig();          // Show Komodo configuration page
-// sv.misc.swapQuotes();          // Swap single and double quotes in selection
-// sv.misc.pathToClipboard();     // Copy file path to clipboard
-// sv.misc.unixPathToClipboard(); // Copy UNIX file path to clipboard
-// sv.misc.timeStamp();           // Stamp text with current date/time
+// sv.misc.sessionData(data);       // Create/open a .csv dataset from session
+// sv.misc.sessionScript(script);   // Create/open a .R script from session
+// sv.misc.sessionReport(rep);      // Create/open a .odt report from session
+// sv.misc.closeAllOthers();        // Close all buffer except current one
+// sv.misc.colorPicker.pickColor(); // Invoke a color picker dialog box
+// sv.misc.moveLineDown();          // Move current line down
+// sv.misc.moveLineUp();            // Move current line up
+// sv.misc.searchBySel();           // Search next using current selection
+// sv.misc.showConfig();            // Show Komodo configuration page
+// sv.misc.swapQuotes();            // Swap single/double quotes in selection
+// sv.misc.pathToClipboard();       // Copy file path to clipboard
+// sv.misc.unixPathToClipboard();   // Copy UNIX file path to clipboard
+// sv.misc.timeStamp();             // Stamp text with current date/time
 ////////////////////////////////////////////////////////////////////////////////
 
 // Define the 'sv.misc' namespace
@@ -91,7 +91,7 @@
     sv.r.refreshSession();
 }
 
-// sv.misc.sessionScript(name); // Create or open a .R script from session
+// Create or open a .R script from session
 sv.misc.sessionScript = function (script) {
     if (typeof(script) == "undefined") {
         script = ko.dialogs.prompt(
@@ -114,7 +114,7 @@
     sv.r.refreshSession();
 }
 
-// sv.misc.sessionReport(name); // Create or open a .odt report from session
+// Create or open a .odt report from session
 sv.misc.sessionReport = function (rep) {
     if (typeof(rep) == "undefined") {
         rep = ko.dialogs.prompt(
@@ -176,18 +176,17 @@
 // Close all buffers except current one (an start page)
 sv.misc.closeAllOthers = function () {
     try {
-        var view = ko.views.manager.currentView;
-        if (view) {
-            var curr_uri = view.document.file.URI;
-            var views = ko.views.manager.topView.getDocumentViews(true);
-            for (var i = views.length - 1; i >= 0; i--) {
-                // Exclude the Start Page from "Close All".
+        var currentView = ko.views.manager.currentView;
+        if (currentView) {
+			currentView.scintilla.focus();
+			var views = ko.views.manager.topView.getDocumentViews(true);
+			for (var i = views.length - 1; i >= 0; i--) {
                 var thisView = views[i];
-                if (thisView.getAttribute("type") != "startpage"
-                    && thisView.document.file
-                    && thisView.document.file.URI != curr_uri) {
-                    if (! thisView.close()) {
-                    return false;
+				// Exclude the Start Page from "Close All".
+				if (thisView.getAttribute("type") != "startpage"
+                    && thisView != currentView) {
+                    if (!thisView.close()) {
+						return false;
                     }
                 }
             }
@@ -207,10 +206,8 @@
  * Modified by: Shane Caraveo
  *              Todd Whiteman
  *              Philippe Grosjean
- *              Kamil Bartoñ
+ *              Kamil Barton
  */
-
-
 sv.misc.colorPicker = {};
 
 (function() {
@@ -224,7 +221,8 @@
 			getService(Components.interfaces.koISysUtils);
 		if (!color)		color = "#000000";
 		// sysUtils.pickColor seems to be broken, does not return any value
-		// which is strange, because it is only wrapper for .pickColorWithPositioning,
+		// which is strange, because it is only wrapper for
+		// .pickColorWithPositioning,
 		// Moreover, positioning does not seem to work anyway.
 		var newcolor = sysUtils.pickColorWithPositioning(color, -1, -1);
 		//Note pickColor was fixed in Komodo 5.2.3
@@ -246,13 +244,10 @@
 			} catch(e) {
 				color = "#ffffff";
 			}
-
 			_colorPicker_system(color);
 		}
 	}
 
-
-
 } else {
 
 	function _colorPicker_onchange (event, cp) {
@@ -260,11 +255,12 @@
 		scimoz.insertText(scimoz.currentPos, cp.color);
 		// Move cursor position to end of the inserted color
 		// Note: currentPos is a byte offset, so we need to correct the length
-		var newCurrentPos = scimoz.currentPos + ko.stringutils.bytelength(cp.color);
+		var newCurrentPos = scimoz.currentPos +
+			ko.stringutils.bytelength(cp.color);
 		scimoz.currentPos = newCurrentPos;
 		// Move the anchor as well, so we don't have a selection
 		scimoz.anchor = newCurrentPos;
-		// for some reason we get the event twice, removing
+		// For some reason we get the event twice, removing
 		// onselect fixes the problem.  Tried to solve it
 		// by canceling the event below, but it went on anyway
 		cp.removeAttribute('onselect');
@@ -315,11 +311,6 @@
 
 }).apply(sv.misc.colorPicker);
 
-
-// Results similiar to following two functions can be achieved with:
-// ko.commands.doCommand('cmd_lineTranspose')
-// Remove these?
-
 // Move Line Down, adapted by Ph. Grosjean from code by "mircho"
 sv.misc.moveLineDown = function () {
     var currentView = ko.views.manager.currentView;
@@ -358,7 +349,7 @@
         var ke = currentView.scimoz;
         var searchText = ke.selText;
         if (!searchText.length) {
-            // use last pattern used
+            // Use last pattern used
             searchText = ko.mru.get("find-patternMru");
         }
 
@@ -428,7 +419,7 @@
     }
 }
 
-// Copy the UNIX version (using '/' as sep) path of current file to the clipboard
+// Copy UNIX version (using '/' as sep) path of current file to the clipboard
 sv.misc.unixPathToClipboard = function () sv.misc.pathToClipboard(true);
 
 // Stamp the current text with date - time
@@ -436,14 +427,16 @@
     try {
         var ke = ko.views.manager.currentView.scimoz;
 
-		// Adapted from setDateFormatExample() in "chrome://komodo/content/pref/pref-intl.js"
+		// Adapted from setDateFormatExample() in
+		// chrome://komodo/content/pref/pref-intl.js
 		var timeSvc = Components.classes["@activestate.com/koTime;1"]
 			.getService(Components.interfaces.koITime);
 		var secsNow = timeSvc.time();
 		var timeTupleNow = timeSvc.localtime(secsNow, new Object());
 		if (!format)
 			format = sv.prefs.getString("defaultDateFormat");
-		var timeStr = timeSvc.strftime(format, timeTupleNow.length, timeTupleNow);
+		var timeStr = timeSvc.strftime(format, timeTupleNow.length,
+			timeTupleNow);
 		ke.replaceSel(timeStr);
     } catch(e) {
         sv.log.exception(e, "sv.misc.timeStamp() error");

Modified: komodo/SciViews-K/content/js/r.js
===================================================================
--- komodo/SciViews-K/content/js/r.js	2009-12-29 11:14:28 UTC (rev 240)
+++ komodo/SciViews-K/content/js/r.js	2009-12-29 20:05:42 UTC (rev 241)
@@ -63,6 +63,10 @@
 // sv.r.clearSession();   // Clear session's .RData and .Rhistory files
 // sv.r.reloadSession();  // Reload .RData nd .Rhistory files from session dir
 // sv.r.quit(save); // Quit R (ask to save in save in not defined)
+// sv.r.kpf2pot(kpfFile); // Create a translation (.pot) file for a project
+// sv.r.kpz2pot(kpzFile); // Create a translation (.pot) file for a package
+// sv.r.kpfTranslate(kpfFile); // Translate a project
+// sv.r.kpzTranslate(kpzFile); // Translate a package
 //
 // Note: sv.r.objects is implemented in robjects.js
 //       sv.r.console functions are implemented in rconsole.js
@@ -266,7 +270,6 @@
 }
 
 // Set the current working directory (to current buffer dir, or ask for it)
-// TODO: make it update sv.prefs.setSession?
 sv.r.setwd = function (dir, ask, type) {
 	// TODO: simplify this:
 	// for compatibility with previous versions
@@ -436,7 +439,7 @@
 		var doc = kv.document;
 
 		var file;
-		if (!doc.isUntitled) {
+		if (!doc.isUntitled && doc.file) {
 			file = doc.file.path.addslashes();
 		} else {
 			file = doc.baseName;
@@ -445,17 +448,18 @@
 		if (!what)
 			what = "all"; // Default value
 
-		// Special case: if "all" and local document is saved, source as the original file
-		if (what == "all" && doc.file.isLocal && !doc.isUntitled && !doc.isDirty) {
+		// Special case: if "all" and local document is saved,
+		// source as the original file
+		if (what == "all" && doc.file && doc.file.isLocal &&
+			!doc.isUntitled && !doc.isDirty) {
 			res = sv.r.eval('source("' + file +  '", encoding = "' +
 				kv.encoding + '")');
 		} else {
-			// save all or part in the temporary file and source that file
+			// Save all or part in the temporary file and source that file.
 			// After executing, tell R to delete it.
 			var code = sv.getTextRange(what);
 			sv.cmdout.clear();
-			sv.cmdout.append(':> #source("' + file + '*") # buffer: ' +
-				what);
+			sv.cmdout.append(':> #source("' + file + '*") # buffer: ' + what);
 
 			var tempFile = sv.tools.file.temp();
 			sv.tools.file.write(tempFile, code, 'utf-8', false);
@@ -471,7 +475,7 @@
 		}
 	} catch(e) {
 		sv.log.exception(e, "Unknown error while sourcing R code in"
-			+ " sv.r.source().", true);
+			+ " sv.r.source():\n\n (" + e + ")", true);
 	}
 	return res;
 }
@@ -670,7 +674,6 @@
 	return(res);
 }
 
-
 sv.r.pager = function(file, title) {
 	var rSearchUrl = "chrome://sciviewsk/content/rsearch.html";
 	var content = sv.tools.file.read(file);
@@ -707,7 +710,6 @@
 	return(res);
 }
 
-
 // Search R web sites for topic
 sv.r.siteSearch = function (topic, idxname) {
 	var res = false;
@@ -740,7 +742,6 @@
 	"&max=20&result=normal&sort=score" + idxname;
 
 	sv.command.openHelp(url);
-
 }
 
 // List available datasets ("loaded" or not defined = loaded packages, or "all")
@@ -1436,7 +1437,83 @@
 	sv.r.objects.clearPackageList();
 }
 
+// Create a translation (.pot) file for a project
+sv.r.kpf2pot = function (kpfFile) {
+	try {
+		// Ask for the filename if not provided
+		if (typeof(kpfFile) == "undefined") {
+			var title = 'Select a Komodo project file (.kpf) to make .pot file';
+			var Filters = [];
+			Filters.push("Komodo Project");
+			kpfFile = ko.filepicker.openFile("", "project.kpf", title,
+				null, Filters);
+		}
+		if (kpfFile == null) return;	// User clicked cancel
+		sv.r.eval('require(svIDE); (kpf2pot("' + kpfFile + '"))');
+	} catch(e) {
+		sv.log.exception(e, "Unknown error while creating .pot file with"
+			+ " sv.r.kpf2pot(). (" + e + ")", true);
+	}	
+}
 
+// Create a translation (.pot) file for a package
+sv.r.kpz2pot = function (kpzFile) {
+	try {
+		// Ask for the filename if not provided
+		if (typeof(kpzFile) == "undefined") {
+			var title = 'Select a Komodo package file (.kpz) to make .pot file';
+			var Filters = [];
+			Filters.push("Komodo Package");
+			kpzFile = ko.filepicker.openFile("", "package.kpz", title,
+				null, Filters);
+		}
+		if (kpzFile == null) return;	// User clicked cancel
+		sv.r.eval('require(svIDE); (kpz2pot("' + kpzFile + '"))');
+	} catch(e) {
+		sv.log.exception(e, "Unknown error while creating .pot file with"
+			+ " sv.r.kpz2pot(). (" + e + ")", true);
+	}
+}
+
+// Translate a project
+sv.r.kpfTranslate = function (kpfFile) {
+	try {
+		// Ask for the filename if not provided
+		if (typeof(kpfFile) == "undefined") {
+			var title = 'Select a Komodo project file (.kpf) to translate';
+			var Filters = [];
+			Filters.push("Komodo Project");
+			kpfFile = ko.filepicker.openFile("", "project.kpf", title,
+				null, Filters);
+		}
+		if (kpfFile == null) return;	// User clicked cancel
+		sv.r.eval('require(svIDE); (kpfTranslate("' + kpfFile + '"))');
+	} catch(e) {
+		sv.log.exception(e, "Unknown error while translating a project file with"
+			+ " sv.r.kpfTranslate(). (" + e + ")", true);
+	}	
+} 
+
+// Translate a package
+sv.r.kpzTranslate = function (kpzFile) {
+	try {
+		// Ask for the filename if not provided
+		if (typeof(kpzFile) == "undefined") {
+			var title = 'Select a Komodo package file (.kpz) to translate';
+			var Filters = [];
+			Filters.push("Komodo Package");
+			kpzFile = ko.filepicker.openFile("", "package.kpz", title,
+				null, Filters);
+		}
+		if (kpzFile == null) return;	// User clicked cancel
+		sv.r.eval('require(svIDE); (kpzTranslate("' + kpzFile + '"))');
+	} catch(e) {
+		sv.log.exception(e, "Unknown error while translating package file with"
+			+ " sv.r.kpzTranslate(). (" + e + ")", true);
+	}		
+} 
+
+
 //// Define the 'sv.r.pkg' namespace ///////////////////////////////////////////
 if (typeof(sv.r.pkg) == 'undefined') sv.r.pkg = new Object();
 

Modified: komodo/SciViews-K/content/js/sciviews.js
===================================================================
--- komodo/SciViews-K/content/js/sciviews.js	2009-12-29 11:14:28 UTC (rev 240)
+++ komodo/SciViews-K/content/js/sciviews.js	2009-12-29 20:05:42 UTC (rev 241)
@@ -686,6 +686,13 @@
 
 	this.all = function (debug) {
 		logger.setLevel(!!debug);
+		if (logger.getEffectiveLevel() == 1) {
+			ko.statusBar.AddMessage("SciViews error logging set to debug level",
+				"svLog", 3000, true);
+		} else {
+			ko.statusBar.AddMessage("SciViews error logging set to level " +
+				logger.getEffectiveLevel(), "svLog", 3000, true);
+		}
 	}
 
 	this.isAll = function () {
@@ -693,13 +700,17 @@
 	}
 
 	this.show = function () {
+		var os = Components.classes['@activestate.com/koOs;1']
+			.getService(Components.interfaces.koIOs);
 		try {
-			var logFile = sv.tools.file.path("ProfD", ["..", "pystderr.log"]);
+			appdir = ko.interpolate.interpolateStrings('%(path:hostUserDataDir)');
+			var logFile = os.path.join(appdir,'pystderr.log');
 			var winOpts = "centerscreen,chrome,resizable,scrollbars,dialog=no,close";
-			window.openDialog('chrome://komodo/content/tail/tail.xul',"_blank",
-				winOpts,logFile);
+			window.openDialog('chrome://komodo/content/tail/tail.xul',
+				"_blank",winOpts,logFile);
 		} catch(e) {
-			this.exception(e, "Unable to display the Komodo error log!", true);
+			this.exception(e,
+				"Unable to display the Komodo error log (" + e + ")", true);
 		}
 	}
 

Modified: komodo/SciViews-K/sciviewsk-0.9.9-ko.xpi
===================================================================
(Binary files differ)

Modified: pkg/svIDE/R/kpfTranslate.R
===================================================================
--- pkg/svIDE/R/kpfTranslate.R	2009-12-29 11:14:28 UTC (rev 240)
+++ pkg/svIDE/R/kpfTranslate.R	2009-12-29 20:05:42 UTC (rev 241)
@@ -9,7 +9,13 @@
 # 3) In macros:
 #    Strings inside _("XXX"), with _() being a function returning its argument
 kpf2pot <- function (kpfFile, potFile) {
-    if (missing(potFile)) 
+    if (missing(kpfFile)  || is.null(kpfFile) || is.na(kpfFile))
+		stop("'kpfFile' must be provided")
+	if (length(kpfFile) != 1)
+		stop("You must provide only a single file name/path for 'kpfFile'")
+	if (!file.exists(kpfFile))
+		stop("The kpfFile is not found")
+	if (missing(potFile)) 
         potFile <- sub("\\.kpf", ".pot", kpfFile)
 	if (kpfFile == potFile)
 		potFile <- paste(kpfFile, "pot", sep = ".")
@@ -85,6 +91,12 @@
 }
 
 kpz2pot <- function (kpzFile, potFile) {
+	if (missing(kpzFile)  || is.null(kpzFile) || is.na(kpzFile))
+		stop("'kpzFile' must be provided")
+	if (length(kpzFile) != 1)
+		stop("You must provide only a single file name/path for 'kpzFile'")
+	if (!file.exists(kpzFile))
+		stop("The kpzFile is not found")
     if (missing(potFile)) 
         potFile <- sub("\\.kpz", ".pot", kpzFile)
 	if (kpzFile == potFile)
@@ -103,168 +115,236 @@
 	return(invisible(file.exists(potFile)))
 }
 
-kpfTranslate <- function (kpfFile, lang, poFile, kpf2File) {
-    if (missing(lang))
-		stop("You must provide 'lang' (ex.: 'fr', or 'de')")
-	po <- paste("-", lang, ".po", sep = "")
-	kpf2 <- paste("-", lang, ".kpf", sep = "")
-	if (missing(poFile)) 
-        poFile <- sub("\\.kpf", po, kpfFile)
-	if (kpfFile == poFile)
-		poFile <- paste(kpfFile, po, sep = "")
-	if (!file.exists(poFile))
-		stop("'poFile' not found!")
-	if (missing(kpf2File)) {
-		kpf2File <- sub("\\.kpf", kpf2, kpfFile)
-		if (kpfFile == kpf2File)
-			kpf2File <- paste(kpfFile, kpf2, sep = "")
-		unlink(kpf2File)  # Make sure we create a new resulting file
+kpfTranslate <- function (kpfFile, langs, poFiles, kpf2Files) {
+    if (missing(kpfFile)  || is.null(kpfFile) || is.na(kpfFile))
+		stop("'kpfFile' must be provided")
+	if (length(kpfFile) != 1)
+		stop("You must provide only a single file name/path for 'kpfFile'")
+	if (!file.exists(kpfFile))
+		stop("The kpfFile is not found")
+	proj <- sub("\\.kpf$", "", kpfFile)
+	if (missing(poFiles) || is.na(poFiles)) poFiles <- NULL
+	if (missing(langs)) {
+		if (is.null(poFiles)) {
+			# Try to get the list of suitable .po files in same dir as kpfFile
+			pattern <- paste(basename(proj), ".+\\.po$", sep = "-")
+			poFiles <- dir(dirname(kpfFile), pattern, full.names = TRUE)
+			if (length(poFiles) < 1)
+				stop("You must provide 'langs' (ex.: 'fr', or 'de'), or 'poFiles'")
+		} else langs <- NULL
 	}
-	
-	# Read the content of the .po file
-	tr <- readLines(poFile, encoding = "UTF-8")
-	# Keep only lines starting with msgid or msgstr
-	trid <- tr[regexpr("^msgid ", tr) == 1]
-	trid <- sub("^msgid ", "", trid)
-	trmsg <- tr[regexpr("^msgstr ", tr) == 1]
-	trmsg <- sub("^msgstr ", "", trmsg)
-	# Check that both trid and trmsg have same length
-	if (length(trid) != length(trmsg))
-		stop("Unequal number of id and translated strings in the .po file!")
-	keep <- trid != "\"\""
-	trid <- trid[keep]
-	trmsg <- trmsg[keep]
-
-	# We need to "unquote" the strings
-	unquote <- function (s) {
-		# Replace any \\\" by \"
-		s <- gsub("\\\\\"", "\"", s)
-		# Eliminate leading and trailing quotes
-		s <- sub("^\"", "", s)
-		s <- sub("\"$", "", s)
-		return(s)
+	if (is.null(poFiles)) {
+		if (is.null(langs))
+			stop("You must provide 'langs' (ex.: 'fr', or 'de'), or 'poFiles'")
+		# Try to guess poFiles from langs
+        poFiles <- paste(proj, "-", langs, ".po", sep = "")
 	}
-	trid <- unquote(trid)
-	trmsg <- unquote(trmsg)
-	names(trmsg) <- trid
-	
-	# Extract translatable strings from the .kpf file
-	doc <- xmlRoot(xmlTreeParse(kpfFile))
-	imax <- xmlSize(doc)
-	if (imax < 1) stop("No node found in the file!")
-	# Collect all strings to be translated
-	trans <- function (s) {
-		tr <- as.character(trmsg[s])
-		if (is.na(tr) || tr == "") return(s) else return(tr)
+	if (any(kpfFile == poFiles))
+		stop("'poFiles' cannot be the same as 'kpfFile'")
+	if (any(!file.exists(poFiles)))
+		stop("One or more 'poFiles' not found!")
+	if (missing(kpf2Files)) {
+		# Guess kpf2Files from poFiles
+		kpf2Files <- sub("\\.po$", ".kpf", poFiles)
 	}
+	if (any(kpfFile == kpf2Files))
+		stop("'kpfFile' and 'kpf2Files' cannot be the same")
+	if (any(poFiles == kpf2Files))
+		stop("'poFiles' and 'kpf2Files' cannot be the same")
+	if (length(poFiles) != length(kpf2Files))
+		stop("Number of items must be the same in 'poFiles' and in 'kpf2Files'")
+	# Make sure we create new resulting files
+	unlink(kpf2Files)
+
+	# Process each file in turn
+	for (h in 1:length(poFiles)) {
+		poFile <- poFiles[h]
+		kpf2File <- kpf2Files[h]
+		# Read the content of the .po file
+		tr <- readLines(poFile, encoding = "UTF-8")
+		# Keep only lines starting with msgid or msgstr
+		trid <- tr[regexpr("^msgid ", tr) == 1]
+		trid <- sub("^msgid ", "", trid)
+		trmsg <- tr[regexpr("^msgstr ", tr) == 1]
+		trmsg <- sub("^msgstr ", "", trmsg)
+		# Check that both trid and trmsg have same length
+		if (length(trid) != length(trmsg))
+			stop("Unequal number of id and translated strings in the .po file '", poFile, "'")
+		keep <- trid != "\"\""
+		trid <- trid[keep]
+		trmsg <- trmsg[keep]
 	
-	s <- character(0)
-	for (i in 1:imax) {
-		n <- xmlGetAttr(doc[[i]], "name")
-		if (!is.null(n)) {
-			# Replace name in attributes of this node
-			node <- addAttributes(doc[[i]], name = trans(n), append = TRUE)
-			type <- xmlName(node)
-			# If this is a snippet, look for other translatable strings
-			if (type == "snippet") {
-				snip <- xmlValue(node)
-				chunks <- strsplit(snip, "\\[\\[|\\]\\]")[[1]]
-				# Translate chunks starting with R-desc:, R-tip:, URL-help:,
-				# RWiki-help: or %tr:
-				toTrans <- grep("^%ask:R-desc:|^%ask:R-tip:|^%ask:URL-help:|^%ask:RWiki-help:|^%pref:URL-help|^%pref:RWiki-help|%tr:", chunks)
-				if (length(toTrans) > 0) {
-					for (j in toTrans) {
-						msg <- sub("^%ask:[^:]+:|%tr:", "", chunks[j])
-						header <- sub("^(%ask:[^:]+:|%tr:).*$", "\\1", chunks[j])
-						chunks[j] <- paste(header, trans(msg), sep = "")
+		# We need to "unquote" the strings
+		unquote <- function (s) {
+			# Replace any \\\" by \"
+			s <- gsub("\\\\\"", "\"", s)
+			# Eliminate leading and trailing quotes
+			s <- sub("^\"", "", s)
+			s <- sub("\"$", "", s)
+			return(s)
+		}
+		trid <- unquote(trid)
+		trmsg <- unquote(trmsg)
+		names(trmsg) <- trid
+		
+		# Extract translatable strings from the .kpf file
+		doc <- xmlRoot(xmlTreeParse(kpfFile))
+		imax <- xmlSize(doc)
+		if (imax < 1) stop("No node found in the kpfFile!")
+		# Collect all strings to be translated
+		trans <- function (s) {
+			tr <- as.character(trmsg[s])
+			if (is.na(tr) || tr == "") return(s) else return(tr)
+		}
+		
+		s <- character(0)
+		for (i in 1:imax) {
+			n <- xmlGetAttr(doc[[i]], "name")
+			if (!is.null(n)) {
+				# Replace name in attributes of this node
+				node <- addAttributes(doc[[i]], name = trans(n), append = TRUE)
+				type <- xmlName(node)
+				# If this is a snippet, look for other translatable strings
+				if (type == "snippet") {
+					snip <- xmlValue(node)
+					chunks <- strsplit(snip, "\\[\\[|\\]\\]")[[1]]
+					# Translate chunks starting with R-desc:, R-tip:, URL-help:,
+					# RWiki-help: or %tr:
+					toTrans <- grep("^%ask:R-desc:|^%ask:R-tip:|^%ask:URL-help:|^%ask:RWiki-help:|^%pref:URL-help|^%pref:RWiki-help|%tr:", chunks)
+					if (length(toTrans) > 0) {
+						for (j in toTrans) {
+							msg <- sub("^%ask:[^:]+:|%tr:", "", chunks[j])
+							header <- sub("^(%ask:[^:]+:|%tr:).*$", "\\1", chunks[j])
+							chunks[j] <- paste(header, trans(msg), sep = "")
+						}
+						# Reconstitute the snippet content using translated messages
+						snip <- paste(chunks, c("[[", "]]"),
+							sep = "", collapse = "")
+						# We need to eliminate latest '[['
+						snip <- sub("\\[\\[$", "", snip)
+						xmlValue(node) <- snip
 					}
-					# Reconstitute the snippet content using translated messages
-					snip <- paste(chunks, c("[[", "]]"),
-						sep = "", collapse = "")
-					# We need to eliminate latest '[['
-					snip <- sub("\\[\\[$", "", snip)
-					xmlValue(node) <- snip
+				} else if (type == "macro") {
+					mac <- xmlValue(node)
+					# Translate tagged strings (i.e., strings inside _(...))
+					repeat {
+						str <- sub("^.*_\\(\"(.*[^\\\\])\"\\).*$", "\\1", mac)
+						if (str == mac) break
+						s <- trans(gsub('\\\\"', '"', str))
+						s <- gsub('"', '\\"', s)
+						mac <- sub("^(.*)(_\\(\".*[^\\\\]\"\\))(.*)$",
+							paste("\\1%%%%%%(\"", s, "\")\\3", sep = ""), mac)
+					}
+					repeat {
+						str <- sub("^.*_\\('(.*[^\\\\])'\\).*$", "\\1", mac)
+						if (str == mac) break
+						s <- trans(gsub("\\\\'", "'", str))
+						s <- gsub("'", "\\'", s)
+						mac <- sub("^(.*)(_\\('.*[^\\\\]'\\))(.*)$",
+							paste("\\1%%%%%%('", s, "')\\3", sep = ""), mac)
+					}
+					mac <- gsub("%%%%%%", "_", mac)
+					xmlValue(node) <- mac
 				}
-			} else if (type == "macro") {
-				mac <- xmlValue(node)
-				# Translate tagged strings (i.e., strings inside _(...))
-				repeat {
-					str <- sub("^.*_\\(\"(.*[^\\\\])\"\\).*$", "\\1", mac)
-					if (str == mac) break
-					s <- trans(gsub('\\\\"', '"', str))
-					s <- gsub('"', '\\"', s)
-					mac <- sub("^(.*)(_\\(\".*[^\\\\]\"\\))(.*)$",
-						paste("\\1%%%%%%(\"", s, "\")\\3", sep = ""), mac)
-				}
-				repeat {
-					str <- sub("^.*_\\('(.*[^\\\\])'\\).*$", "\\1", mac)
-					if (str == mac) break
-					s <- trans(gsub("\\\\'", "'", str))
-					s <- gsub("'", "\\'", s)
-					mac <- sub("^(.*)(_\\('.*[^\\\\]'\\))(.*)$",
-						paste("\\1%%%%%%('", s, "')\\3", sep = ""), mac)
-				}
-				mac <- gsub("%%%%%%", "_", mac)
-				xmlValue(node) <- mac
+				# Replace the node with its translated version
+				doc[[i]] <- node
 			}
-			# Replace the node with its translated version
-			doc[[i]] <- node
 		}
+		# In case the project has a name, we change it now
+		projname <- xmlGetAttr(doc, "name")
+		if (!is.null(projname))
+			doc <- addAttributes(doc, name = basename(kpf2File), append = TRUE)
+		
+		# Make sure the directory where to place the kpf2File exists
+		dir.create(dirname(kpf2File), showWarnings = FALSE, recursive = TRUE)
+		
+		# Save the translated XML content into the second .kpf file
+		saveXML(doc, file = kpf2File, prefix = '<?xml version="1.0" encoding="UTF-8"?>\n<!-- Komodo Project File - DO NOT EDIT -->\n')
 	}
-	# In case the project has a name, we change it now
-	projname <- xmlGetAttr(doc, "name")
-	if (!is.null(projname))
-		doc <- addAttributes(doc, name = basename(kpf2File), append = TRUE)
-	
-	# Save the translated XML content into the second .kpf file
-	saveXML(doc, file = kpf2File, prefix = '<?xml version="1.0" encoding="UTF-8"?>\n<!-- Komodo Project File - DO NOT EDIT -->\n')
-	# Check that the new .kpf file is produced
-	return(invisible(file.exists(kpf2File)))	
+	# We don't need .mo files => delete them
+	moFiles <- sub("\\.po$", ".mo", poFiles)
+	if (any(moFiles != poFiles))
+		unlink(moFiles)
+	# Check that all the translated .kpf files are produced
+	res <- file.exists(kpf2Files)
+	names(res) <- basename(kpf2Files)
+	return(invisible(res))	
 }
 
-kpzTranslate <- function (kpzFile, lang, poFile, kpz2File) {
-    if (missing(lang))
-		stop("You must provide 'lang' (ex.: 'fr', or 'de')")
-	po <- paste("-", lang, ".po", sep = "")
-	kpz2 <- paste("-", lang, ".kpz", sep = "")
-	if (missing(poFile)) 
-        poFile <- sub("\\.kpz", po, kpzFile)
-	if (kpzFile == poFile)
-		poFile <- paste(kpzFile, po, sep = "")
-	if (!file.exists(poFile))
-		stop("'poFile' not found!")
-	if (missing(kpz2File))
-		kpz2File <- sub("\\.kpz", kpz2, kpzFile)
-	if (kpzFile == kpz2File)
-		kpz2File <- paste(kpzFile, kpz2, sep = "")
-	unlink(kpz2File)  # Make sure we create a new resulting file
+kpzTranslate <- function (kpzFile, langs, poFiles, kpz2Files) {
+    if (missing(kpzFile)  || is.null(kpzFile) || is.na(kpzFile))
+		stop("'kpzFile' must be provided")
+	if (length(kpzFile) != 1)
+		stop("You must provide only a single file name/path for 'kpzFile'")
+	if (!file.exists(kpzFile))
+		stop("The kpzFile is not found")
+	proj <- sub("\\.kpz$", "", kpzFile)
+	if (missing(poFiles) || is.na(poFiles)) poFiles <- NULL
+	if (missing(langs)) {
+		if (is.null(poFiles)) {
+			# Try to get the list of suitable .po files in same dir as kpfFile
+			pattern <- paste(basename(proj), ".+\\.po$", sep = "-")
+			poFiles <- dir(dirname(kpzFile), pattern, full.names = TRUE)
+			if (length(poFiles) < 1)
+				stop("You must provide 'langs' (ex.: 'fr', or 'de'), or 'poFiles'")
+		} else langs <- NULL
+	}
+	if (is.null(poFiles)) {
+		if (is.null(langs))
+			stop("You must provide 'langs' (ex.: 'fr', or 'de'), or 'poFiles'")
+		# Try to guess poFiles from langs
+        poFiles <- paste(proj, "-", langs, ".po", sep = "")
+	}
+	if (any(kpzFile == poFiles))
+		stop("'poFiles' cannot be the same as 'kpzFile'")
+	if (any(!file.exists(poFiles)))
+		stop("One or more 'poFiles' not found!")
+	if (missing(kpz2Files)) {
+		# Guess kpz2Files from poFiles
+		kpz2Files <- sub("\\.po$", ".kpz", poFiles)
+	}
+	if (any(kpzFile == kpz2Files))
+		stop("'kpzFile' and 'kpz2Files' cannot be the same")
+	if (any(poFiles == kpz2Files))
+		stop("'poFiles' and 'kpz2Files' cannot be the same")
+	if (length(poFiles) != length(kpz2Files))
+		stop("Number of items must be the same in 'poFiles' and in 'kpz2Files'")
+	# Make sure we create new resulting files
+	unlink(kpz2Files)
 	
     # The kpz file is a zipped file containing package.kpf in a subdirectory
-	f <- file.path(tempdir(), "package.kpf")
-	unlink(f)	# Make sure the file does not exist yet
+	pack <- file.path(tempdir(), "package.kpf")
+	unlink(pack)	# Make sure the file does not exist yet
 	unzip(kpzFile, junkpaths = TRUE, exdir = tempdir())
-	if (!file.exists(file.path(tempdir(), "package.kpf")))
+	if (!file.exists(pack))
 		stop("Impossible to extract the content of the .kpz file.")
+	# kpf2Files are "package.kpf" files in respective subdirectories with names
+	# of the packages, like mypack-fr, mypack-it, etc.
+	kpf2Dirs <- file.path(tempdir(), sub("\\.kpz$", "", basename(kpz2Files)))
+	kpf2Files <- file.path(kpf2Dirs, "package.kpf")
 	
 	# Call kpfTranslate on the created package.kpf file
-	kpfTranslate(f, lang, poFile, f)
+	kpfTranslate(pack, poFiles = poFiles, kpf2Files = kpf2Files)
 	
-	# Compress the file in a kpz zipped archive named kpz2File
-	# Create a directory of the same name as the package
-	d <- sub("\\\\.kpz$", "", basename(kpz2File))
-	d <- file.path(dirname(f), d)
-	dir.create(d)
-	# Move the package.kpf file there
-	f2 <- file.path(d, "package.kpf")
-	file.copy(f, f2)
-	unlink(f)
-	# Compress (zip) the directory
+	# Eliminate the temporary extracted package.kpf file
+	unlink(pack)
 	odir <- getwd()
 	on.exit(setwd(odir))
-	setwd(dirname(kpz2File))
-	# Note: the 'zip' program must be accessible!
-	cmd <- paste('zip -rqm9 "', basename(kpz2File), '" "', d, '"', sep = "")
-	try(system(cmd, intern = TRUE, wait = TRUE), silent = TRUE)
-	# Check that the file is produced
-	return(invisible(file.exists(kpz2File)))
+	# Compress the created files in kpz zipped archives named kpz2Files	
+	for (h in 1:length(kpz2Files)) {
+		kpz2File <- kpz2Files[h]
+		kpf2Dir <- kpf2Dirs[h]
+		if (file.exists(kpf2Dir)) {
+			setwd(dirname(kpz2File))
+			# Note: the 'zip' program must be accessible!
+			cmd <- paste('zip -rqm9 "', basename(kpz2File), '" "', kpf2Dir, '"',
+				sep = "")
+			try(system(cmd, intern = TRUE, wait = TRUE), silent = TRUE)
+		}
+	}
+	
+	# Check that all the translated .kpz files are produced
+	res <- file.exists(kpz2Files)
+	names(res) <- basename(kpz2Files)
+	return(invisible(res))	
 }

Modified: pkg/svIDE/man/kpfTranslate.Rd
===================================================================
--- pkg/svIDE/man/kpfTranslate.Rd	2009-12-29 11:14:28 UTC (rev 240)
+++ pkg/svIDE/man/kpfTranslate.Rd	2009-12-29 20:05:42 UTC (rev 241)
@@ -4,107 +4,124 @@
 \alias{kpfTranslate}
 \alias{kpzTranslate}
 
-\title{ Create a POT file or use a PO file to allow translating Komodo project (.kpf) or package (.kpz) }
+\title{
+  Create a POT file or use a PO file to allow translating Komodo project
+  (.kpf) or package (.kpz)
+}
 
 \description{
-  Komodo Edit/IDE snippets are static elements and do not allow to use translation
[TRUNCATED]

To get the complete diff run:
    svnlook diff /svnroot/sciviews -r 241


More information about the Sciviews-commits mailing list