Page 1 of 1

linebreaks and indents in TEXT output

Posted: Thu Sep 10, 2020 1:30 am
by GregWait42
I have a DITA document for **TEXT** output that contains msg elements like this:

Code: Select all

<msg>
  <msgId>
 
     <msgNumber>1234567</msgNumber>

  </msgId>
  <msgText>The variations of this message are explained below. <?linebreak?> -option one. <?linebreak?> -option two. 
  </msgText>
</msg>
I need the output of msgText to break at each <?linebreak?> and to indent the result. Because the output is simple text my hands are tied in a lot of ways. Here’s a sample of the desired output:

-----------------------------------------------------------------
1234567 The variations of this message are explained below.
                                                                 
        -option one.
                                                                 
       -option two.


I’ve managed to force the line breaks and indent the subsequent lines, BUT where any segment of msgText is long enough to wrap to the next line, the wrapped portion is not indented…

-----------------------------------------------------------------
1234567 The variations of this message are explained below. This
part wraps and needs to be indented.
                                                                
        -option one. When these segments are long enough to wrap
this part wraps and needs to be indented.
                                                                
       -option two.

Here’s the code I have that makes it work to the extent it does:

Code: Select all

<xsl:template match="*[contains(@class, ' msg/msgText ')]">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="processing-instruction()[name() = 'linebreak']">
  <!-- This forces a linebreak by filling an entire line with non-breaking-spaces, and tacking on 
     a normal space to allow content that follows to wrap to the next line. -->
   <text>
      <xsl:for-each select="1 to $LINELENGTH">&#160;</xsl:for-each>
      <xsl:text> </xsl:text>
  </text>
     <!-- This indents the first line of the next segment of msgText. -->
     <text>&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text>
</xsl:template>
I’m close to the solution on this, but I can’t think of a way to directly manipulate the segments of msgText since I’m breaking it into segments when the focus is on <?linebreak?>.

Any thoughts, ideas, lifelines gratefully accepted. Thanks!

Re: linebreaks and indents in TEXT output

Posted: Thu Sep 10, 2020 6:52 am
by Radu
Hi Greg,

That particular "msgText" does not appear to be part of the DITA specification. How about if you add in your DITA specialization another element named "msgPreserveText" which would extend the DITA <codeblock> base element?

Coming back to your stylesheet, maybe instead of matching the PIs you could match the text nodes before each PI:

Code: Select all

    <xsl:template match="text()[following-sibling::node()[1][processing-instruction()[name() = 'linebreak']]]">
        
        
    </xsl:template>
Regards,
Radu

Re: linebreaks and indents in TEXT output

Posted: Thu Sep 10, 2020 11:05 pm
by GregWait42
Radu -

Thanks for your reply. Unfortunately, unless I'm missing some nuance or piece you expected me to know to fill in, your code simply selects the entire msgText text node as a single entity in essentially the same way <xsl:template match="*[contains(@class, ' msg/msgText ')]"> does.

In testing, when I replace my processing-instruction template with your suggestion and add "matched" to indicate its impact...

Code: Select all

<xsl:template match="*[contains(@class, ' msg/msgText ')]">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="text()[following-sibling::node()[1][processing-instruction()[name() = 'linebreak']]]">
        <text>matched</text>
</xsl:template>
I get this result:

-----------------------------------------------------------------
1234567 matchedThe variations of this message are explained below. -option one. -option two.


What I hoped/need as a result is:

-----------------------------------------------------------------
1234567 matchedThe variations of this message are explained below. matched-option one. matched-option two.


If I can break msgText into a number of separate entities I can handle uniquely, I'll be able to achieve the desired result. Unless I'm implementing it incorrectly, your solution returns the text of msgText in its entirety.

Thanks!

Re: linebreaks and indents in TEXT output

Posted: Fri Sep 11, 2020 8:33 am
by Radu
Hi,

Sorry, should have checked my XSLT bit before offering it as an example.
This should work to match all individual pieces of text immediately followed by that processing instruction:

Code: Select all

  <xsl:template match="msgText/text()[following-sibling::node()[1][self::processing-instruction()][name() = 'linebreak']]">
Regards,
Radu

Re: linebreaks and indents in TEXT output

Posted: Fri Sep 11, 2020 8:38 am
by Radu
Or maybe match text which is after a processing instruction:

Code: Select all

    <xsl:template match="msgText/text()[preceding-sibling::node()[1][self::processing-instruction()][name() = 'linebreak']]">
whatever suits you better.

Regards,
Radu

Re: linebreaks and indents in TEXT output

Posted: Sat Sep 12, 2020 12:37 am
by GregWait42
Radu,

I think you've got me on the right path. With a few tweaks I have it breaking up the text so I can handle the first segment separately from those that follow. Now I need to figure out a way to indent any part of each segment that wraps to the next line, but you've got me moving forward. Thanks!

Greg