protected IList <SegmentData> GetInlineSegments(XElement element) { var builder = new SegmentedContentBuilder(); SegmentInlineContent(builder, element, true); return(builder.GetSequence()); }
protected override bool HandleMarkElement(SegmentedContentBuilder builder, XElement mrk, bool allow_segmentation) { if ((string)mrk.Attribute("mtype") == "x-mq-tc") { // mrk[@mtype = 'x-mq-tc'] is a tracked change in memoQ. var tctype = (string)mrk.Attribute(MQ + "tctype"); switch (tctype) { case "del": builder.PushProp(InlineProperty.Del); SegmentInlineContent(builder, mrk, false); builder.PopProp(); return(true); case "ins": builder.PushProp(InlineProperty.Ins); SegmentInlineContent(builder, mrk, false); builder.PopProp(); return(true); default: // Unknown mq:tctype attribute value. Just pass it to the default mrk processing. break; } } return(base.HandleMarkElement(builder, mrk, false)); }
protected InlineString GetInline(XElement element) { if (element == null) { return(null); } var builder = new SegmentedContentBuilder(); SegmentInlineContent(builder, element, false); var seq = builder.GetSequence(); if (seq.Count == 0) { return(InlineString.Empty); } if (seq.Count != 1) { throw new Exception("Internal Error"); } if (seq[0]?.InlineString == null) { throw new Exception("Internal Error"); } return(seq[0].InlineString); }
protected override bool HandleMarkElement(SegmentedContentBuilder builder, XElement mrk, bool allow_segmentation) { switch ((string)mrk.Attribute("mtype")) { case "x-sdl-deleted": // This is a deleted section in change tracking. // Can a mrk[@mtype='seg'] occur inside mrk[@mtype='x-sdl-deleted']? FIXME. builder.PushProp(InlineProperty.Del); SegmentInlineContent(builder, mrk, allow_segmentation); builder.PopProp(); return(true); case "x-sdl-added": // This is an added (inserted) section in change tracking. // Can a mrk[@mtype='seg'] occur inside mrk[@mtype='x-sdl-added']? FIXME. builder.PushProp(InlineProperty.Ins); SegmentInlineContent(builder, mrk, allow_segmentation); builder.PopProp(); return(true); default: break; } return(base.HandleMarkElement(builder, mrk, allow_segmentation)); }
/// <summary> /// Try to handle an mrk element. /// </summary> /// <param name="builder">The builder the contents are fed to.</param> /// <param name="mrk">The mrk element to be handled.</param> /// <param name="allow_segmentation">true if segmentation is allowed at this level.</param> /// <returns>true if <paramref name="mrk"/> has been handled, false otherwise.</returns> protected virtual bool HandleMarkElement(SegmentedContentBuilder builder, XElement mrk, bool allow_segmentation) { // mrk tags are _markers_ for CAT tools. // We take care of the XLIFF segmentation spec. // In the spec., // mrk[@mtype='seg'] is used for segmentation. // Other standard @mtype are mostly linguistic annotations. // mrk elements with non-standard @mtype are CAT software dependent. // Most of their uses are invisible to translators, // although there MAY BE some that are visible. // For the moment, // we ignore the start and end tags for all mrk elements, // leaving the content, // except for those for segmentation. if (allow_segmentation && (string)mrk.Attribute("mtype") == "seg") { builder.Add(mrk); return(true); } return(false); }
protected virtual bool HandleUnknownTag(SegmentedContentBuilder builder, XElement element) { return(false); }
/// <summary> /// Analyzes contents of an XML element as a (possibly segmented) XLIFF inline text. /// </summary> /// <param name="builder">Results are stored in this object.</param> /// <param name="elem">The element whose contents is analyzed.</param> /// <param name="allow_segmentation">true if the standard XLIFF segmentation is allowed.</param> protected void SegmentInlineContent(SegmentedContentBuilder builder, XElement elem, bool allow_segmentation) { // Why shouldn't we throw ArgumentNullException in this case? FIXME. if (elem == null) { return; } foreach (var n in elem.Nodes()) { if (n is XText) { builder.Add((n as XText).Value); } else if (n is XElement) { var e = (XElement)n; var ns = e.Name.Namespace; var name = e.Name.LocalName; if (ns == X && name == "mrk") { var handled = HandleMarkElement(builder, e, allow_segmentation); if (!handled) { SegmentInlineContent(builder, e, allow_segmentation); } } else if (ns == X && (name == "x" || name == "ph")) { // Replace a standalone native code element with a standalone inline tag. builder.Add(BuildNativeCodeTag(Tag.S, e, name == "ph")); } else if (ns == X && (name == "bx" || name == "bpt")) { // Replace a beginning native code element with a beginning inline tag. builder.Add(BuildNativeCodeTag(Tag.B, e, name == "bpt")); } else if (ns == X && (name == "ex" || name == "ept")) { // Replace an ending native code element with an ending inline tag. builder.Add(BuildNativeCodeTag(Tag.E, e, name == "ept")); } else if (ns == X && name == "it") { // Replace an isolated native code element with an appropriate inline tag. Tag type; switch ((string)e.Attribute("pos")) { case "open": type = Tag.B; break; case "close": type = Tag.E; break; default: type = Tag.S; break; } builder.Add(BuildNativeCodeTag(type, e, true)); } else if (ns == X && name == "g") { // If this is an XLIFF g element, // replace start and end tags with inline tags, // and keep converting its content, // because the g holds instructions in its attributes, // and its content is a part of translatable text. builder.Add(BuildNativeCodeTag(Tag.B, e, false)); SegmentInlineContent(builder, e, allow_segmentation); builder.Add(BuildNativeCodeTag(Tag.E, e, false)); } else { // Unknown element, i.e., some external (no XLIFF) element or a // misplaced XLIFF element. // OH, I have no good idea how to handle it. FIXME. var handled = HandleUnknownTag(builder, e); if (!handled) { var id = "*"; var rid = UniqueNumber.ToString(); if (string.IsNullOrEmpty(e.Value)) { builder.Add(new InlineTag(Tag.S, id, rid, name, null, null, null)); } else { // Assume the contents of this element is a translatable text. builder.Add(new InlineTag(Tag.B, id, rid, name, null, null, null)); SegmentInlineContent(builder, e, allow_segmentation); builder.Add(new InlineTag(Tag.E, id, rid, name, null, null, null)); } } } } else { // Silently discard any other nodes, i.e., comment or pi, entirely. } } }