0

I'm building a large word document, and need to change the text colour of 'part' of a string, only.

I've found similar questions in a few places here, here and here, but where my problem seems to differ, is that I only wish to colour part of a string, as opposed to a whole paragraph, or an entire OpenTBS field, as in these examples.

I first tried wrapping the individual chunk of string in docx XML tags, but found php converted then to entities (&gt; etc) which clearly was no use. Currently, I've moved on to wrapping the part of the text in XML tags through a template script, which gives me a malformed XML output, I presume because I have content between the </w:r> from one substring, and the <w:r> of the next substring.

Any advice on how to do this properly? Below is the current code and output.

//Function called onmerge. I wrap the portion of string I want to change the text 
//colour of with [UNTRANSLATED] and [ENDUNTRANSLATED] manually earlier, and attempt 
//to swap them for tags at this point.
function lb($FieldName, &$CurrVal) { 
    $CurrVal= str_replace('[UNTRANSLATED]', '<w:r><w:rPr><w:color w:val="FF0000"/></w:rPr><w:t>', $CurrVal); 
    $CurrVal= str_replace('[ENDUNTRANSLATED]', '</w:t></w:r>', $CurrVal); 
}

And the output...

<w:t> 
    <w:r> 
        <w:rPr> 
            <w:color w:val="FF0000" /> 
        </w:rPr> 
        <w:t>Slaked Lime</w:t> 
    </w:r>,
    <w:r>
         <w:rPr>
             <w:color w:val="FF0000" />
         </w:rPr>
         <w:t>Air slaked Lime</w:t>
    </w:r>,
[code continues in same style...]

Word flags the error at the point where my second block, and second <w:r> tag are. Unfortunately the error is beautifully non-descript.


Community
  • 1
  • 1
Chris
  • 5,882
  • 2
  • 32
  • 57
  • 1
    Is it so hard to test it without the commas between and let us know if those are actually the problem? If they are, I think the first question you referenced has the answer you need and you just don't want to wrap those commas in their own elements... I also don't think you can wrap ``s inside other ``s - have you tried changing the parent to ``? And hopefully the missing closing tag is just a copy-paste error... – Sarah Kemp Dec 16 '13 at 16:11
  • Hello Sarah. Tried again, it's not specifically the commas, but Word flags the error at the point after my first `` and next ``. (It's a non-descript error.) I'll update the question accordingly. I haven't tried changing the parent `` - I don't know so much about how docx xml is structured. All this part of the code is autogenerated however, is there any version of getParentXMLTag() in tinybutstrong? I wouldn't be sure how to go about doing that. – Chris Dec 16 '13 at 16:26

2 Answers2

2

The issue with the above code was that OpenTBS inputs strings into a pair of <w:r><w:t> tags, which need to be closed, before you insert your own. (As Sarah Kemp said in comments, <w:t> doesn't appear to be nestable.

The below is an updated, working version. xml:space="preserve" also needed to be added to preserve spacing.

//Function called onmerge. I wrap the portion of string I want to change the text 
//colour of with [UNTRANSLATED] and [ENDUNTRANSLATED] manually earlier, and attempt 
//to swap them for tags at this point.
function lb($FieldName, &$CurrVal) {
  $CurrVal= str_replace('[UNTRANSLATED]', '</w:t></w:r><w:r><w:rPr><w:color w:val="FF0000"/></w:rPr><w:t xml:space="preserve">', $CurrVal);
  $CurrVal= str_replace('[ENDUNTRANSLATED]', '</w:t></w:r><w:r><w:t xml:space="preserve">', $CurrVal);
} 
Chris
  • 5,882
  • 2
  • 32
  • 57
1

My only suggestion is to look at a well-formed Word document and base your code on that. I made a basic document and typed a line then changed the color of a word. Then I changed the file extension to zip from docx and looked at the XML in word/document.xml. Here is what it looks like straight from Word (with formatting applied):

<w:p w:rsidR="00BA3836" w:rsidRDefault="00420636">
    <w:r>
        <w:t xml:space="preserve">This is some text where </w:t>
    </w:r>
    <w:r w:rsidRPr="00420636">
        <w:rPr>
            <w:color w:val="FF0000"/>
        </w:rPr>
        <w:t>parts</w:t>
    </w:r>
    <w:r>
        <w:t xml:space="preserve"> are red.</w:t>
    </w:r>
</w:p>

In the document, the word 'parts' is red.

I could offer more help if you extract the XML from your .docx file like I've done and post the relevant area (with TBS tags intact - prior to merge).

It sounds like you are very close to getting this resolved. Did you play with parameter strconv=no?

Sarah Kemp
  • 2,670
  • 3
  • 21
  • 29
  • Hi Sarah, thanks for the full reply! The example above is the extracted XML post-merge, pre-merge, it's just a single tag in a cell of a many level nested table, as this part is generated from a tag which creates about 16 pages of word doc, through a massive nested merge. Regardless, the tag is simply `[section_sub1_sub1.fieldContents;onformat=lb;magnet=tbs:row]` (But as it shows, this is a couple of sub blocks in!) – Chris Dec 17 '13 at 09:31
  • From your example, that shows me that I should be enclosing my other (non-coloured) text in `` tags - but how can I get at it to do that? :-/ Although perhaps I could complete all that part of it in PHP...but then I'd imagine it will be nested inside the original `` of the docx, which I imagine is forbidden? I'll have more of a play. – Chris Dec 17 '13 at 09:33
  • Managed to work it out in the way shown below eventually - thank you for your help debugging, and helpful pointers! – Chris Dec 17 '13 at 09:54