How to support this blog?

To support this blog, you can hire me as an OmegaT consultant/trainer, or you can send translation and project management jobs my way.

Search the site:

TextEdit to TMX!!!

April 14 2023: the script has been updated to fasten the array process by using Shane Stanley's Bridgeplus.


I've just adapted my 'Excel to TMX' script so that it works with a number of files opened in TextEdit windows instead.

https://github.com/brandelune/OmegaT-things

Use case:

  • you have contents in a number of languages, and the contents are aligned (i.e. each line is a language variation of the lines at the same position in the other files)
  • you want to use all that in OmegaT, or any other TMX supporting tool
  • so you want to glue all that into a nice and simple TMX
  • but you also don't want to use Excel, because it's too cumbersome, or because the data has quotation marks that Excel interprets as

Solution:

  1. Copy one language content in a file, the other language in another file (in a different window), etc. The documents do not have to be saved or named. Just create new windows as necessary and paste your contents.
  2. Run the script
  3. It will ask you for the language of the contents in the first window, then in the second window, etc.
  4. Use valid TMX language codes there, because the strings you enter will be the ones used in the TMX
  5. The script displays a progression dialog,
    and at the end, boom, the TMX is created on your Desktop with a timely name like this: TextEdit2tmx_20211219T071214Z.tmx

I've run it with ~ 500 segments in 2 windows (2 languages) and it took me about 5 seconds to create the TMX. It does not really seem to matter how many characters there are in the documents. What seems to matter is the number of lines (segments), and windows.

Also, the segmentation is exactly one segment per line. So you just create a TMX from contents that's segmented and you know is aligned.

"OmegaT Code Reading Sessions", Part 4 !

Are you scared of being bored today ?

The "OmegaT Code Reading Sessions" offer an exciting opportunity to spend one hour of your life trying to make sense of OmegaT's Java code…

Today is the 4th session. It will take place somewhere on a Jitsi instance, at 9pm Tokyo Time.

It's nicer (but not required) if:

  • you're interested in OmegaT
  • you're not scared of reading code, even if that does not make any sense to your current self

You still want to join ?

Export your Numbers file to a PDF in the same folder

use AppleScript version "2.4" -- Yosemite (10.10) or later

use scripting additions


property alert_exists : "The PDF already exists. Continue?"

property dialog_yes : "Yes"

property dialog_no : "No"

property export_complete : "The PDF has been exported"


# this script exports a PDF of the frontmost Numbers file

# the Numbers file is saved before export to make sure that it exists

# the PDF file is exported to the same folder as the original file

# if the name of the original is myName.numbers, the PDF name is myName.pdf

# if the PDF already exists it is possible to cancel the export

# once the export is completed, Numbers displays an alert

# and Finder opens the enclosing folder


tell application "Numbers"

# this script exports a PDF of the frontmost Numbers file

set myDocument to (item 1 of (document of windows whose index is 1))

# the file is saved before export to make sure that it exists

save myDocument

set myDocumentName to name of myDocument

set myDocumentPath to file of myDocument as text

end tell


tell application "Finder"

# the PDF file is exported to the same folder as the original file

set myDocumentContainer to (container of file myDocumentPath) as text

end tell


# if the name of the original is myName.numbers, the PDF name is myName.pdf

set myExportedPDF to myDocumentContainer & myDocumentName & ".pdf"


tell application "System Events"

# if the PDF already exists it is possible to cancel the export

if exists file myExportedPDF then

display alert alert_exists as warning buttons {dialog_yes, dialog_no} cancel button dialog_no

end if

end tell


tell application "Numbers"

(close access (open for access (myExportedPDF)))

export myDocument to file myExportedPDF as PDF with properties {image quality:Best}

# once the export is completed, Numbers displays an alert

display alert export_complete

end tell


tell application "Finder"

# and Finder opens the enclosing folder

activate

open myDocumentContainer

end tell


# here again, save this script as an Application, with a funny name

# so that you can easily call with with Spotlight

