Terminology Provider Develop Problem

I am developing cloud terminology, but I ran into a problem in search function. The "Term Recognition" and "Term Search" use the same sdk funtion as below



public override IList<ISearchResult> Search(string text, ILanguage source, ILanguage destination, int maxResultsCount, SearchMode mode, bool targetRequired)

 

The Term Search user SearchMode normal can get the right result, but Term Recongition which use SearchMode fuzzy could not

I debug into the search function, and I found the search function did get the right data from our server, but Term Recongnition could not display the right info in Trados UI.

I don't know how to sovle this problem, please help me.

 

 

here is MyTerminologyProvider source code:

using Sdl.Terminology.TerminologyProvider.Core;
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;

namespace TmxmallTermPlugin
{
    public class MyTerminologyProvider : AbstractTerminologyProvider
    {
        public const string ProviderScheme = "tmxmalltermprovider";

        private List<IEntry> _entry = new List<IEntry>();

        public TmxmallTermOptions Options { get; set; }

        private TerminologyClient _terminologyClient;

        public string SrcLanguage = "zh";

        public string TgtLanguage = "en";

        //Sets the terminology provider settings, i.e. in our implementation the glossary file name
        public MyTerminologyProvider(TmxmallTermOptions options)
        {
            this.Options = options;
            _terminologyClient = new TerminologyClient(options);
        }

        public override IDefinition Definition
        {
            get
            {
                return new Definition(GetDescriptiveFields(), GetLanguages().Cast<IDefinitionLanguage>().ToList());

            }
        }

        public override string Description
        {
            get
            {
                return PluginResources.Plugin_Description;
            }
        }

        public override string Name
        {
            get
            {
                return PluginResources.Plugin_Name;
            }
        }

        public override Uri Uri
        {
            get
            {
                return this.Options.Uri;

            }
        }

        public override IEntry GetEntry(int id)
        {
            return _entry.FirstOrDefault(_entry => _entry.Id == id);

        }

        public override IEntry GetEntry(int id, IEnumerable<ILanguage> languages)
        {
            return _entry.FirstOrDefault(_entry => _entry.Id == id);
        }

        public override IList<ILanguage> GetLanguages()
        {
            var result = new List<IDefinitionLanguage>();
            string[] languages = "English,en;Chinese,zh;Korean,ko;Japanese,ja;French,fr;Germany,de;Russian,ru;Spanish,es;Arabic,ar;Portuguese,pt".Split(';');
            for (int i = 0; i < languages.Length; i++)
            {
                string languageLabel = languages[i].Split(',')[0], languageLocale = languages[i].Split(',')[1];

                var tbLanguage = new DefinitionLanguage
                {
                    Name = languageLabel,
                    Locale = new System.Globalization.CultureInfo(languageLocale)
                };

                result.Add(tbLanguage);
            }
            

            return result.Cast<ILanguage>().ToList();

        }

        public void UpdateOptions(TmxmallTermOptions options)
        {
            Options = options;
        }

        public override IList<ISearchResult> Search(string text, ILanguage source, ILanguage destination, int maxResultsCount, SearchMode mode, bool targetRequired)
        {
            string[] chunks;
            var results = new List<ISearchResult>();
            if (source.Locale.ToString().Equals(destination.Locale.ToString()))
            {
                return results;
            }
            List<string> hits = this._terminologyClient.Search(text, source.Locale.ToString(), destination.Locale.ToString());
            // Create search results object (hitlist)
            _entry.Clear();
            for (int i = 0; i < hits.Count; i++)
            {
                chunks = System.Text.RegularExpressions.Regex.Split(hits[i], this.Options.TermSpliter);
                // We create the search result object based on the source term
                // found in the glossary, we assign the id, which associates the search
                // result to the correspoinding entry, and we assume that the search score 
                // is always 100%.
                SearchResult result = new SearchResult
                {
                    Text = chunks[0] + "    [" + chunks[2] + "]", // source term
                    Score = 100,
                    Language = source,
                    Id = Convert.ToInt32(i.ToString()) // entry id
                };

                // Construct the entry object for the current search result
                _entry.Add(CreateEntry(i.ToString(), chunks[0], chunks[1], chunks[2], destination.Name));

                results.Add(result);
            }
            this.SetDefault(true);
            return results;
        }

        // Creates the termbase definition by declaring the Definition text field.
        // This allows our terminology provider to also display the Definition field content
        // in the Termbase Search and Terminology Recognition windows.
        public IList<IDescriptiveField> GetDescriptiveFields()
        {
            var result = new List<IDescriptiveField>();

            var definitionField = new DescriptiveField
            {
                Label = "Definition",
                Level = FieldLevel.EntryLevel,
                Type = FieldType.String
            };
            result.Add(definitionField);

            return result;
        }

        // This helper function is used to construct the entry content with entry id, source and target term, and
        // definition (if applicable)
        private IEntry CreateEntry(string id, string sourceTerm, string targetTerm, string definitionText, string targetLanguage)
        {
            // Assign the entry id
            IEntry thisEntry = new Entry
            {
                Id = Convert.ToInt32(id)
            };

            // Add the target language
            IEntryLanguage trgLanguage = new EntryLanguage
            {
                Name = targetLanguage
            };

            // Create the target term
            IEntryTerm _term = new EntryTerm
            {
                Value = targetTerm
            };
            trgLanguage.Terms.Add(_term);
            thisEntry.Languages.Add(trgLanguage);

            // Also add the definition (if available)
            if (definitionText != "")
            {
                IEntryField _definition = new EntryField
                {
                    Name = "Definition",
                    Value = definitionText
                };
                thisEntry.Fields.Add(_definition);
            }

            return thisEntry;
        }
    }
}

Parents
  • I finally managed to get a look at your code and run a test.

    The problem is the way you create the SearchResult Text propriety. This has to be only the source term because this needs to be identified in the segment. You're adding other information and because of that the term matching in Trados Studio is not able to find the term inside the source text. So in your code you should set the Text property only with chunk[0]. 

    If you want to provider additional information you should provide that as part of entry fields.

    Romulus Crisan | Translation Productivity Development Manager | SDL | (twitter) @cromica_82 | (blog) http://www.romuluscrisan.com/

  • Hi Romulus - similar case on our end (currently developing a Coreon Terminology Provider for Studio). You say here that "This has to be only the source term because this needs to be identified in the segment." Does this indicate that there is (currently) no way to tell Studio about the offsets of a found term. I mean the found term (the normal form as stored in the termbase) is usually different from the token occurring in the segment itself (inflections, German umlauts, and discontinuous patterns - Der Anwender fährt den Rechner hoch := hochfahren). Or is there a way to say: we found "hochfahren" in the termbase, and this hit applies to the source segment at following offsets ([14-18],[32-35]). In other words, our Terminology Provider does the identification already, and we'd like to pass this on to Studio. Is this somehow exposed in the API (or not)?

Reply
  • Hi Romulus - similar case on our end (currently developing a Coreon Terminology Provider for Studio). You say here that "This has to be only the source term because this needs to be identified in the segment." Does this indicate that there is (currently) no way to tell Studio about the offsets of a found term. I mean the found term (the normal form as stored in the termbase) is usually different from the token occurring in the segment itself (inflections, German umlauts, and discontinuous patterns - Der Anwender fährt den Rechner hoch := hochfahren). Or is there a way to say: we found "hochfahren" in the termbase, and this hit applies to the source segment at following offsets ([14-18],[32-35]). In other words, our Terminology Provider does the identification already, and we'd like to pass this on to Studio. Is this somehow exposed in the API (or not)?

Children