Here’s a script that lets you export your whole OmegaT project into an HTML file with one or more tables, one for each source file. The left column will have source segments, and the right will be either blank if the segment isn’t translated, or populated with translation (or , if translation was set to be empty). Each table will have source file name for its heading. The script was requested and kindly sponsored by Roman Mironov at Translation Agency Velior. As usual, in the below listing the heading is a link to pastebin.com where you can download this script. Continue reading
Tag Archives: omegat
Export relavant TU’s from legacy TMX files in OmegaT
Situation
You have a new project and legacy translation memory files that usually go to /tm folder of OmegaT project. You need to give this project to someone else, but you don’t want to give away all of your previous translation. Somehow you need to extract from your TMX files only those TU’s that have matches in the current project.
Problem
The problem is evident — you need OmegaT to get matches for each segment, and if they are any good, store them somewhere handy, in a separate TMX file.
The problem has been (or still is) discussed on OmegaT Yahoo Group.
Solution
lame GUI update to the new TMX export
This is an update to the previous post about exporting new translations to a TMX.
The script doesn’t have a GUI to select date and time or to specify whether it should work globally or on selected files. This update still doesn’t have that GUI, but provides for an external program to fill that gap. In this post I’m sharing the updated groovy script and a simple bash+zenity wizard-like script for Linux that acquires necessary data.
If no such external program/script exists, the groovy script continues to work as before without any extra fuss.
-
write_new_trans2TMX_extGUI.groovy
/* * Purpose: Export new translations completed after the specified * date (line 21) either for the entire project or for the * selected files ("select_files" must be set to 'yes' — line 27) * to TMX file * #Files: Writes 'translated_after_<date_time>.tmx' * in the current project's root * #File format: TMX v.1.4 * #Details: http:/ /wp.me / p3fHEs-6z * * @author Kos Ivantsov * @date 2013-08-12 * @version 0.3 */ /* * The date should be specified as "year-month-day HOURS:minutes" * If not specified or specified wrongly, the script will look for * translations that are newer than one day. */ def newdate = '' /* * Set "select_files" to 'yes' if you want to use file selector * to specify files for export. If anything else is specified, the script * will work with the complete project. */ select_files = '' import javax.swing.JFileChooser import org.omegat.util.StaticUtils import org.omegat.util.TMXReader import static javax.swing.JOptionPane.* import static org.omegat.util.Platform.* def prop = project.projectProperties if (!prop) { final def title = 'Export new translation' final def msg = 'Please try again after you open a project.' showMessageDialog null, msg, title, INFORMATION_MESSAGE return } /* * If you want to use an external date and time selector and a window to * ask whether you want to select individual files, specify the whole path * to that program/script. It should print out date in the proper format * on the first line of the stout, and "yes" or anything else on the second * line. */ def command = "/home/user/.omegat/script/new2tmx_tweak" try { proc = command.execute() proc.waitFor() //console.println "${proc.in.text}" def lines = "${proc.in.text}".readLines() newdate = lines[0] select_files = lines[1] } catch(java.io.IOException ex){ if (ex.getMessage() =~ 'error=13'){ console.println "The program is not executable" } if (ex.getMessage() =~ 'error=2'){ console.println "The program is not found" } } try { newdate = new Date().parse("yyyy-MM-dd HH:mm", newdate) } catch (java.text.ParseException e) { newdate = new Date().minus(1) final def title = 'Wrong date format' final def msg = """\ The date has been specified in a wrong format. The script will work with entries exactly one day old, i.e. changed after $newdate\ """ console.println msg showMessageDialog null, msg, title, INFORMATION_MESSAGE } namedate = new Date().parse("E MMM dd H:m:s z yyyy", newdate.toString()).format("MMM-dd-yyyy_HH.mm") def fileloc = prop.projectRoot+'translated_after_'+namedate+"${ (select_files == 'yes') ? "_select" : ''}"+'.tmx' exportfile = new File(fileloc) if (prop.isSentenceSegmentingEnabled()) segmenting = TMXReader.SEG_SENTENCE else segmenting = TMXReader.SEG_PARAGRAPH def sourceLocale = prop.getSourceLanguage().toString() def targetLocale = prop.getTargetLanguage().toString() exportfile.write("", 'UTF-8') exportfile.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", 'UTF-8') exportfile.append("<!DOCTYPE tmx SYSTEM \"tmx11.dtd\">\n", 'UTF-8') exportfile.append("<tmx version=\"1.4\">\n", 'UTF-8') exportfile.append(" <header\n", 'UTF-8') exportfile.append(" creationtool=\"OmegaTScripting\"\n", 'UTF-8') exportfile.append(" segtype=\"" + segmenting + "\"\n", 'UTF-8') exportfile.append(" o-tmf=\"OmegaT TMX\"\n", 'UTF-8') exportfile.append(" adminlang=\"EN-US\"\n", 'UTF-8') exportfile.append(" srclang=\"" + sourceLocale + "\"\n", 'UTF-8') exportfile.append(" datatype=\"plaintext\"\n", 'UTF-8') exportfile.append(" >\n", 'UTF-8') def hitcount = 0 if ((select_files == 'yes')) { srcroot = new File(prop.getSourceRoot()) sourceroot = prop.getSourceRoot().toString() as String JFileChooser fc = new JFileChooser( currentDirectory: srcroot, dialogTitle: "Choose files to export", fileSelectionMode: JFileChooser.FILES_ONLY, //the file filter must show also directories, in order to be able to look into them multiSelectionEnabled: true) if(fc.showOpenDialog() != JFileChooser.APPROVE_OPTION) { console.println "Canceled" return } if (!(fc.selectedFiles =~ sourceroot.replaceAll(/\\+/, '\\\\\\\\'))) { console.println "Selection outside of ${prop.getSourceRoot()} folder" final def title = 'Wrong file(s) selected' final def msg = "Files must be in ${prop.getSourceRoot()} folder." showMessageDialog null, msg, title, INFORMATION_MESSAGE return } fc.selectedFiles.each { fl = "${it.toString()}" - "$sourceroot" exportfile.append(" <prop type=\"Filename\">" + fl + "</prop>\n", 'UTF-8') } exportfile.append(" </header>\n", 'UTF-8') exportfile.append(" <body>\n", 'UTF-8') fc.selectedFiles.each{ fl = "${it.toString()}" - "$sourceroot" files = project.projectFiles files.each{ if ( "${it.filePath}" != "$fl" ) { println "Skipping to the next file" }else{ it.entries.each { def info = project.getTranslationInfo(it) def changeId = info.changer def changeDate = info.changeDate def creationId = info.creator def creationDate = info.creationDate def alt = 'unknown' if (info.isTranslated()) { if (newdate.before(new Date(changeDate))){ hitcount++ source = StaticUtils.makeValidXML(it.srcText) target = StaticUtils.makeValidXML(info.translation) exportfile.append(" <tu>\n", 'UTF-8') exportfile.append(" <tuv xml:lang=\"" + sourceLocale + "\">\n", 'UTF-8') exportfile.append(" <seg>" + "$source" + "</seg>\n", 'UTF-8') exportfile.append(" </tuv>\n", 'UTF-8') exportfile.append(" <tuv xml:lang=\"" + targetLocale + "\"", 'UTF-8') exportfile.append(" changeid=\"${changeId ?: alt }\"", 'UTF-8') exportfile.append(" changedate=\"${ changeDate > 0 ? new Date(changeDate).format("yyyyMMdd'T'HHmmss'Z'") : alt }\"", 'UTF-8') exportfile.append(" creationid=\"${creationId ?: alt }\"", 'UTF-8') exportfile.append(" creationdate=\"${ creationDate > 0 ? new Date(creationDate).format("yyyyMMdd'T'HHmmss'Z'") : alt }\"", 'UTF-8') exportfile.append(">\n", 'UTF-8') exportfile.append(" <seg>" + "$target" + "</seg>\n", 'UTF-8') exportfile.append(" </tuv>\n", 'UTF-8') exportfile.append(" </tu>\n", 'UTF-8') } } } } } } } else { exportfile.append(" </header>\n", 'UTF-8') exportfile.append(" <body>\n", 'UTF-8') files = project.projectFiles files.each { it.entries.each { def info = project.getTranslationInfo(it) def changeId = info.changer def changeDate = info.changeDate def creationId = info.creator def creationDate = info.creationDate def alt = 'unknown' if (info.isTranslated()) { if (newdate.before(new Date(changeDate))){ hitcount++ source = StaticUtils.makeValidXML(it.srcText) target = StaticUtils.makeValidXML(info.translation) exportfile.append(" <tu>\n", 'UTF-8') exportfile.append(" <tuv xml:lang=\"" + sourceLocale + "\">\n", 'UTF-8') exportfile.append(" <seg>" + "$source" + "</seg>\n", 'UTF-8') exportfile.append(" </tuv>\n", 'UTF-8') exportfile.append(" <tuv xml:lang=\"" + targetLocale + "\"", 'UTF-8') exportfile.append(" changeid=\"${changeId ?: alt }\"", 'UTF-8') exportfile.append(" changedate=\"${ changeDate > 0 ? new Date(changeDate).format("yyyyMMdd'T'HHmmss'Z'") : alt }\"", 'UTF-8') exportfile.append(" creationid=\"${creationId ?: alt }\"", 'UTF-8') exportfile.append(" creationdate=\"${ creationDate > 0 ? new Date(creationDate).format("yyyyMMdd'T'HHmmss'Z'") : alt }\"", 'UTF-8') exportfile.append(">\n", 'UTF-8') exportfile.append(" <seg>" + "$target" + "</seg>\n", 'UTF-8') exportfile.append(" </tuv>\n", 'UTF-8') exportfile.append(" </tu>\n", 'UTF-8') } } } } } exportfile.append(" </body>\n", 'UTF-8') exportfile.append("</tmx>", 'UTF-8') final def title = 'TMX file written' final def msg = "$hitcount TU's written to " + exportfile.toString() console.println msg showMessageDialog null, msg, title, INFORMATION_MESSAGE returnThe only difference compared to the previous version is lines 43-66. The external program is specified in line 50.
- new2tmx_tweak
#!/bin/bash DATE=$(zenity --calendar \ --title "Select date" \ --text="TU's newer than the selected date will be used for export" \ --date-format=%F) HRS=({00..24}) MINS=({00..59}) HRS=$(zenity --entry --title "Select time" \ --text="Hours" \ --entry-text="${HRS[@]}" ) MINS=$(zenity --entry --title "Select time" \ --text="Minutes" \ --entry-text="${MINS[@]}" ) zenity --question --title="Select Files" \ --text="Do you want to select individual files for export?" if [ $? == "0" ]; then FILESEL='yes' else FILESEL='no' fi echo "$DATE $HRS:$MINS" echo $FILESELThis script should be saved somewhere (in this example it’s /home/user/.omegat/script/new2tmx_tweak) and made executable (
chmod +x /home/user/.omegat/script/new2tmx_tweak). Zenity should be installed for it to work. One can cook up a nicer GUI using other tools, of course, but this serves just as a quick example. I guess, similar can be done using AutoIt or AutoHotKey on MS Windows or AppleScript on OSX.
If you happen to come up with your own date and time picker for this, feel free to share in comments or link to your solution.
But as of now,
Good luck!
Export TMX for new translations
Here’s a script that lets you export translation units that are newer than a specified date. It might be useful if you get a project with a legacy TMX containing some perfect matches (that memory should be put into /tm/auto), and you want to be able to run QA tests only on new TU’s that have been translated since you’ve started to work on the project, or you want to keep your own translations for later and don’t really care for what has been translated before.
If the script is invoked without changing or specifying anything, it looks for TU’s that are one day old and works globally on the whole project. If you need to filter TU’s older or newer than that, you’ll have to specify the date on line 21.
The date should be in “yyyy-MM-dd HH:mm” (4_digit_year-2_digit_month-2_digit_day space 2_digit_hour_in_military_notation:2_digit_minute) format. If not specified properly, it will fall back to the default one-day-old value.
Beside that, the user can specify whether the script should work globally on the entire project, or only on selected files. To enable file selection, the line 27 should read:
select_files = 'yes'
Anything other than ‘yes’ means the script will work globally. Continue reading
Export TMX for selected files
OmegaT exports TMX for current files in the project every time translated documents are created. It writes three TMX files in the root of the project. But what if you need a translation memory file that contains translation units of only one or several files, not all that are currently present in the project. One solution is to temporarily move unneeded files out of source folder, reload the project and then create translated documents. But it is somewhat awkward and time consuming.
Here’s a groovy script that lets you select one or several files located in the same subfolder of the current project’s /source. Once they are selected, the script writes selected_files.[date_time].tmx in the project root. This TMX-file contains TU’s only for the selected files.
- write_sel_files2TMX.groovy
/* * Purpose: Export source and translation segments of user selected * files into TMX-file * #Files: Writes 'selected_files_<date_time>.tmx' in the current project's root * #File format: TMX v.1.4 * #Details: http:/ /wp.me / p3fHEs-6g * * @author Kos Ivantsov * @date 2013-08-12 * @version 0.3 */ import javax.swing.JFileChooser import org.omegat.util.StaticUtils import org.omegat.util.TMXReader import static javax.swing.JOptionPane.* import static org.omegat.util.Platform.* def prop = project.projectProperties if (!prop) { final def title = 'Export TMX from selected files' final def msg = 'Please try again after you open a project.' showMessageDialog null, msg, title, INFORMATION_MESSAGE return } def curtime = new Date().format("MMM-dd-yyyy_HH.mm") srcroot = new File(prop.getSourceRoot()) def fileloc = prop.projectRoot+'selected_files_'+curtime+'.tmx' exportfile = new File(fileloc) def sourceroot = prop.getSourceRoot().toString() as String JFileChooser fc = new JFileChooser( currentDirectory: srcroot, dialogTitle: "Choose files to export", fileSelectionMode: JFileChooser.FILES_ONLY, //the file filter must show also directories, in order to be able to look into them multiSelectionEnabled: true) if(fc.showOpenDialog() != JFileChooser.APPROVE_OPTION) { console.println "Canceled" return } if (!(fc.selectedFiles =~ sourceroot.replaceAll(/\\+/, '\\\\\\\\'))) { console.println "Selection outside of ${prop.getSourceRoot()} folder" final def title = 'Wrong file(s) selected' final def msg = "Files must be in ${prop.getSourceRoot()} folder." showMessageDialog null, msg, title, INFORMATION_MESSAGE return } if (prop.isSentenceSegmentingEnabled()) segmenting = TMXReader.SEG_SENTENCE else segmenting = TMXReader.SEG_PARAGRAPH def sourceLocale = prop.getSourceLanguage().toString() def targetLocale = prop.getTargetLanguage().toString() exportfile.write("", 'UTF-8') exportfile.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", 'UTF-8') exportfile.append("<!DOCTYPE tmx SYSTEM \"tmx11.dtd\">\n", 'UTF-8') exportfile.append("<tmx version=\"1.4\">\n", 'UTF-8') exportfile.append(" <header\n", 'UTF-8') exportfile.append(" creationtool=\"OmegaTScripting\"\n", 'UTF-8') exportfile.append(" segtype=\"" + segmenting + "\"\n", 'UTF-8') exportfile.append(" o-tmf=\"OmegaT TMX\"\n", 'UTF-8') exportfile.append(" adminlang=\"EN-US\"\n", 'UTF-8') exportfile.append(" srclang=\"" + sourceLocale + "\"\n", 'UTF-8') exportfile.append(" datatype=\"plaintext\"\n", 'UTF-8') exportfile.append(" >\n", 'UTF-8') fc.selectedFiles.each{ fl = "${it.toString()}" - "$sourceroot" exportfile.append(" <prop type=\"Filename\">" + fl + "</prop>\n", 'UTF-8') } exportfile.append(" </header>\n", 'UTF-8') exportfile.append(" <body>\n", 'UTF-8') def count = 0 fc.selectedFiles.each{ fl = "${it.toString()}" - "$sourceroot" files = project.projectFiles files.each{ if ( "${it.filePath}" != "$fl" ) { println "Skipping to the next file" }else{ it.entries.each { def info = project.getTranslationInfo(it) def changeId = info.changer def changeDate = info.changeDate def creationId = info.creator def creationDate = info.creationDate def alt = 'unknown' if (info.isTranslated()) { source = StaticUtils.makeValidXML(it.srcText) target = StaticUtils.makeValidXML(info.translation) exportfile.append(" <tu>\n", 'UTF-8') exportfile.append(" <tuv xml:lang=\"" + sourceLocale + "\">\n", 'UTF-8') exportfile.append(" <seg>" + "$source" + "</seg>\n", 'UTF-8') exportfile.append(" </tuv>\n", 'UTF-8') exportfile.append(" <tuv xml:lang=\"" + targetLocale + "\"", 'UTF-8') exportfile.append(" changeid=\"${changeId ?: alt }\"", 'UTF-8') exportfile.append(" changedate=\"${ changeDate > 0 ? new Date(changeDate).format("yyyyMMdd'T'HHmmss'Z'") : alt }\"", 'UTF-8') exportfile.append(" creationid=\"${creationId ?: alt }\"", 'UTF-8') exportfile.append(" creationdate=\"${ creationDate > 0 ? new Date(creationDate).format("yyyyMMdd'T'HHmmss'Z'") : alt }\"", 'UTF-8') exportfile.append(">\n", 'UTF-8') exportfile.append(" <seg>" + "$target" + "</seg>\n", 'UTF-8') exportfile.append(" </tuv>\n", 'UTF-8') exportfile.append(" </tu>\n", 'UTF-8') count++; } } } } } exportfile.append(" </body>\n", 'UTF-8') exportfile.append("</tmx>", 'UTF-8') final def title = 'TMX file written' final def msg = "$count TU's written to " + exportfile.toString() console.println msg showMessageDialog null, msg, title, INFORMATION_MESSAGE returnThe TMX file is rewritten each time the script in invoked.
Big thank you goes to Roman Mironov and Velior Translation Agency for the idea and comprehensive support.
Suggestions and comments are always welcome.
But as of now,
Good luck!
Write all source segments to a file
Update: Please, download scripts from the dedicated SF.net project page where they are maintained. Scripts at the links below might be obsolete (though most likely still working).
Since we started to make OmegaT write stuff to files, let’s try to dump all source segments to one file. I’m pretty sure one can find some use for it.
/*
* #Purpose: Write all source segments to a file
* #Files: Writes 'allsource.txt' in the current project's root
*
* @author: Kos Ivantsov
* @date: 2013-07-16
* @version: 0.2
*/
/* change "includefilenames" to anything but 'yes' (with quotes)
* if you don't need filenames to be included in the file */
def includefilenames = 'no'
def includerepetitions = 'no'
import static javax.swing.JOptionPane.*
import static org.omegat.util.Platform.*
// abort if a project is not opened yet
def prop = project.projectProperties
if (!prop) {
final def title = 'Source to File'
final def msg = 'Please try again after you open a project.'
showMessageDialog null, msg, title, INFORMATION_MESSAGE
return
}
def folder = prop.projectRoot+'/script_output'
def fileloc = folder+'/allsource.txt'
writefile = new File(fileloc)
if (! (new File(folder)).exists()) {
(new File(folder)).mkdir()
}
writefile.write("", 'UTF-8')
def count = 0
def uniqline
if (includefilenames == 'yes') {
files = project.projectFiles;
for (i in 0 ..< files.size())
{
fi = files[i];
marker = "+${'='*fi.filePath.size()}+\n"
writefile.append("$marker|$fi.filePath|\n$marker", 'UTF-8')
for (j in 0 ..< fi.entries.size())
{
ste = fi.entries[j];
source = ste.getSrcText();
writefile.append source +"\n", 'UTF-8'
count++;
}
}
} else {
project.allEntries.each { ste ->
source = ste.getSrcText();
writefile.append source+"\n",'UTF-8'
count++
}
console.println "$count segments found in all files"
if (includerepetitions != 'yes') {
count = 0
uniqline = writefile.readLines().unique()
//console.println uniqline
writefile.write("",'UTF-8')
uniqline.each {
writefile.append "$it\n\n",'UTF8';
count++
}
}
}
console.println count +" segments written to "+ writefile
final def title = 'Source to File'
final def msg = count +" segments"+"\n"+"written to \n"+ writefile
showMessageDialog null, msg, title, INFORMATION_MESSAGE
return
Once the script is invoked, it’ll create a file named “allsource.txt” in the current project’s root folder, where each segment will be on a new line. It’ll contain all the segments, even the ones that are already translated, and all the repetitions. The script can either just dump all segments into the file, or write out a filename in a box like this
+====+
|file|
+====+
followed by all the segments that belong to this file, and then a new filename and respective segment, and so on, or just dump all the segments in the order they appear in OmegaT without indicating what files they belong to. This behavior can be triggered by changing line 13. When it says def includefilenames = 'yes', you’ll get filenames written to the allsource.txt, but if you don’t want the filenames, change ‘yes’ to anything else or even leave it empty, making sure you have quotes, i.e. it can say def includefilenames = 'no, thanks' or even def includefilenames = '', but not def includefilenames = no (no quotes in the last example).
The way the filenames get marked is defined in lines 44, 45.
If filenames are not included, one can choose whether to include repetitions (line 14). 'yes' means “yes”, anything else, even 'yep', means “no”.
Suggestions, enhancements, bug reports, donations, postcards, invitations to a cup of coffee, feature requests, interesting translation projects with a good pay etc. are always welcome. Criticism isn’t, but will be accepted too.
But as of now,
Good luck
SVN status
Here’s a little script that checks current SVN status of various files in an OmegaT team project. May not be awfully useful, but sometimes it can help you prevent or solve SVN sync issues. It doesn’t do anything special, just shows you the status of the project’s project_save.tmx, main writable glossary, current file and the whole project folder. Continue reading
Batch Search and Replace and Selective Pretranslation in OmegaT
Update: Most of the post ramains true, but make sure you download these scripts from the SF.net repository.
In this post I want to share three scripts that can do an extended search and replace in OmegaT project. Search and replace templates for each script are specified in external plain text files located in project’s root folder, so these scripts without any modifications can be used for different projects with different sets of search and replace patterns — the user needs to modify only those plain text files as needed. On top of text modification there is a possibility to do a simple math on what is being found by the script thus enabling the user to have a per project unit converter.
Each script should be accompanied by its own external file located in a subfolder named .ini in the project’s root (details under each script further on). The format of these files is the same for all three:
- Only one empty line in the file — the very last one
- Each line consists of tree blocks:
- Search pattern (regex aware)
- Tab
- Replace pattern
So, if you need to replace “Владимир Владимирович” (taking into consideration different cases of Russian nouns) with “the President of Russian Federation“, here’s what you need to specify in the substitution file:
Владимир\p{L}?+\sВладимирович\p{L}?+ the President of Russian Federation Continue reading
Stripping Tags Everywhere, Groovy Way
Every once in a while you have to deal with a match that has wrong tags. Hopefully, pretty soon OmegaT will be smart enough to deal with such matches for you, making it possible to insert a wrongly tagged match in such a way that you wouldn’t have to fix tags — they’ll get fixed on their own. But while we are not there yet, a practical workaround is to use the match tag-free and to insert proper tags wherever needed (OmegaT 3 lets you insert them one by one, and a new default shortcut for that is Ctrl+T).
In this post I share 5 groovy scripts to strip tags in different situations (headings link to pastebin.com, files can be downloaded from there):
- Replacing target with match
/* * #Purpose: Replace current target with tag-free match * #Details: http: // wp.me/p3fHEs-4W * * @author Kos Ivantsov * @date 2013-06-26 * @version 0.1 */ import static javax.swing.JOptionPane.* import static org.omegat.util.Platform.* import org.omegat.core.Core; // abort if a project is not opened yet def prop = project.projectProperties if (!prop) { final def title = 'Replace with Match (no tags)' final def msg = 'Please try again after you open a project.' showMessageDialog null, msg, title, INFORMATION_MESSAGE return } def match = Core.getMatcher() def near = match.getActiveMatch() if (near != null) { def matchtranslation = "$near.translation" matchtranslation = matchtranslation.replaceAll(/<\/?[a-z]+[0-9]* ?\/?>/, '') editor.replaceEditText(matchtranslation); } - Inserting match
/* * #Purpose: Insert tag-free match into current target * #Details: http: // wp.me/p3fHEs-4W * * @author Kos Ivantsov * @date 2013-06-26 * @version 0.1 */ import static javax.swing.JOptionPane.* import static org.omegat.util.Platform.* import org.omegat.core.Core; // abort if a project is not opened yet def prop = project.projectProperties if (!prop) { final def title = 'Insert Match (no tags)' final def msg = 'Please try again after you open a project.' showMessageDialog null, msg, title, INFORMATION_MESSAGE return } def match = Core.getMatcher() def near = match.getActiveMatch() if (near != null) { def matchtranslation = "$near.translation" matchtranslation = matchtranslation.replaceAll(/<\/?[a-z]+[0-9]* ?\/?>/, '') editor.insertText(matchtranslation) } - Replacing target with source
/* * #Purpose: Replace current target with tag-free source * #Details: http: // wp.me/p3fHEs-4W * * @author Kos Ivantsov * @date 2013-06-26 * @version 0.1 */ import static javax.swing.JOptionPane.* import static org.omegat.util.Platform.* // abort if a project is not opened yet def prop = project.projectProperties if (!prop) { final def title = 'Replace with Source (no tags)' final def msg = 'Please try again after you open a project.' showMessageDialog null, msg, title, INFORMATION_MESSAGE return } def stext = editor.currentEntry.getSrcText().replaceAll(/<\/?[a-z]+[0-9]* ?\/?>/, '') editor.replaceEditText(stext) - Inserting source
/* * #Purpose: Insert tag-free source into current target * #Details: http: // wp.me/p3fHEs-4W * * @author Kos Ivantsov * @date 2013-06-26 * @version 0.1 */ import static javax.swing.JOptionPane.* import static org.omegat.util.Platform.* // abort if a project is not opened yet def prop = project.projectProperties if (!prop) { final def title = 'Insert source (no tags)' final def msg = 'Please try again after you open a project.' showMessageDialog null, msg, title, INFORMATION_MESSAGE return } def stext = editor.currentEntry.getSrcText().replaceAll(/<\/?[a-z]+[0-9]* ?\/?>/, '') editor.insertText(stext) - Stripping tags in target
/* * #Purpose: Remove tags in the current target * #Details: http: // wp.me/p3fHEs-4W * * @author Kos Ivantsov * @date 2013-06-26 * @version 0.1 */ import static javax.swing.JOptionPane.* import static org.omegat.util.Platform.* // abort if a project is not opened yet def prop = project.projectProperties if (!prop) { final def title = 'Strip tags in current segment' final def msg = 'Please try again after you open a project.' showMessageDialog null, msg, title, INFORMATION_MESSAGE return } target = editor.getCurrentTranslation() if (target != null) { target = target.replaceAll(/<\/?[a-z]+[0-9]* ?\/?>/, '') } editor.replaceEditText(target)
There are plenty of other ways to remove tags in OmegaT, some of them even posted as my recipes, but the beauty of using groovy is that scripts can be run from withing OmegaT, with its own keyboard shortcut, without needing to assign an OS shortcut to an external script/application.
As usual, inspiration for the scripts was an idea shared at OmegaT Yahoo! Group
Good luck!
Writing Auxilary Text Files from OmegaT
Update: Please, download scripts from the dedicated SF.net project page where they are maintained. Scripts at the links below might be obsolete (though most likely still working).
Here I’d like to share two Groovy scripts that don’t help with anything at hand in OmegaT, but write out external text files that can often be helpful in producing better quality translation.
The first script writes selected text to a file along with some context information. This can be helpful if you need to produce a list of unknown/unclear term that need to be discussed with the client, or things to be double-checked, studied, rewritten etc.
- write_selection2list.groovy
/* * #Purpose: Write selection to a file to create a list of terms * #Files: Writes 'terms_list.txt' in the current project's root * the file contains selection text, segment number, segment text * and filename of the selection, if selection is in the current segment, * or just the text of selection and the filename, if selection * is outside the current segment. * #Note: When invoked without selection, it opens the file * in the default text editor * #Details: http : / / wp.me/p3fHEs-4L * * @author Kos Ivantsov * @based on scripts by Yu Tang * @date 2013-06-25 * @version 0.2 */ import static javax.swing.JOptionPane.* import static org.omegat.util.Platform.* // abort if a project is not opened yet def prop = project.projectProperties if (!prop) { final def title = 'Selection to List' final def msg = 'Please try again after you open a project.' showMessageDialog null, msg, title, INFORMATION_MESSAGE return } // get segment #, source filename and the whole current segment def srcfile = editor.currentFile def ste = editor.currentEntry cur_text = ste.getSrcText() cur_seg = ste.entryNum() // define list file def folder = prop.projectRoot def fileloc = folder+'/terms_list.txt' list_file = new File(fileloc) // create file if it doesn't exist if (! list_file.exists()) { list_file.write("",'UTF-8') } /* * command to open the file if there's no active selection * if a custom (not OS default) text editor should be used, * it needs to be defined in the next line (edit as needed and uncomment) */ // def textEditor = /path to your editor/ def command switch (osType) { case [OsType.WIN64, OsType.WIN32]: command = "cmd /c start \"\" \"$list_file\"" // default try { command = textEditor instanceof List ? [*textEditor, list_file] : "\"$textEditor\" \"$list_file\"" } catch (ignore) {} break case [OsType.MAC64, OsType.MAC32]: command = ['open', list_file] // default try { command = textEditor instanceof List ? [*textEditor, list_file] : ['open', '-a', textEditor, list_file] } catch (ignore) {} break default: // for Linux or others command = ['xdg-open', list_file] // default try { command = textEditor instanceof List ? [*textEditor, list_file] : [textEditor, list_file] } catch (ignore) {} break } def sel_txt = editor.selectedText if (sel_txt) { list_file.append "${'='*10}\n $sel_txt\n",'UTF-8' if (cur_text =~ sel_txt) { list_file.append "${'-'*5}\n\ filename: $srcfile\n\ segment: $cur_seg\n\ segment text: $cur_text \n\n",'UTF-8' }else{ list_file.append "${'-'*5}\n\ filename: $srcfile\n\ ***Selection outside of current segment***\n",'UTF-8' } console.println "\"$sel_txt\" written to $list_file" } else { console.println "[No selection]" console.println "***Opening the file in text editor***" console.println "Command: $command" command.execute() return // exit }The list is created in the current OmegaT project folder, file is named
terms_list.txt. When the script is invoked with no selection, this file is opened in the default text editor — so that you can easily view or edit the file. When it’s invoked with some text selected in the Editor pane, the selection gets written to the file along with some context info depending on whether selection is inside or outside of the current segment.
I’d like to write wider context, but I don’t know how to get text from previous and next segment without actually going there. Any help is welcome and appreciated, as usual.
The second script writes unique untranslated segments from the complete project into a text file named untranslated.txt. This files is located in the project’s root folder, and is rewritten each time the script is invoked. Such file can be used for a number of purposes, including producing TMX with MT.
- write_untranslated2file.groovy
/* * #Purpose: Write all unique untranslated segments to a file * #Files: Writes 'untranslated.txt' in the current project's root * #Details: http : / / wp.me/p3fHEs-4L * * @author Kos Ivantsov * @based on scripts by Yu Tang * @date 2013-06-25 * @version 0.2 */ import static javax.swing.JOptionPane.* import static org.omegat.util.Platform.* // abort if a project is not opened yet def prop = project.projectProperties if (!prop) { final def title = 'Untranslated to File' final def msg = 'Please try again after you open a project.' showMessageDialog null, msg, title, INFORMATION_MESSAGE return } def folder = prop.projectRoot def fileloc = folder+'/untranslated.txt' writefile = new File(fileloc) writefile.write("", 'UTF-8') def count = 0 project.projectFiles .each { //console.println "\n${it.filePath}" it.entries .findAll {!project.getTranslationInfo(it).isTranslated()} .each {count++; writefile.append "${it.srcText}\n",'UTF-8'} } console.println "\nUntranslated segments found: $count" count = 0 def lines = writefile.readLines() uniqline = lines.unique() writefile.write("",'UTF-8') uniqline.each { writefile.append "$it\n",'UTF8'; } console.println "Unique untranslated segments written to file: $uniqline.size"
If you have ideas how to improve these, feel free to share.
UPDATE:
Here’s another script that writes all source segments to a file
But as of now,
Good luck!