# I chose "> Numbers PDF"

Building "vanilla" emacs on macOS, with brew, and more...


Table of contents

  1. Free software = build your software yourself
  2. Required dependencies for building emacs on macOS
  3. Extra dependencies that will add features to your emacs
  4. 8 lines of instructions
  5. emacs documentation
  6. To use emacs from the command line
  7. Updating the code requires 2 instructions
  8. Free Software = you can write code and contribute
  9. References

This is Free Software!

Lots of people seem to wonder, "what is the best emacs for macOS"?

Their criteria for "best" being not always clear, the answer I systematically give is: "Clone the repository and build it yourself. This is free software!"

Since I always forget the dependencies and the steps, this page is a memo for myself, and for curious people who want to try themselves.

Note: I am not a programmer. I just follow instructions. There is nothing magic in the 8 instruction lines that follow. Before, or after you've cloned emacs, you can read the INSTALL.REPO file where basically everything I write here is found, along with the README and the INSTALL files where you'll find additional or redundant information. It's basically all there. I am not making this up.

ToC

Required dependencies

The dependencies below are the minimum emacs requires, and you can find them by running ./autogen.sh first and then ./configure yourself before using brew to install them: the two scripts will just choke every time they don't find the required libraries.

What I did to come up with that list is just add dependencies until the scripts ran their course without error.

If this is your first "development" attempt, you will need the XCode command line tools, basically because you'll need gcc and git for the whole process.

brew will prompt you about that during its install process, and even if that does not happen, the first time you run git, for example to clone emacs, macOS will tell you that you need to install them and prompt you with a nice dialog.

The required dependencies are the following:

  • Autoconf
    "Autoconf is an extensible package of M4 macros that produce shell scripts to automatically configure software source code packages."
  • texinfo
    "Texinfo is the official documentation format of the GNU project."
  • GNU Mailutils
    "Mailutils is a swiss army knife of electronic mail handling. It offers a rich set of utilities and daemons for processing e-mail."
  • GnuTLS
    "GnuTLS is a secure communications library implementing the SSL, TLS and DTLS protocols and technologies around them."

ToC

Extra dependencies

I sent the link to this article to the emacs-devel mailing list for verification and Pankaj Jangid was nice enough to tell me about his own experiences and suggested a list of non-required but recommended packages that emacs would notice during the configuration process. Alan Third, the ns-port maintainer, also chimed in to indicate that some of Pankaj proposed libraries were in fact ignored since the image types they correspond to are handled by macOS proper.

The recomended dependencies are the following:

  • librsvg
    "This is librsvg - A small library to render Scalable Vector Graphics (SVG), associated with the GNOME Project."
  • libxpm
    "X11 pixmap library"
  • lcms2
    "Little CMS intends to be a small-footprint color management engine, with special focus on accuracy and performance."
  • jansson
    "Jansson is a C library for encoding, decoding and manipulating JSON data."

If you want to install the above recommended dependencies, you'll need to add a brew install instruction as shown below.

ToC

The instructions

# install brew
# URL: https://brew.sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# install required dependencies
# or jump to "configure, etc." below and install them one by one
brew install autoconf texinfo gnutls mailutils

# install recommended dependencies, but only after you've checked what they do by following the links above...
brew install librsvg libxpm lcms2 jansson

# clone emacs
# URL: https://savannah.gnu.org/projects/emacs
git clone -b master git://git.sv.gnu.org/emacs.git

# configure, build and install emacs
cd emacs
./autogen.sh
./configure
make install

Et voilà! Emacs.app now resides in emacs/nextstep/Emacs.app.

ToC

Documentation

I don't suppose you'd want to install emacs from scratch without knowing how to use it, but if that's the case, and that's totally OK, emacs comes with thousands of pages of manuals that are just a ctrl-h i away.

That shortcut means hit the control key, hold it pressed, hit the h key, release both, and hit the i key. That shortcut calls the info function, which bring up the list of manuals included in emacs.

