Trouble with AbstractNativeFileWriter in Native FileType Plugin – SegmentEnd vs. ParagraphUnitEnd != Line end

I am developing a custom FileType plugin for certain text files.

Although I've stumbled several times, I made it pretty far. Files are properly recognized and parsed, all great. My trouble now is with generating the target files.

To be precise: The problem arises with lines that span several segments in Studio. They should be written in one line.

I have tried to accomplish this by replacing the override SegmentEnd() method in the sample with ParagraphUnitEnd():

public override void ParagraphUnitEnd()
    {
        _targetFile.WriteLine();
    }

This does indeed write the paragraphs as one line. Unfortunately it also adds a hard return after each structure tag, which is not intended.

 

So to recap, my problem. Intended outcome:

key1=value1, bla yadda. More yadda.
key2=value2, foo. Bar...

 

Outcome using override SegmentEnd():

key1=value1, bla yadda.
More yadda.
key2=value2, foo.
Bar...

 

Outcome using override ParagraphUnitEnd():

key1=
value1, bla yadda. More yadda.
key2=
value2, foo. Bar...

 

How can I achieve my intended output?

Thanks!

  • Hi Jesse,

    I have not implemented an override to ParagraphUnitStart at all.

    Here is my complete class. Should have posted that right away anyway:

    public class IslTextWriter : AbstractNativeFileWriter, INativeContentCycleAware
    {
        IPersistentFileConversionProperties _conversionProperties;
        StreamWriter _targetFile = null;

        public void SetFileProperties(IFileProperties properties)
        {
            _conversionProperties = properties.FileConversionProperties;
            var utf8 = new Codepage(new UTF8Encoding(true));
            _conversionProperties.PreferredTargetEncoding = utf8;
        }

        public void EndOfInput()
        {
            _targetFile.Close();
            _targetFile.Dispose();
            _targetFile = null;
        }

        public void StartOfInput()
        {
            _targetFile = new StreamWriter(OutputProperties.OutputFilePath);
            _targetFile.Write("\xfeff");
        }

        public override void StructureTag(IStructureTagProperties tagInfo)
        {
            var sLine = tagInfo.TagContent;
            if (sLine.StartsWith("LanguageName") || sLine.StartsWith("LanguageID") || sLine.StartsWith("LanguageCodePage"))
            {
                _targetFile.WriteLine(sLine);
            }
            else
            {
                if (sLine.StartsWith("[") || sLine.StartsWith(";") || string.IsNullOrEmpty(sLine.Trim('\r', '\n')))
                {
                    _targetFile.WriteLine(sLine);
                }
                else
                {
                    _targetFile.Write(sLine + "=");
                }
            }
        }

        public override void Text(ITextProperties textInfo)
        {
            _targetFile.Write(textInfo.Text);
        }

        public override void InlineStartTag(IStartTagProperties tagInfo)
        {
            _targetFile.Write(tagInfo.TagContent);
        }

        public override void InlineEndTag(IEndTagProperties tagInfo)
        {
            _targetFile.Write(tagInfo.TagContent);
        }

        public override void InlinePlaceholderTag(IPlaceholderTagProperties tagInfo)
        {
            _targetFile.Write(tagInfo.TagContent);
        }

        //make sure a line break is inserted after each end of a segment
        //public override void SegmentEnd()
        //{
        //    _targetFile.WriteLine();
        //}
        public override void ParagraphUnitEnd()
        {
            _targetFile.WriteLine();
        }
    }

     

    As you can see, I have tried to set the encoding to UTF8 with BOM. Since this does not work directly, I am writing the BOM in StartOfInput().

    It would be easily fixed if something like this existed (Pseudocode):

    public override void SegmentEnd()
    {
        if(this.LocationTracker.Equals(Location.EndOfParagraph))
            _targetFile.WriteLine();
    }

     

    P.S: Does this board have any kind of preview function before posting?

  • Hi Andreas,

    Thanks for the explanation.
    I cannot think of an elegant solution for this...
    If I understand correctly, if the previous written item is a structure tag, then you do not want a new line.

    Does the following work?

    bool lastSawStructureTag = false;

    public override void StructureTag(IStructureTagProperties tagInfo)
    {
    lastSawStructureTag = true;
    // Rest of code
    }

    public override void SegmentEnd()
    {
    lastSawStructureTag = false;
    }

    public override void ParagraphUnitEnd()
    {
    if (!lastSawStructureTag) _targetFile.WriteLine();
    }
  • "If it is stupid but it works it is not stupid!"
    Thanks Jesse, that perfectly does the trick!
    :-)