Export #OmegaT Project Notes

Here’s a new script that lets you export OmegaT project notes to a HTML table. It may help you to discuss different translation issues with the client/editor/your spiritual guru or review your own translation if you use notes for yourself.

When the script is invoked, it will create a file named PROJECTNAME_notes.html in /script_output subfolder of the current project root (the subfolder will be created if it doesn’t exist, and PROJECTNAME is the actual name, of course).

Exported notes screenshot

Here’s the listing, and the script title is linked to SF.net where you can download it.

  • write_notes.groovy
     * #Purpose:	Export the project's notes into a HTML table
     * #Files:	Writes 'NAME_notes.html' in the 'script_output' subfolder
     *		of current project's root. Each source file where notes are found
     *		is exported to a separate table that has the name of the file as its
     *		heading, then for each segment with a note there is a row with segment
     *		number, text of the note, source and target text (with text from prev.
     *		and next segments for context).
     * #Details:	http://wp.me/p3fHEs-9N
     * @author:	Kos Ivantsov
     * @date:	2014-03-09
     * @version:	0.2
    def tagbg	= '#E5E4E2'	//tag background in context
    def tagfg	= 'green'	//tag foreground in context
    def contxtfg	= 'darkgray'	//font foreground in context
    def notebg	= 'yellow'	//note background
    def curtagbg	= '#BCC6DD'	//tag background in segment's text
    def curtagfg	= 'green'	//tag foreground in segment's text
    def curtxtbg	= '#BCC6CC'	//font background in segment's text
    def filenmbg	= 'lightgray'	//cell background for filename
    def thbg	= 'gray'	//table heading cells background
    import static javax.swing.JOptionPane.*
    import static org.omegat.util.Platform.*
    import org.omegat.util.StaticUtils
    def prop = project.projectProperties
    if (!prop) {
    	final def title = 'Export project notes'
    	final def msg   = 'Please try again after you open a project.'
    	showMessageDialog null, msg, title, INFORMATION_MESSAGE
    def folder = prop.projectRoot+'script_output/'
    projname = new File(prop.getProjectRoot()).getName()
    table_file = new File(folder + projname + '_notes.html')
    // create folder if it doesn't exist
    if (! (new File (folder)).exists()) {
    	(new File(folder)).mkdir()
    count = 0
    def painttag = {x, tbg, tfg -> x.replaceAll(/(\&lt\;\/?\s?\w+\s?\/?\d+?\s?\/?\s?\/?\&gt\;)/, /\<sup\>\<font size=\"1\"  style=\"background-color:$tbg\; color:$tfg" \>$1\<\/font\>\<\/sup\>/)}
    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
    <body>\n""", 'UTF-8')
    files = project.projectFiles
    	for (i in 0 ..< files.size())
    		fi = files[i]
      <table border=\"1px\" style=\"margin-bottom:50px\" width=\"100%\">
      <tr align=\"center\"><th style=\"border:1px solid black\" colspan=\"4\" width=\"100%\" bgcolor=$filenmbg><strong>$fi.filePath</strong></th></tr>
    	<th bgcolor=$thbg>Segment</th>
    	<th bgcolor=$thbg>Note</th>
    	<th bgcolor=$thbg>Source</th>
    	<th bgcolor=$thbg>Target</th>
      </tr>\n""", 'UTF-8')
    		for (j in 0 ..< fi.entries.size())
    			ste = fi.entries[j]
    			info = project.getTranslationInfo(ste)
    			seg_num = ste.entryNum()
    			source = ste.getSrcText()
    			target = info ? info.translation : null
    			if (info.hasNote()) {
    				unitnote = "\n        ${StaticUtils.makeValidXML(info.note)}"
    				if (j != 0) {
    					prevsrc = StaticUtils.makeValidXML(fi.entries[j-1].getSrcText())
    					prevsrc = painttag(prevsrc, tagbg, tagfg)
    					prevtrg = project.getTranslationInfo(fi.entries[j-1]) ? project.getTranslationInfo(fi.entries[j-1]).translation : null
    					if (prevtrg == null || prevtrg.size() == 0) {
    						prevtrg = '**N/A**'
    					prevtrg = painttag(StaticUtils.makeValidXML(prevtrg), tagbg, tagfg)
    						prevsrc = '**N/A**'
    						prevtrg = '**N/A**'
    				if (j < fi.entries.size()-1) {
    					nextsrc = StaticUtils.makeValidXML(fi.entries[j+1].getSrcText())
    					nextsrc = painttag(nextsrc, tagbg, tagfg)
    					nexttrg = project.getTranslationInfo(fi.entries[j+1]) ? project.getTranslationInfo(fi.entries[j+1]).translation : null
    					if (nexttrg == null || nexttrg.size() == 0) {
    						nexttrg = '**N/A**'
    					nexttrg = painttag(StaticUtils.makeValidXML(nexttrg), tagbg, tagfg)
    						nextsrc = '**N/A**'
    						nexttrg = '**N/A**'
    				if (target == null) {
    					target = "zzznullzzz"
    				if (target.size() == 0 ) {
    					target = "<EMPTY>"
    				source = StaticUtils.makeValidXML(source)
    				source = painttag(source, curtagbg, tagfg)
    				target = StaticUtils.makeValidXML(target).replaceAll(/zzznullzzz/, /⁠/)
    				target = painttag(target, curtagbg, tagfg)
      <tr><td style=\"border:1px solid black\" width=\"2%\" align=\"center\">$seg_num</td>
      <td style=\"border:1px solid black ; background-color:$notebg\" width=\"48%\">$unitnote</td>
      <td style=\"border:1px solid black\" width=\"25%\"><small><font style=\"color:$contxtfg\">$prevsrc </font></small><font style=\"background-color:$curtxtbg\">$source</font><small><font style=\"color:$contxtfg\"> $nextsrc </font></small></td>
      <td style=\"border:1px solid black\" width=\"25%\"><small><font style=\"color:$contxtfg\">$prevtrg </font></small><font style=\"background-color:$curtxtbg\">$target</font><small><font style=\"color:$contxtfg\"> $nexttrg </font></small></td></tr>""", 'UTF-8')
    		table_file.append("\n  </table>\n", 'UTF-8')
    table_file.append("</body>\n</html>", 'UTF-8')
    String contents = table_file.getText('UTF-8') 
    contents = contents.replaceAll(/\<table border=\"1px\" style=\"margin-bottom:50px\" width=\"100\%\">\s+\<tr align=\"center\">\<th style=\"border:1px solid black\" colspan=\"4\" width=\"100\%\" bgcolor=$filenmbg\>\<strong\>.*\<\/strong\>\<\/th>\<\/tr\>\n\s+\<tr\>\n\t\<th bgcolor=$thbg\>Segment\<\/th\>\n\t\<th bgcolor=$thbg\>Note\<\/th\>\n\t\<th bgcolor=$thbg\>Source\<\/th\>\n\t\<th bgcolor=$thbg\>Target\<\/th\>\n\s+\<\/tr\>\n\s+\<\/table\>/, '')
    table_file.write(contents, 'UTF-8')
    console.println "$count segments written to $table_file"

    As you see in the screenshot, there will be none or more tables that show filename, segment number, text of the note on yellow background, and source and target text of the current segment surrounded by the respective context (if available). Context is colored differently, and the actual text is highlighted. Tags are colored too. HTML output is not CSS-enabled, but you can fairly easy change colors in the script itself. Lines 18-26 is where you can define them.

Comments, complains, requests are always welcome, either here or at SF.net

But as of now,

God, save Ukraine!

9 thoughts on “Export #OmegaT Project Notes

  1. Pingback: (CAT) - Export OmegaT Project Notes | Translato...
  2. Pingback: (CAT) – Export OmegaT Project Notes | Translator’s Recipes | Glossarissimo!
  3. Thank you, this is the exact script I was looking for! And when I thought it couldn’t be any better, I also found and tried your filtered note export script, which is even better and solved a problem that I didn’t even know I had.

  4. Hi Kos,
    it has been a while.
    I am back with a request again 😉
    My question is:
    How can I modify this script (and the “Write Excel Table” script) in order to export also the contents of the “comments” pane from OmegaT?
    I would preferably like to have an Excel Table with e.g. 5 columns:
    Segment-number Source Target Comment Note
    Is there a script that does this already out there? If not, what are the identifiers for the above mentioned fields in order to add them in the scripts I already have?

    Thank you for time and help.

  5. hi Kos,
    Your script is really helpful (to share notes on translations in progress) absent any other way to export notes.
    I was wondering if there would be any way to let the exported html file take into account hard returns in the notes (say, to replace them with ). Right now all text from the notes ignores any hard returns, tabs, etc. Html code doesn’t register. This would make the export more easily readable.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s