You can also start a tutorial with ctrl-h t, which means hit the control key, hold it pressed, hit the h key, release both, and hit the t key. That shortcut calls the help-with-tutorial function.

The manuals are online, if you feel more confortable reading in a web browser: GNU Emacs Manuals Online

ToC

A few extra settings

If you need to use emacs from the command line you may need to update your .profile file with aliases like this:

alias emacs='path/to/emacs/nextstep/Emacs.app/Contents/MacOS/Emacs'
alias emacsclient='path/to/emacs/nextstep/Emacs.app/Contents/MacOS/bin/emacsclient'
alias ctags='path/to/emacs/nextstep/Emacs.app/Contents/MacOS/bin/ctags'
alias ebrowse='path/to/emacs/nextstep/Emacs.app/Contents/MacOS/bin/ebrowse'
alias etags='path/to/emacs/nextstep/Emacs.app/Contents/MacOS/bin/etags'

and that's basically it.

ToC

Updating the thing

The first time you build emacs, along with installing all the dependencies, etc. might take some time, maybe a good 30 minutes, maybe more. But then, you end up with a configuration where you just need to update the code once in a while, and make install the thing again to have the latest version running.

Basically, all is needed is to run this:

# inside the cloned emacs directory
# update the code
git pull

# build and install the new version
make install

And the next time to start emacs, you run the lastest master branch code.

ToC

This it Free Software! 2

The whole point of Free Software is that is gives you the tools necessary to understand what is going on, to learn how to do things yourself and to control your environement.

So, yes, emacs is free software, and now you're all set to play with the code and do your own thing, that will eventually lead to first contribute small things, and then bigger and bigger things to emacs proper.

For that, you just need to create your own development branch and code there:

# inside the cloned emacs directory
# update the code, just to have the latest one
git pull

# create your development/test branch, for example "myEmacs"
git checkout -b myEmacs

# open that new branch in Finder
open .

Everything you do there will never impact the master branch from which you have built emacs. You can always git checkout master back to go back to a clean slate (git will eventually ask you to git stash away your modifications before switching to master, so just follow the instructions).

ToC

References

Now, you may want to know a bit more about Emacs Lisp, about git, about how to contribute to emacs, so here are some references:

  • The "Introduction to Programming in Emacs Lisp" is the entry point for Emacs Lisp development. It is available from inside emacs (type ctrl-h i to find the list of manuals available right at your finger tips) and also online:
    An Introduction to Programming in Emacs Lisp
  • git comes with excellent documentation, and a free book too:
    Git Documentation
  • If you want to practice your Emacs Lisp skills, the "Exercism" site has a track for you:
    Emacs Lisp on Exercism
  • You will quickly find that you need to have a good Emacs Lisp reference to go further. emacs provides you with an excellent reference for pretty much everything you need to know, here again, just a ctrl-h i away, but it is also online:
    GNU Emacs Lisp Reference Manual
  • If you need general help, there is a help-gnu-emacs list and for development help there is the emacs-devel list, along with a lot of other emacs related lists, hosted on the emacs development site:
    emacs - Mailing Lists
  • And here is a tutorial about the procedure to follow if you want to propose your code for inclusion into emacs, by Colin Woodbury:
    Contributing to Emacs

ToC

Everything you wanted to know about modifying application shortcuts, and more...

Modifying application shortcuts

Or, how to spend two hours on your machine on a Sunday morning, when you could go take a walk instead...

Here I talk about an itch I felt the need to scratch this morning, and about 2 applications: CheatSheet, and customShortcuts, and I put a lot of references at the end, so have fun reading!


You can change shortcuts in System Preferences > Keyboard > Shortcuts > App Shortcuts

Most of the things you'll ever need to do can be done there.

But then, some can't.

This morning, I realized that in Mail.app, moving from Delete (Cmd+Del) to Mark as Read (Shift+Cmd+U) when I read and sort my mail, was not what I wanted.

