This document in English is to help developpers to internationalise the scrountch
tool: that is
to let people program in their own language.
scrountch
is built on top of Groovy
which is itself built on top of Java
.
Developpers who want to configure scrountch
, so it could accept code in a specific language, should be familiar with internationalisation
ressource handling in Java through .properties
files and should know how to update a jar file.
How are translations operated in scrountch
(A rather technical topic for those familiar with Groovy)
The internationalisation of code happens through 3 steps:
-
The text of the code is scanned for anything that looks like a keyword (or a very common function like
println
). Then these words are searched in a dictionary and if a translation from the current language to english is found then the english word replaces the initial word in the text. This should not be used to rename classes or methods. -
At load-time original class names are aliased with their translation in the current language.
-
At runtime if a method is not found to be associated with a given class (which at runtime has its original name) a translation of this method is searched and then the method name is added to the metaclass.
Most free functions (that are not invoked as members of a class) are supposed to be static methods of the
scrountch.Fab
class (unless these are declared in the current code).
Note
|
Reminder
Properties files have an ISO8859-1 encoding so to write characters that are out of this range you should use the
Here is an example for a chinese word:
Sometimes you may need several unicodes for a single character. Here is an example with an emoji:
|
The properties files
Each of those files is supposed to be part of the scrountch
package and should be named according to
the internationalisation convention used in Java.
For instance if the language is arabic then the internationalisation of
keywords should reside in a file scrountch/keywords_ar.properties
(or with the name_language_country.properties
convention)
Keywords
Keywords and current types and function (such as int
, String
or println
) should reside in the keywords
ressource.
Here is a model:
# modify the needed keywords
#as
#assert
#break
#case
#catch
#class
#const
#continue
#def
#default
#do
#else
#enum
#extends
#false
#finally
#for
#goto
#if
#implements
#import
#in
#instanceof
#interface
#new
#null
#package
#return
#super
#switch
#this
#throw
#throws
#trait
#true
#try
#while
#int
#short
#byte
#char
#double
#float
#boolean
# other non keywords
# String
# println
Since there may be some confusion with identifier you may use a convention for internationalisation of keywords
(underline is used in french except for types or litterals: so int
is translated entier
,
true
is translated VRAI
but while
is translated _tantQue
)
BEWARE : original keywords are still in use! So if you translated int
or while
the code can still
use the english keywords! (which is useful when delegates slowly switch from completely translated to code
to "real" code).
Class names
Class names are translated in the classes
properties files.
You can translate any class name be it java or groovy standard or specific to scrountch
You shoud check the scrountch
code to know which classes you want to translate.
Here is an example of a classes_fr.properties
for french:
scrountch.geom.SFrame = Cadre
scrountch.geom.Cell = Canevas
scrountch.geom.GraphicObject = ObjetGraphique
scrountch.geom.GraphicImage = ImageGraphique
scrountch.geom.GraphicString = ChaineGraphique
scrountch.geom.GraphicShape = FormeGraphique
scrountch.geom.SButton = Bouton
scrountch.geom.Turtle = Tortue
scrountch.geom.IconImage = Icone
scrountch.geom.Radial2D= RadialInfo
#
scrountch.utils.SelectionListener = VeilleurSelection
# import from std libs
java.awt.Shape = Forme
java.awt.Label = Label
java.awt.BasicStroke = TraitSimple
java.awt.Polygon = Polygone
java.awt.Rectangle = Rectangle
java.awt.event.MouseListener = VeilleurSouris
java.awt.event.ActionListener = VeilleurAction
# import from java.awt.geom
# this one is necessary if translation of Shape needed
java.awt.geom.RectangularShape=FormeRectangulaire
# BEWARE OF INNER CLASSES!!!
java.awt.geom.Ellipse2D$Double = EllipseD
java.awt.geom.Ellipse2D = Ellipse2d
java.awt.geom.Line2D$Double = LigneD
java.awt.geom.Point2D$Double = PointD
java.awt.geom.Path2D$Double = Cheminement
java.awt.geom.Rectangle2D$Double = RectangleD
java.awt.geom.RoundRectangle2D$Double = RectangleArrondiD
java.awt.geom.Area = java.awt.geom.Area
#import from Groovy
groovy.lang.Closure = Fermeture
Many more classes should be added to the list!
Method names
The translation are described in the methods
properties file.
Remember how methods are searched: the execution starts from the "real" name of the class, so the description is strange since we need to describe a translated method name to an original class name!
Here is an example from the methods_fr.properties
:
note that the properties entry is of the form originalClassName#translatedMethodName=originalMethodName
# Factories
# basic static functions from the default Fab code
Fab#créerPolygone=createPolygon
Fab#créerRectangle=createRectangle
Fab#créerEllipse=createEllipse
Fab#créerLigne=createLine
Fab#créerTrait =createStroke
Fab#créerTortue =createTurtle
Fab#iconeDepuisFichier=createIconImageFromFile
Fab#iconeDepuisURL=createIconImageFromURL
# Graphic objects
Fab#créerFormeGraphique=createGraphicShape
Fab#formeGraphiqueCentrée=centeredGraphicShape
Fab#créerImageGraphique=createGraphicImage
Fab#créerChaineGraphique=createGraphicString
Fab#imageDepuisFichier=createGraphicImageFromFile
Fab#imageDepuisURL=createGraphicImageFromURL
Fab#créerPolygoneGraphique= createGraphicPolygon
Fab#créerRectangleGraphique= createGraphicRectangle
Fab#créerEllipseGraphique= createGraphicEllipse
Fab#créerLigneGraphique= createGraphicLine
Fab#courbe= createLineCurve
Fab#courbeParPoints= createDotCurve
Fab#histogramme= createSimpleHistogram
Fab#axes= axles
Fab#axesGradués= axlesTicks
Fab#compiler=compileFiles
Fab#garder=keep
Fab#recentrer=forceCenter
Fab#activerTraces=enableTraces
Fab#nombreAuHasard=randomInt
# awt
Fab#créerCadre=createFrame
Fab#créerBouton=createButton
Fab#créerLabel=createLabel
# SFrame methods
SFrame#canevas=getCell
SFrame#tousLesCanevas=cells
SFrame#ajouterAuNord=addNorth
SFrame#retirerDuNord=removeNorth
SFrame#ajouterAuSud=addSouth
SFrame#retirerDuSud=removeSouth
SFrame#siClicSurTous=allOnClick
# Cell methods
Cell#listeGraphiques=getList
Cell#ajoutGraphique=addToGraphics
Cell#ajoutListeGraphiques=addAll
Cell#effacerGraphique=removeFromGraphics
Cell#effacerTout=clearGraphics
Cell#ajout=addNoRepaint
Cell#enlever=remove
Cell#enleverTout=clear
Cell#siClic=onClick
Cell#retirerVeilleurSouris=removeMouseListener
Cell#siSelection=onSelection
Cell#retirerVeilleurSelection=removeSelectionListener
Cell#repeindre=forceRepaint
Cell#ligne= getLinePos
Cell#colonne= getColPos
Cell#arrièrePlan=setBackground
Cell#couleurTracé=setForeground
#SButton methods
SButton#référence=getRef
SButton#siClic=onClick
SButton#retirerVeilleurSouris=removeMouseListener
# GraphicObject methods
GraphicObject#déplacerDe=moveAlong
GraphicObject#changerDirection=changeDirection
GraphicObject#rotationCentrée= centerRotation
#GraphicImage
#GraphicImage#rallonger=lenghtenPath
GraphicImage#hauteurInitiale = getOriginalHeight
GraphicImage#largeurInitiale = getOriginalWidth
GraphicImage#changerEchelle = setScale
GraphicImage#retour = home
GraphicImage#rotationCentrée= centerRotation
GraphicImage#rotationCoin= cornerRotation
GraphicImage#annulerRotations= clearRotation
#GraphicString methods
GraphicString#retour = home
GraphicString#rotationCentrée= centerRotation
GraphicString#rotationCoin= cornerRotation
GraphicString#couleurTracé= setDrawPaint
GraphicString#changerPolice= setFont
#GraphicShape methods
GraphicShape#hauteurInitiale = getOriginalHeight
GraphicShape#largeurInitiale = getOriginalWidth
GraphicShape#changerTrait=setStroke
GraphicShape#couleurTracé=setDrawPaint
GraphicShape#remplissage=setFillPaint
GraphicShape#retour = home
GraphicShape#rotationCentrée= centerRotation
GraphicShape#rotationCoin= cornerRotation
# Turtle methods
Turtle#avance=forward
Turtle#sauteEn=jumpTo
Turtle#tourneDroite=turnRight
Turtle#tourneGauche=turnLeft
Turtle#pointCourant=getCurrentPoint
#IconImage methods
IconImage#hauteur=getIconHeight
IconImage#largeur=getIconWidth
# graphics
Shape#enveloppe=getBounds
Shape#hauteur=getHeight
Shape#largeur=getWidth
Shape#plusGrandeDim=maxDim
Rectangle#hauteur=getHeight
Rectangle#largeur=getWidth
# BEWARE OF INNER CLASSES NAMES
Rectangle2D$Double#hauteur=getHeight
Rectangle2D$Double#largeur=getWidth
#Ellipse2D$Double#enveloppe=getBounds
Ellipse2D$Double#hauteur=getHeight
Ellipse2D$Double#largeur=getWidth
java.awt.geom.Area#contient=contains
Radial2D#rayon=getRadius
Note: you can use the simple name of the class or, if ambiguous, the canonical name.
Messages
Though not yet widely used (yet) there is room for message translations in the messages
properties file:
A limited list of messages to be translated:
save_changes_to=Save changes to
Interrupt_question=Script executing. Press 'OK' to attempt to interrupt it before exiting.
Updates
Once your properties files is created you can update the scrountchConsole.jar
file (with -u
option).
You can test also by invoking java with a specific option such as java -Duser.language=xx -jar scrountchConsole.jar
(xx
being the code for your language)