Announcement

Collapse
No announcement yet.

Translating text to other languages

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Translating text to other languages

    I've been asked to investigate how to display the messages from one of our apps in Spanish. I'm not bilingual, so can't put the alternate text into the code. About 95% of all the messages that need to be displayed are processed in a custom message box replacement, so I'm thinking about using Google translate or some such to intercept the text & translate it before displaying it.. Does anyone have any pointers, or code they can share?
    Real programmers use a magnetized needle and a steady hand

  • #2
    Bud, if the number of text items is small, I would be inclined to spend some time using Google translate and save each one as text then simply have a switch in your app to switch between English and Spanish. I am sure it can be done dynamically via Google translate but it would be messy and probably slow.
    hutch at movsd dot com
    The MASM Forum - SLL Modules and PB Libraries

    http://www.masm32.com/board/index.php?board=69.0

    Comment


    • #3
      I certainly wouldn't try to use an online tranlation service in real time!
      You have no way of knowing what sort of text you will get and it may change over time.

      You really need to know exactly what text is going to be displayed,
      • you need to be sure that the message is accurate
      • you need to be sure that it won't change from run to run
      • you need to know the length of the text string to be displayed

      The usual way to do this is to build an array for each language with a Message identifier and the appropriate word(s).
      Then set a flag for the language to use and display the appropriate text from the appropriate array.

      You can do a one-off translation of all the messages using an on-line transalation server - but you arer STRONGLY advised to run the results past a native language speaker before you implement this.

      It's not uncommon to put all the text strings in a DLL or other supplementary file (can be just simple text array and GET), one per language so that you can easily add additional languages in the future.

      Comment


      • #4
        Howdy, Bud!

        the messages from one of our apps
        I'd agree with the folks above. Particularly, if the number of messages is low, creating your own library of translated messages sounds best. Will there be merely hundreds of messages to translate? If only a few hundreds of messages, then your search/conversion routine can be kept very simple.

        I did a similar thing with an app of mine and as Stuart suggested, I hired a native language translator to help. That worked out well because the translations are NOT word-for-word substitutions, so the conversions required some thought and decisions on what fit the best.

        Comment


        • #5
          Bud, here is a simple test using Google Translate.

          IN
          Code:
          good morning sir
          .
          good morning madam
          .
          hello
          .
          Do you want to format this disk
          .
          How can I help you today
          OUT
          Code:
          Buenos días señor
          .
          Buenos días señora
          .
          Hola
          .
          ¿Quieres formatear este disco?
          .
          Cómo puedo ayudarte hoy
          PS: as per Stuart's suggestion, pass any translation past a native Spanish speaker to make sure it sounds OK and makes sense.
          Last edited by Steve Hutchesson; 13 Jan 2022, 10:14 PM. Reason: More typos !
          hutch at movsd dot com
          The MASM Forum - SLL Modules and PB Libraries

          http://www.masm32.com/board/index.php?board=69.0

          Comment


          • #6
            Originally posted by Steve Hutchesson View Post
            Bud, here is a simple test using Google Translate.
            Another online service which is generally rated to be considerable "better' than the other main translators:
            https://www.deepl.com/en/translator

            Comment


            • #7
              Fixed messages, or do they contain variables "filled-in" during run?

              For button tops, labels, list boxes etcetera; for different languages I use DLLs. (can't find my demo right now)

              In main source (very abbreviated)
              Code:
              . . .
              CALL DWORD pItem USING KeyToWord ("HELP") TO ItemName
              CONTROL ADD BUTTON, hDlg, %ID_ExitBtn, ItemName, x, y, xx, yy
              . . .
              In English DLL source
              Code:
              . . .
              FUNCTION KeyToWord alias "KeyToWord" (ItemName as WSTRING) EXPORT AS WSTRING
                . . .
                CASE "ExitBtn"
                  FUNCTION = "Exit"
              In Spanish DLL source
              Code:
              . . .
              FUNCTION KeyToWord alias "KeyToWord" (ItemName as WSTRING) EXPORT AS WSTRING
                . . .
                CASE "ExitBtn"
                 FUNCTION = "Salida"
              The messages can each be in separate functions in the DLLs.

              Cheers,
              ​​​​​​​
              Dale

              Comment


              • #8
                The messages can each be in separate functions in the DLLs.
                Separate functions!!!

                Can you spell "String table?"
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  But perhaps more practical.

                  I've been asked to investigate how to display the messages from one of our apps in Spanish
                  I had to do this for one of my apps for a clcient.. printing invoices and statements.. and which language was used was triggered by a setting in the customer master table.

                  What I did was make all program literals into variables, and provide a lookup table in the form of an "INI" file.

                  Since I do not speak French - the 'other' language in this case, I made it a user responsibility to provide the actual text. Let me see if I can find a sample file..

                  Found 'em.

                  Here is the start of the English Language file

                  Code:
                  ; FILE: English_language_literals_file.INI
                  ; last update: 8/19/08 MCM 
                  [LITERALS]
                  ; this is a sectionless version of this file... requires all keys be unique
                  ; (unless you want some weird results)
                  ' used in [Header]
                  HInvoiceLiteral=Invoice
                  HCreditMemoLiteral=Credit Memo
                  HInvoiceNo=Invoice Number
                  HInvoiceDate=Invoice Date
                  ; note that invoice date iteral is used both at top of page and in header bar
                  HCustomerNo=Customer No.
                  HCustomerPONo=Purchase Order number
                  HCurrency=Currency 
                  HDate=Date
                  HDueDate=Due Date
                  HPage=Page 
                  HSoldTo=Sold To:
                  HShipTo=Ship To:
                  HSalesOrderNo=Sales Order/RMA#
                  HQuestionsContact=Questions/Contact
                  HTermsLiteral=Terms
                  HFOB=FOB
                  hShipVia=Ship Via 
                  
                  ....
                  ... and here is the start of the French Language version..

                  Code:
                  ; FILE: french_language_literals_file.ini
                  ; 07.22.08 change to sectionless version with single [LITERALS] section
                  ; 8/18/08 removed unused sections only, no updates to values
                  [LITERALS]
                  ;[Header] = H
                  ;Company=Leader   OUT OUT OUT 
                  HInvoiceLiteral=Facture
                  HCreditMemoLiteral=French for Credit Memo here
                  HInvoiceNo=Nº de Facture
                  HInvoiceDate=Date de Facture
                  HCustomerNo=Nº de client.
                  HCustomerPONo=Nº du bon de commande du client
                  HCurrency=Unité monétaire
                  HDate=Date
                  HDueDate=Payable le
                  HPage=Page 
                  HSoldTo=Sold To (In French):
                  HShipTo=Ship To (in French):
                  HSalesOrderNo=Nº de Order
                  HQuestionsContact=Questions/Contact
                  HTermsLiteral=le Terms
                  HFOB=Le FOB
                  hShipVia=Le Ship Via 
                  ;[LineItem] = "L"
                  LCustomerPONo=Nº du bon de commande
                  LOrderDate=Date de la commande
                  LSalesOrderno=Nº du bon de commande/autorisation de retour d'article
                  
                  ....
                  The client updated the French... and remains responsible for all literals appearing on his invoice.

                  It's a thought
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    So when I needed a literal, I would look up the value for say, "LCustomerPONo" passing the language code for this particular customer and the item as a parameter.

                    Any pure "text" which appears on the invoice in terms of invoice items was already in the target language since that's how the order-takers entered it.

                    YES it is a lot more work than using inline literals.
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #11
                      Originally posted by Michael Mattias View Post
                      Separate functions!!!
                      Can you spell "String table?"
                      On this occasion, no. Though it is also a way to do the job. Another would be ASM DATA


                      Dale

                      Comment


                      • #12
                        My approach:

                        In controls which have fixed text (ie. buttons, labels, etc.) and which can support ownerdraw, I create the app in english, but add a macro to the text like this:

                        "My Button Text//001"

                        The double slashes mean an index number to a table is indicated. I write the app completely in english, but the ownerdraw code can swap out non-english text based on tables. The ownerdraw engine also removes the macro from the text when displayed, so they don't see the index number macro.


                        I then created a second app which is a Language editor. It has all the english strings in it and their index numbers. The language editor can then allow someone to create secondary languages and store them in a language template file for each language. Now when the main app runs it searches for language templates and loads them into memory and when the user changes language, it simply looks up the strings in the template and swaps them out (and changes font if necessary).




                        Chris Boss
                        Computer Workshop
                        Developer of "EZGUI"
                        http://cwsof.com
                        http://twitter.com/EZGUIProGuy

                        Comment


                        • #13
                          Once you have an app which can support other languages (via templates) and a language editor app, you can then get help from others who know the other languages to help with the translation. It is best to have someone who actually will use the app to help since they will appreciate the meaning of the english phrases and what a could translation would be. Google translate won't cut it since every language has its unique ways to wording things. Some english words have multiple meanings and can't just be translated word for word to another language.

                          By creating an external language editor app, you can easily hire someone if needed to do the translation and all they need to have is the language editor and not your actual app.

                          It is also important to take into consideration the ability to define a macro to either increase or decrease the font size per each string. The reason is that sometimes an english phrase may only be a few words, but in another language it may take twice as many words for the translation.

                          By using external language template files, one can support a number of languages in one app without a lot of extra work in the app itself.

                          Currently the app supports 15 different languages. The plan is to progressively get help to create all the language templates using the language Editor. The app though supports the 15 languages (once all the templates are created) with the correct fonts and so forth.
                          Chris Boss
                          Computer Workshop
                          Developer of "EZGUI"
                          http://cwsof.com
                          http://twitter.com/EZGUIProGuy

                          Comment


                          • #14
                            IMO, if one only plans to support one additional language then hardcoding it may be fine. But if one plans on supporting multiple languages over time, then defining the languages via external templates makes a lot more sense.
                            Chris Boss
                            Computer Workshop
                            Developer of "EZGUI"
                            http://cwsof.com
                            http://twitter.com/EZGUIProGuy

                            Comment


                            • #15
                              Thanks everyone for the feedback. The static text on buttons, labels and so forth is not the challenge (other than the time needed to code the alternate text -- this particular program has 50-odd forms, and much supporting code). Dale hit it on the head in post #7; many of the messages are built dynamically based on what's happening at the moment, with replaceable values along the way. Right now, some employees are typing the messages into Google translate on their phones, so I'm guessing that system is relatively accurate, so i was hoping for a relatively quick hit to "automate" that.
                              Real programmers use a magnetized needle and a steady hand

                              Comment


                              • #16
                                If one only plans to support one additional language then hardcoding it may be fine.
                                For as long as you have been programming, you sure got that wrong.

                                The correct citation is, "As soon as a user tells you there will only be one additional language, better write the program to handle more."

                                And curiously enough, that kind of happened in my referenced example. The client decided to move his United Kingdom branch office to the invoice printing software and they used some slightly different wording and spelling even within the English language (think "color" vs "colour").

                                While those customers' "language codes" were also "English" , the fact the literals were user-maintained on the local branch server made the cultural differences easy to implement.
                                Michael Mattias
                                Tal Systems (retired)
                                Port Washington WI USA
                                [email protected]
                                http://www.talsystems.com

                                Comment


                                • #17
                                  Just to kinda follow up. As a very quick down-n-dirty test, I added a 'translate' button to another program, where the source data may get entered in a language other than english. The button code gets the string from a text box and submits it to Google translate, opening a browser window. Code snippet:

                                  Code:
                                  ' just a snippet for concept
                                  
                                  URL = "https://translate.google.com/?sl=auto&tl=en&text=" + SrcText + "&op=translate"
                                  Replace " " With "%20" In URL
                                  Replace "," With "%2C" In URL
                                  Replace $Dq With "%22" In URL
                                  
                                  ShellExecute 0, "open", URL, $Nul, $Nul, %SW_Show
                                  Preliminary field testing by users say it's working quite well. Yes, the code for converting the text into something that can be part of the URL string is crude, but this was not meant to be the finished product. My search skills so far have not been up to finding any existing code to do said conversion, but it won't be hard to come with something to convert this is a test to this%20is%20a%20test.
                                  Real programmers use a magnetized needle and a steady hand

                                  Comment


                                  • #18
                                    Originally posted by Bud Durland View Post
                                    My search skills so far have not been up to finding any existing code to do said conversion,
                                    You could try the simple function at https://forum.powerbasic.com/forum/u...698#post782698



                                    Juts noticed that the strOK there includes a couple of unwanted spaces. You need to remove them! And the acceptable characters were for a specific use case - strOK may need additional modification depending on your usage.

                                    Comment


                                    • #19
                                      One more way to URL encode/Percent-Encoding including UTF8 conversion

                                      '
                                      Code:
                                      #COMPILE EXE
                                      #DIM ALL
                                      #UNIQUE VAR ON
                                      
                                      FUNCTION PBMAIN () AS LONG
                                       LOCAL myString AS WSTRING
                                      
                                       myString = "My Test text with é ô UTF8"
                                       ? rmURLEncode (myString)
                                      
                                      END FUNCTION
                                      
                                      FUNCTION rmURLEncode (StrConvert AS WSTRING)  AS STRING
                                      '-----------------------------------------------
                                      ' URL encoding also known as Percent-encoding
                                      ' Convert a text Value to UTF8 URL friendly
                                      '
                                      ' Usage     rmURLEncode ("this is, a test")
                                      ' Result    = this%20is%2C%20a%20test%22
                                      '-----------------------------------------------
                                           LOCAL i AS LONG
                                           LOCAL StrUTF8 AS STRING
                                           LOCAL hxp AS BYTE POINTER
                                           LOCAL sb AS ISTRINGBUILDERA
                                           sb = CLASS "StringBuilderA"
                                           StrUTF8 = CHRTOUTF8$(StrConvert)
                                           hxp = STRPTR(StrUTF8)
                                           FOR i=1 TO LEN(StrUTF8)
                                               IF (@hxp > 47 AND @hxp < 58) _                                             ' 0 to 9  these no encoding
                                                  OR (@hxp > 64 AND @hxp < 91) _                                          ' A to Z
                                                  OR (@hxp > 96 AND @hxp < 123) _                                         ' a to z
                                                  OR (@hxp = 45)  OR (@hxp = 46)  OR (@hxp = 95)  OR (@hxp = 126) THEN    ' -_.~
                                                sb.add CHR$(@hxp) '
                                               ELSE
                                                sb.add "%"+ HEX$(@hxp,2) ' <-- only two hex digits
                                               END IF
                                                INCR hxp
                                           NEXT
                                      FUNCTION = sb.string
                                      END FUNCTION  ' rmURLEncode
                                      'The generic URI syntax recommends that new URI schemes that provide for the representation of character
                                      'data in a URI should, in effect, represent characters from the unreserved set without translation, and
                                      'should convert all other characters to bytes according to UTF-8, and then percent-encode those values.
                                      ' RFC 3986 section 2.3 Unreserved Characters
                                      ' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.~
                                      
                                      '

                                      Comment


                                      • #20
                                        As I said, my search skills are lacking (or maybe I should do it AFTER coffee).. Thanks Stuart and Rod..
                                        Real programmers use a magnetized needle and a steady hand

                                        Comment

                                        Working...
                                        X