When I read my mail, there are obvious deletes, but a lot of my casual mail can just be not read (discussion lists, where only a few threads are interesting), or specifically marked for later reference. But moving from Cmd+Del to Shift+Cmd+U involves a lot of friction and I want to get rid of that.

I want to have something like:

  • Cmd+Del = Mark as Read (or Mark as Unread, depending on context)
  • Shift+Cmd+Del = Delete
    and since that one is taken by "Erase Deleted Items > In All Accounts...", which I never use, I'd move that item to
  • Alt+Shift+Cmd+Del = Erase Deleted Items > In All Accounts...

That way, I have my morning "mail discussion parsing" workflow all centered on Del, which is a Good Thing™.

The problem is that the System Preference panel has its ideas on what can and cannot be done, and won't allow us to assign Cmd+Del to anything but Delete...

I know there are solutions that give you access to key bindings data, things that are really interesting and let you dive into the intricacies of the OS, but I was not really in that mood this morning (I put all the references at the bottom, there is plenty to read and play with, when you have time).

I remembered that there was an app that gives you all the shortcuts available in any given app (at least apps that live into the macOS GUI system, i.e. basically anything that has a real macOS menu at the top of the window, including Java apps like OmegaT, Electron apps like TMXEditor, etc.), the app is "CheatSheet" and can be found here:

https://www.mediaatelier.com/CheatSheet/

Just out of renewed curiosity, I decided to take a peek, just in case...

And there, behold! There is a link to that companion app: "CustomShortcuts" that (also) "works hand in hand with CheatSheet" by allowing you to edit shortcuts directly in the CheatSheet interface, which is pretty neat...

https://www.houdah.com/customShortcuts/

After a quick download and a few authorizations, I can now do what I wanted to do (assign Cmd+Del to Mark as Read, etc.), plus customShortcuts has autocompletion of menu item names, so you don't have to actually check the target application interface and worry about whether "..." is three dots, or an ellipsis… (← this thing).

Et voilà, I've got my workflow fixed now, I can spend the rest of my Sunday with my heart at ease, and here are the references I promised:


References

Post scriptum

You may want to give CheatSheet a "longish" delay before appearing when you hit Cmd, because it gets tiring real quick to have it pop up while you think about the shortcut you actually want to hit while holding Cmd, which really happens all the time...

In 2009, I had put together a similar thing on how to play with keybindings in the shell. It is here:
Bash (command line) shortcuts

Finder selected files, or a scratchpad, in Emacs

# This script a huge improvement on my original script that appeared here
# about 3 years ago: Open a file in your editor of choice.

# This script is a way to either
#   • open in Emacs the files selected in Finder
#    or
#   • open a scratchpad in Emacs when you need to jot down information.

# The script can be adapted to work with any text editor.

# It tests whether Finder was front when the script was launched *and*
# whether it had selected files.
# If either is negative, it opens a scratchpad with a name that's set here.
# Otherwise is opens the files selected in Finder.

# Personal settings:
# Obviously, your Emacs.app file is located in a different place:
set myEmacsAppPath to "/Users/******/Documents/Repositories/emacs/nextstep/"
# This is the name of the empty default Emacs buffer you want to open:
set myScratchBufferName to "turlututu"

# This part is unlikely to change, it assumes that you use the emacsclient
# that corresponds to the selected Emacs.app. And that you run Emacs as a server.
set myEmacsclient to myEmacsAppPath & "Emacs.app/Contents/MacOS/bin/emacsclient"
set myEmacsApp to myEmacsAppPath & "Emacs.app"

# saved by: https://forum.latenightsw.com/t/how-an-applescript-applet-can-get-the-frontmost-application-other-than-itself/2482/7
# This makes sure that this script is not mistaken for the frontmost application.
# The delay works at 0.2 on my machine, 0.1 is not enough.

tell application "System Events"
    tell (first application process whose frontmost is true)
        set frontmost to false
        set visible of it to false
        delay 0.2
    end tell
    set previously_active_app to item 1 of (get name of processes whose frontmost is true and visible is true)
