Search Results for

    Show / Hide Table of Contents

    Processing Inline Formatting

    In this chapter you will learn how to enhance your file type plug-in to properly mark up inline tags and apply character formatting.

    Add New Members to the Parser Class

    For your parser class to identify inline tags embedded within translatable content and apply character display formatting, add the following items:

    First, add the regular expressions namespace to your class because you will use regular expressions to identify tags within translatable strings:

    System.Text.RegularExpressions
    

    Second, add the Sdl.FileTypeSupport.Framework.Formatting namespace. This namespace provides the functionality to apply display character formatting in the editor of Trados Studio.

    To keep this project simple, assume the text file contains only the <b> tag for applying bold character formatting. Add a new formatting member to the global settings of your class:

    • C#
    IPersistentFileConversionProperties _fileConversionProperties;
    StreamReader _reader = null;
    
    FormattingGroup _fBold;
    

    Add the Functionality Required for Processing Formatting

    Modify the ProcessLine() helper function to call a new ProcessFormatting() function through WriteText(). (You will add this helper function in the next step.)

    • C#
    // determines whether a given line is
    // translatable or not
    // if not, a structure tag is output
    // otherwise, the translatable text is exposed
    private void ProcessLine(string sLine)
    {
        if (sLine.StartsWith("[") && sLine.EndsWith("]"))
        {
            WriteStructureTag(sLine);
            WriteContext(sLine);
        }
        else
        {                
            WriteText(ProcessFormatting(sLine));
        }
    }
    

    Now add the function that identifies inline tag content within a translatable line:

    • C#
    // this function uses regular expressions to identify
    // what is 'normal' translatable content and which strings
    // need to be marked up as inline tags, e.g. <b>
    private string ProcessFormatting(string sLine)
    {
        int LastPosition = 0;
        // search for opening and closing <b> tags
        Regex rx = new Regex(@"\<.*?\>", RegexOptions.Compiled);
        MatchCollection rxMatches = rx.Matches(sLine);
    
        foreach (Match rxMatch in rxMatches)
        {
            if (LastPosition != rxMatch.Index)
            {
                WriteText(sLine.Substring(LastPosition, rxMatch.Index - LastPosition));
            }
    
            bool IsOpening = rxMatch.Value.Contains("/") ? false : true;
            WriteInlineTag(rxMatch.Value, IsOpening);  
    
            LastPosition = rxMatch.Index + rxMatch.Length;
        }
        return sLine.Substring(LastPosition, sLine.Length - LastPosition);
    }
    

    This function calls WriteText() to output 'normal' text and WriteInlineTag() to output any inline tags that have been found. Next, add the function that outputs the inline < b> tags. Note that these inline tags always occur in pairs, i.e. there will be an opening and a closing tag. This is why this function takes a boolean isStart parameter. If this function is called with a True value from ProcessFormatting(), a start tag will be created through the properties factory, which is then output to the bilingual file. Otherwise an end tag will be output.

    Note

    Start tags and end tags must be well-formed in the XML sense, i.e. all start tags must match an end tag with the same nesting of paired tags. If not, the File Type Support Framework will throw a fatal exception. When paired tags are processed by the File Type Support Framework and the framework-based editor, this well-formedness is guaranteed to be preserved. This can simplify other tag processing modules such as the native file writer (see Implementing the File Writer).

    Outputting the start tag of a tag pair: The properties factory provides a CreateStartTagProperties method that creates properties for a start tag inside localizable content. The start tag has a corresponding end tag. Pass the tag content to the Create() method as a parameter. Output the start tag property to the API using Output.InlineStartTag().

    Outputting the end tag of a tag pair: The properties factory provides a CreateEndTagProperties method that creates properties for an end tag matching a previously emitted start tag. Pass the tag content to the Create() method as a parameter. Output the end tag property to the API using OutputInlineEndTag().

    This function also creates a formatting object to apply bold display formatting in the editor for the translator's convenience. Use the CanHide property to hide the inline tags by default. Translators see only the formatting, not the actual tags, which is usually more convenient for the translation process.

    • C#
    // this function outputs an opening or a closing <b> tag
    // and applies bold character formatting to the strings
    // that the tags enclose
    private void WriteInlineTag(string tagContent, bool isStart)
    {
        _fBold = new FormattingGroup();
        _fBold.Add(new Bold(true));
    
        if (isStart)
        {
            IStartTagProperties startTag = PropertiesFactory.CreateStartTagProperties(tagContent);
            startTag.DisplayText = "b";
            startTag.TagContent = tagContent;
            startTag.Formatting = _fBold;
            startTag.CanHide = true;
            Output.InlineStartTag(startTag);
        }
        else
        {
            IEndTagProperties endTag = PropertiesFactory.CreateEndTagProperties(tagContent);
            endTag.DisplayText = "b";
            endTag.TagContent = tagContent;
            endTag.CanHide = true;
            Output.InlineEndTag(endTag);
        }
    }
    

    Use the DisplayText property to define the tag text that users see when they enable partial tag text mode. The TagContent property determines the tag text that users see when they enable full tag text view.

    Below, the text displays with proper character formatting:

    OnlyFormatting

    This is the editor view when the user enables inline tags (partial tag text):

    PartialTagText

    This is the editor view when the user enables inline tags (full tag text):

    FullTagText

    Putting It All Together

    The enhanced file parser class should now look as shown below:

    • C#
    using System.Drawing;
    using System.IO;
    using System.Text.RegularExpressions;
    using Sdl.FileTypeSupport.Framework.BilingualApi;
    using Sdl.FileTypeSupport.Framework.Core.Utilities.Formatting;
    using Sdl.FileTypeSupport.Framework.NativeApi;
    using Sdl.FileTypeSupport.Framework.Formatting;
    
    namespace Sdk.Snippets.Native
    {
        public class SimpleTextParser : AbstractNativeFileParser, INativeContentCycleAware
        {
            IPersistentFileConversionProperties _fileConversionProperties;
            StreamReader _reader = null;
    
            FormattingGroup _fBold;
    
            // through the properties object you can retrieve important information
            // on the native input file such as the original file name and path
            public void SetFileProperties(IFileProperties properties)
            {
                _fileConversionProperties = properties.FileConversionProperties;
            }
    
            public void StartOfInput()
            {
    
            }
    
    
            public void EndOfInput()
            {
    
            }
    
            protected override void BeforeParsing()
            {
                // set progress reporter to the beginning
                OnProgress(0);
    
                // open the native input file for reading
                _reader = new StreamReader(_fileConversionProperties.OriginalFilePath);
            }
    
            protected override bool DuringParsing()
            {
                // iterate through all lines in the input file
                while (!_reader.EndOfStream)
                {
                    ProcessLine(_reader.ReadLine());
                }
                return false;
            }
    
            protected override void AfterParsing()
            {
                //close original file
                _reader.Close();
                _reader.Dispose();
                _reader = null;
                //set progres report to 100%
                OnProgress(100);
            }
    
            // determines whether a given line is
            // translatable or not
            // if not, a structure tag is output
            // otherwise, the translatable text is exposed
            private void ProcessLine(string sLine)
            {
                if (sLine.StartsWith("[") && sLine.EndsWith("]"))
                {
                    WriteStructureTag(sLine);
                    WriteContext(sLine);
                }
                else
                {                
                    WriteText(ProcessFormatting(sLine));
                }
            }
    
            // output translatable text
            private void WriteText(string TextContent)
            {
                ITextProperties textProperties = PropertiesFactory.CreateTextProperties(TextContent);
                Output.Text(textProperties);
            }
    
            // output non-translatable text as structure tag
            private void WriteStructureTag(string TagContent)
            {
                IStructureTagProperties structureTagProperties = PropertiesFactory.CreateStructureTagProperties(TagContent);
                structureTagProperties.DisplayText = TagContent;
                Output.StructureTag(structureTagProperties);
            }
    
            // output context information, not required, but useful
            // information for the translator
            private void WriteContext(string ContextContent)
            {
                IContextProperties contextProperties = PropertiesFactory.CreateContextProperties();
                IContextInfo contextInfo = PropertiesFactory.CreateContextInfo(ContextContent);
                contextInfo.DisplayCode = "EL";
                contextInfo.DisplayName = "Element";
                contextInfo.Description = ContextContent;
                contextInfo.DisplayColor = Color.Beige;
                contextProperties.Contexts.Add(contextInfo);
                Output.ChangeContext(contextProperties);
            }
    
            // this function uses regular expressions to identify
            // what is 'normal' translatable content and which strings
            // need to be marked up as inline tags, e.g. <b>
            private string ProcessFormatting(string sLine)
            {
                int LastPosition = 0;
                // search for opening and closing <b> tags
                Regex rx = new Regex(@"\<.*?\>", RegexOptions.Compiled);
                MatchCollection rxMatches = rx.Matches(sLine);
    
                foreach (Match rxMatch in rxMatches)
                {
                    if (LastPosition != rxMatch.Index)
                    {
                        WriteText(sLine.Substring(LastPosition, rxMatch.Index - LastPosition));
                    }
    
                    bool IsOpening = rxMatch.Value.Contains("/") ? false : true;
                    WriteInlineTag(rxMatch.Value, IsOpening);
    
                    LastPosition = rxMatch.Index + rxMatch.Length;
                }
                return sLine.Substring(LastPosition, sLine.Length - LastPosition);
            }
    
            // this function outputs an opening or a closing <b> tag
            // and applies bold character formatting to the strings
            // that the tags enclose
            private void WriteInlineTag(string tagContent, bool isStart)
            {
                _fBold = new FormattingGroup();
                _fBold.Add(new Bold(true));
    
                if (isStart)
                {
                    IStartTagProperties startTag = PropertiesFactory.CreateStartTagProperties(tagContent);
                    startTag.DisplayText = "b";
                    startTag.TagContent = tagContent;
                    startTag.Formatting = _fBold;
                    startTag.CanHide = true;
                    Output.InlineStartTag(startTag);
                }
                else
                {
                    IEndTagProperties endTag = PropertiesFactory.CreateEndTagProperties(tagContent);
                    endTag.DisplayText = "b";
                    endTag.TagContent = tagContent;
                    endTag.CanHide = true;
                    Output.InlineEndTag(endTag);
                }
            }
        }
    }
    

    See Also

    • Implementing the File Parser
    • Processing Placeholder Tags
    • Handling Tags During Segmentation
    • Tag display modes
    Note

    This content may be out-of-date. To check the latest information on this topic, inspect the libraries using the Visual Studio Object Browser.

    • Improve this Doc
    In this article
    Back to top Generated by DocFX