A pseudo translator is a piece of code that "translates" text in an automated manner. For example, it may convert all source text to upper case, inject special characters or make the translation longer or shorter. Such approaches are commonly used by software localization teams during development and testing. They are also useful to simply test Beebox translation workflows without having to resort to real translators or (slower or cost incurring) machine translation.Adding your algorithm is just The Beebox user interface lets users find text segments by a large variety of filter criteria. Built-in filters permit to look for untranslated content, problems with embedded codes, etc:
You can add your own filters to this list. This is done in a few steps:
- Add a class that implements the IBeeboxPseudoTranslator IBeeboxTextFilter interface.
- Code the TranslateIsMatch() method. It receives one segment at a source text time and returns the translated texttrue if the segment passes the filter.
- Compile and install your dll.
The code below is a sample implementation. All interface methods are verbosely commented and should be self-explanatory.
Sample class
The Beebox extension below adds a simple pseudo translator that converts source text to uppercasefilter that yields segments that are not translated: A simple but fundamental quality assurance algorithm.
Code Block |
---|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Wordbee.Beebox.Extensibility; namespace Acme.PseudoTranslationSample { /// <summary> /// This is a sample Beebox extension that adds a simple pseudo translation option to the Beebox. /// If you want to add multiple algorithms, then add multiple classes to your dll and assign them different "ExtensionID"s. /// </summary> [Serializable] public class SamplePseudoTranslatorSampleTextFilter : MarshalByRefObject, IBeeboxPseudoTranslatorIBeeboxTextFilter { /// <summary> /// Keeps extension alive. This code is mandatory or your extension won't work. /// </summary> /// <returns></returns> public override object InitializeLifetimeService() { return null; } /// <summary> /// Gets the globally unique id of this extension. /// </summary> public string ExtensionID { get { return "acme1acme2"; } } /// <summary> /// Gets if the extension is by default enabled. If false, then it must be enabled explicitly in each /// Beebox project from the Beebox Admin UI. /// </summary> public bool EnableByDefault { get { return true; } } /// <summary> /// Gets a name. Displayed in the Beebox extension manager page. /// </summary> public string Name { get { return "Acme QA translatorfilter"; } } /// <summary> /// Gets the title of the algorithm shown in the user interface such as the "Actions" tool where a user can pseudo translate /// selected content. /// </summary> public string UITitle { get { return "Acme translator- Missing translations"; } } /// <summary> /// Gets a description. Displayed in the Beebox extension manager page. /// </summary> public string Description { get { return "Some words on my algorithm..."; } } /// <summary> /// Gets version number. Displayed in the Beebox extension manager page. /// </summary> public string Version { get { return "1.0"; } } /// <summary> /// Gets the author. Displayed in the Beebox extension manager page. /// </summary> public string Author { get { return "Acme Ltd"; } } /// <summary> /// OverrideReturn totrue implementif yourthe machine translation algorithm. /// Return null to not translate the source textsegment passes the filter. Otherwise do return the translationfalse. /// </summary> /// Basically this method is called with each<param name="segment"> /// Segment details with source text., translation and additional properties: /// - Translate "text" and return the result. Source: The original text /// - ReturnTarget: nullThe iftranslated the source text shall(can be leftnull asor is. /// </summary> /// <param name="text">The text to translate</param> "" to indicate no translation yet) /// <param name="sourceLocale">The ISO code of the source language</param> - SourceLocale: The source language code /// <param name="targetLocale">The ISO code of the target language</param> - TargetLocale: The target language code /// <param name="context">Contains additional information on the segment including the project key and the source file containing the text.</param>- Status: The Quality Assurance status: 0 = not set, 1 = QA Ok, 2 = QA Error /// <returns> /// Return the translated text.- Validated: The translation currently is approved or not /// Return- nullLocked: toThe nottranslation changeis thelocked currentfor translation (null will not clearediting by the translation!)user /// </returns> public string Translate(string text, string sourceLocale, string targetLocale, SegmentContext context) { StringBuilder sb = new StringBuilder(text.Length); // This sample shows how to pseudo translate by converting all characters to uppercase. // The code is a bit more complicate than one might imagine... The reason is that the // source text may contain "markup". Think of html tags such as in "Click <a>here</a>". // We do not want markup converted and so we must have some logic to skip markup when transforming text. bool intag = false; foreach (char ch in text) { // Skip any markup. Markup is enclosed between special codes (char)1 and (char)2. if (ch == ExtensionsHelper.TAG_MARKER_CLOSE) { sb.Append(ch); intag = false; continue; } // We have finished markup if (ch == ExtensionsHelper.TAG_MARKER_OPEN) intag = true; // Markup is starting here if (intag) { sb.Append(ch); continue; } // In the middle of markup // Now we transform the character to uppercase sb.Append(char.ToUpper(ch)); } return sb.ToString(); } - File: The file name containing the segment /// - Project: The project key /// - Key: Gets the segment key or the context of the segment. File format dependent: "Heading 1", "Hyperlink", ... /// - SourceNext: The text just before this segment /// - SourcePrevious: The text just after this segment /// </param> /// <returns> /// True: The filter retains the segment /// False: The filter discards the segment /// </returns> public bool IsMatch(Segment segment) { // We want all empty translations! if (string.IsNullOrWhiteSpace(segment.Target)) return true; // Those with content we skip! return false; } } } |