end tell

# Now that we know whether Finder was previously front or not, we can put Emacs to the front.

try
    tell application "System Events" to tell process "Emacs" to set frontmost to true
on error
    tell application myEmacsApp
        activate
        delay 1
    end tell
end try

# The script's main logic is here.

if previously_active_app is "Finder" then
    # If Finder is the active application when the script is launched, either there is
    # or there is no selection.
    try
        # This is the weird part. There are cases when there is no selection but the assignment
        # is not considered an error, hence I test whether item 1 of the selection exists.
        tell application "Finder" to set fileSelection to its selection
        item 1 of fileSelection exists
    on error
        # If item 1 of selection does not exist, there is no selection and the error branches out here.
        # A scratchpad is opened in Emacs.
        set myCommand to myEmacsclient & " -n -e \"(switch-to-buffer \\\"" & myScratchBufferName & "\\\")\""
        do shell script myCommand
        return
    end try
    # Now that we have checked for that non-selection error, we can work on the selection.
    repeat with selectedFile in fileSelection
        set selectedFile to (POSIX path of (selectedFile as alias))
        set myCommand to myEmacsclient & " -n -e \"(find-file " & "\\\"" & selectedFile & "\\\"" & ")\""
        do shell script myCommand
    end repeat
    return
else
    # And if Finder was not frontmost when the script was launched, then we just intended to
    # open a scratchpad in Emacs.
    set myCommand to myEmacsclient & " -n -e \"(switch-to-buffer \\\"" & myScratchBufferName & "\\\")\""
    do shell script myCommand
    return
end if

# Et voilà.
# Now, save the script in the format that corresponds to the way you usually launch scripts.
# I prefer the "myAppScript.app" way so that I can launch my script by calling it from Spotlight.
# I call this one ">Emacs.app".

emacs regex with emacs lisp

June 28 update: using \#1 instead of (string-to-number \1)

A reader on reddit mentionned that the manual also had the "\#d" construct to replace the often used (string-to-number \d) function.

That regex-replace improvement was mentionned in Stevve Yegge's emacs 22 introduction, back in 2006.

Last but not least, I noticed that the whole post was originally written with (string-as-number ...) when the correct function name is (string-to-number ...)


Not strictly related to translation but here is what's happening...

I've resumed studies last year, trying to finish an MA in Japan Studies I started 25 years ago.

For the first year, I only have to write a 30ish pages dissertation on my subject (representation of women in kendo magazines in Japan) and I decided to go the emacs + org-mode way, with the easy export to ODF function that's packaged with the thing.

So I decided to write each chapter in a different org file, and send them one by one to my director. But then, for the final delivery I needed to put all that in one big file and was faced with the fact that all my footnotes would need to be re-indexed manually because each file had notes starting at 1...

I usually use BBedit for any serious regex work. Mostly because the interface is clearer than emacs, and the regexp feels more modern (\d vs [:digit:])

But one thing you can't do in BBEdit is to send commands to the replace string. For ex, in my case, add 21 to the matching number, which seems pretty trivial, when you think of it, but doing that will involve other technologies, like using perl or some other command line thing.

In emacs, however, everything can be interpreted as an expression, hence you can insert code wherever you want and get the result from that code right in the document.

The org-mode footnotes all look like [fn:12], where "12" is the note number that I need to replace with an incremented number. Since there are no instances of fn:\d+ without the brackets that are not footnotes, I figured I could just be searching for that string:

fn:\([:digit:]+\)

Notice that in emacs, "(" and ")" need to be escaped, also I could have used the [0-9] class.

In BBedit I'd just need:

fn:(\d+)

And now I need to replace that with the expression that will add 21 to the number.

In BBEdit, I'd be stuck here. I just can't add anything to a match. In emacs, I can replace the match with that:

fn:\,(+ 21 (string-to-number \1))

The emacs lisp expression is "(+ 21 (string-to-number \1))", which means "convert the \1 match that is a string into its numerical value and add 21 to it".

But, wasn't \1 supposed to match [0-9]+, which is a number? Well, yes, but really it's just digits, hence strings, that have no numerical value whatsoever, so first, we need the expression to convert them to a numerical value before adding 21 to them.

Now, the trick is to have the expression be handled as an operation and not as an arbitrary string, and that's where the "\," prefix comes into play.

"\," tells the replace engine that the string that follows must be interpreted as an emacs lisp expression and not as a mere string. With it, the regexp replaces properly adds 21 to my note numbers, and I get two dozen footnotes updated in one fell swoop...

I love BBEdit and its people, but emacs is really a gift that keeps on giving.


Here are some handy references:

the emacs regexp-replace function
Regexp Replacement
the emacs regexp syntax
Syntax of Regular Expressions
the emacs-lisp string-to-number function
Conversion of Characters and Strings

And here is a really super short introduction to lisp syntax

There is no real need to have a very deep understanding of emacs lisp to use this regexp-replace function. Just remember that a lisp expression generally looks like this:

(operator operands)

Where the operator is a generally a function, like + or string-to-number above, and the operands can be any expression that is accepted by the operator. So, here:

(+ 21 (string-to-number \1))

means:

add 21 to the result of the expression (string-to-number \1)

with (string-to-number \1) meaning:

convert the string matched by \1 to its numeric value

Obviously, if \1 is not a string, the conversion will fail and the addition won't work. And without that conversion, if we had just added \1 as a string, the addition that expects numbers as operands would have failed.

I just realized that this is my first emacs lisp related post ever ! I'd like to thank that person I met in Tokyo about 15 years ago who showed me the way. It's an egg that definitely took some time to hatch...

Maxprograms is back, take 2.

Free software by a world class XLIFF expert

I first wrote about Maxprograms in 2007. That was after Rodolfo M. Raya left Heartsome to pursue his activity as the Maxprograms software company. I’ve been meaning to write about his work for a long time now, especially since he decided to put all his products on Github, thus allowing translators to get the code, build the things, get the updates and run them on their side, for free.

Maxprograms also offers a lot of technical articles on the subjects of DITA, XLIFF and XML in localization. Check the page here if you are interested.

Rodolfo M. Raya is an editor of the XLIFF 2.0 specification and is a member of the OASIS XLIFF technical committee. He is also co-author of A Practical Guide to XLIFF 2.0.

April 15, 2023 update: Rodolfo has updated the build requirements.

  • JDK 17 or newer is required for compiling and building
  • Apache Ant 1.10.12 or newer
  • Node.js 18.15.0 LTS or newer
  • TypeScript 5.0.0 or newer
I've updated the version numbers below. Make sure you check the various requirements on the respective repository pages.

July 4, 2021 update: all of Maxprograms products are now available under an OSI approved Open Source license

Most of Maxprograms' products come with an easy-to-use installer and only the packages listed in italics below do not, because in their case an installer is not relevant.

If you check the repository list at https://github.com/rmraya?tab=repositories you will see the following software packages (among others). I added the product page on Maxprograms' site (the "..." links) to make it easier for you to find extra information:

  • Eclipse Public License 1.0 (OSI approved)
    • Fluenta (DITA translation manager) ...
    • Swordfish (standards based XLIFF CAT, supports Trados Studio packages) ...
    • TMXEditor (TMX editor, as the name suggests) ...
    • Stingray (document aligner) ...
    • XLIFFManager (GUI for OpenXLIFF) ...
    • OpenXLIFF (command line utility to create, merge, validate XLIFF files) ...
    • TMXValidator (validator/cleaner for TMX files) ...
    • TMEngine (translation memory engine) ...
    • SRXEditor (SRX editor) ...
    • MVDServer (simple web server) ...
    • XLIFFValidation (web-based XLIFF validation tool) ...
    • RemoteTM (remote TM server) ...
  • MIT (FSF and OSI approved)
    • Conversa (DITA publisher) ...
    • KeysAnalyzer (DITA keys analyzer) ...

A "normal" freelance translator would use Swordfish as an XLIFF translation editor/project manager. With eventually TMXEditor to work on client TMX, Stingray to align file sets, and TMXValidator to check and clean TMX files.

More advanced users, or PMs would use XLIFFManager or OpenXLIFF, along with XLIFFValidation and SRXEditor.

DITA specialists would use Fluenta, Conversa and KeyzAnalyzers.

Users who want to self-host services would use XLIFFValidation, MVDServer, RemoteTM.

Maxprograms' packages offer pretty much anything a translator would need, in very cleanly packaged solutions, with excellent user support, either community-based (on groups.io), or directly from Maxprograms if you are a subscriber.

And if your main translation editor in not Swordfish, you can still benefit from all the other packages depending on your needs.

DIY software

Fluenta, Swordfish, TMXEditor and Stingray are subscription-based, but allow translators to run the software for free from the source code (RemoteTM is proposed as a "software as a service" hosted by Maxprograms, but you can host it on your own server if you want).

What that means is that the packaged installer comes as a subscription, but if you don’t mind using Terminal to run your software, which is, let’s be honest, not much of a hurdle, you can use the software, access its updates, eventually make modifications for your own use, etc. for free.

The requirements to download, build and run the software are all given on each product’s Github repository, but here is the gist:

Ant, Node.js and Typescript are also available from Homebrew (https://brew.sh).

To build the software you’ll need to checkout (clone) the repositories. You also need to make sure that Ant uses Java 17 to build the package.

Rodolfo gives all the steps for building (for ex. Stingray):

    $ git clone https://github.com/rmraya/Stingray.git
    $ cd Stingray
    $ ant
    $ npm install
    $ npm start

Java ?

Maxprograms' applications used to be multiplatform Java only applications. Now they use a combination of Java and Javascript (even if the names are close, the two languages are totally unrelated) see below for Rodolfo's explanations.

Apple used to ship Java when macOS was young. It was in fact one of its selling points. Apple has stopped distributing Java a long time ago and now suggests that users install Oracle Java. Changes in the Oracle license and the availability of free Java distributions have allowed users to still benefit from Java without having to pay for a commercial user license.

Even after installing Adoptium's JDK, your machine will still prefer to use an older Java version if you have one installed on your machine.

Which means that if you run:

$ echo $JAVA_HOME

in Terminal and it won’t point to Java 17, you won’t be able to build the software.

On my machine, the above command gives

/Library/Java/JavaVirtualMachines/temurin-11.jdk/Contents/Home

A short investigation shows that the newly installed Java 17 is here:

/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/

The way to have ant use Java 17 instead of Java 11 for the build process is simply to give ant the right pointer:

$ export JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/; ant

Once you’re done with the process, you can export your Java_Home back to its original value, just to be on the safe side. You’ll need to point to Java 17 only to build the software after a code update ($ git pull).

Back to the command line

Once you’ve run

$ npm install

you’re free to launch the application any time you want with

$ npm start

That’s it. This procedure works for Swordfish, Stingray, TMXEditor.

You can also create an Applescript that packages the whole process into a nice application that you can use to launch the various packages as you'd launch standard macOS applications.

A simple Applescript to do that could be:

use AppleScript version "2.4" -- Yosemite (10.10) or later use scripting additions set SwordfishPath to "/path/to/Swordfish/local/repository" set myCommand to "cd " & SwordfishPath & "; npm start" tell application "Terminal"'s front window delay 0.1 do script myCommand in its last tab end tell

Electron ?

Maxprograms' applications used to be Java only applications. But Oracle (Java's main caretaker) neglect of GUI libraries led to a not very satisfactory situation for Java GUI application developers. Here is Rodolfo's rationale for his move away from Java-based GUI libraries:

I use HTML + JavaScript + CSS for the UI and Java for core libraries. In essence, my apps are web pages running on a Java server.

NodeJS provides access to Chrome's V8 JavaScript Engine. Electron is a bridge that provides native windowing environment for JavaScript pages displayed on top of Chrome.

JavaScript is a powerful language, but it is dangerously sloppy. Instead of coding directly on JavaScript, I use TypeScript (which is a safer language) and "transpile" my code to JavaScript for deployment.

I have not switched completely to TypeScript because there aren't good XML libraries for JavaScript. All translation standards are defined using XML and Java is still the best option for handling them. The good news is that JLIFF (a JSON-based version of XLIFF) is currently in development.

Why switch to HTML + CSS for the UI if Java is a cross-platform tool?, you may ask. The answer is simple: Java dropped its major UI libraries.

Initially, Java shipped with AWT, a horrible toolkit with poor design and feature lacking. AWT was so bad that two options replaced it: Swing (originally developed by Sun and currently used by OmegaT) and SWT (the one I used in Swordfish, developed by Eclipse Foundation).

Oracle deprecated Swing in Java 8 and replaced it with JavaFX. When Java 9 was released, JavaFX was abandoned and development moved to its own open-source project, away from Oracle.

The Eclipse Foundation, which developed and maintained SWT for years, stopped improving SWT when JavaFX appeared. It did not fully embrace JavaFX and SWT is languishing since then.

With SWT dying, I looked at JavaFX. It tries to mimic HTML + CSS without success. Not good enough. The real alternative: adopt HTML and CSS.

Et voilà!

I'm not even scratching the surface of what Maxprograms has offered to translators since Heartsome disappeared. Each software package deserves a whole article.

Maxprograms' packages are yet another proof that working on macOS as translators, project managers or localization engineers is possible. And we're lucky that most of the multiplatform packages that allow us to work on macOS are backed by very talented people and communities who do their best to keep us from having to change of platform.

Disclaimer: I am not affiliated in any way to Maxprograms. Just so that you know...

Popular, if not outdated, posts...

.docx .NET .pptx .sdf .xlsx AASync accented letters Accessibility Accessibility Inspector Alan Kay alignment Apple AppleScript ApplescriptObjC AppleTrans applications Aquamacs Arabic archive Automator backup bash BBEdit Better Call Saul bug Butler C Calculator Calendar Chinese Cocoa Command line CSV CSVConverter database defaults Devon Dictionary DITA DocBook Dock Doxygen EDICT Emacs emacs lisp ergonomics Excel external disk file formats file system File2XLIFF4j Finder Fink Font français Free software FSF Fun Get A Mac git GNU GPL Guido Van Rossum Heartsome Homebrew HTML IceCat Illustrator InDesign input system ITS iWork Japanese Java Java Properties Viewer Java Web Start json keybindings keyboard Keynote killall launchd LISA lisp locale4j localisation MacPort Mail markdown MARTIF to TBX Converter Maxprograms Mono MS Office NeoOffice Numbers OASIS Ocelot ODF Okapi OLPC OLT OmegaT OnMyCommand oo2po OOXML Open Solaris OpenDocument OpenOffice.org OpenWordFast org-mode OSX Pages PDF PDFPen PlainCalc PO Preview programming python QA Quick Look QuickSilver QuickTime Player Rainbow RAM reggy regular expressions review rsync RTFCleaner Safari Santa Claus scanner Script Debugger Script Editor scripting scripting additions sdf2txt security Services shell shortcuts Skim sleep Smultron Snow Leopard Spaces Spanish spellchecking Spotlight SRX standards StarOffice Stingray Study SubEthaEdit Swordfish System Events System Preferences TBX TBXMaker Terminal text editing TextEdit TextMate TextWrangler The Tool Kit Time Capsule Time Machine tmutil TMX TMX Editor TMXValidator transifex Translate Toolkit translation Transmug troubleshooting TS TTX TXML UI Browser UI scripting Unix VBA vi Virtaal VirtualBox VLC W3C WebKit WHATWG Windows Wine Word WordFast wordpress writing Xcode XLIFF xml XO xslt YAML ZFS Zip