Turning styled text into tagged text

Get help using and writing Nisus Writer Pro macros.
Post Reply
waltzmn
Posts: 50
Joined: 2013-05-05 12:52:00

Turning styled text into tagged text

Post by waltzmn »

This one takes me back a long, long way....

Back in the NisusWriter Classic days, I created a macro that would convert a formatted document into a markup language (in this case, Quark XPress tags). The most important part of this process, and the one I don't know how to recreate, was reading the ruler name of a particular paragraph, putting an @ symbol at the front, and a colon at the end. So if I had a paragraph using the "normal" ruler, it would be something like this:

This is a paragraph that uses the "Normal" ruler. Otherwise, it's just text. But I want to put the ruler name at the beginning as a tag.

When the macro was run, it would produce this:

@Normal:This is a paragraph that uses the "Normal" ruler. Otherwise, it's just text. But I want to put the ruler name at the beginning as a tag.

I suddenly find I need to do this same operation. Obviously the old macro doesn't work. :-) But, more to the point, the method doesn't work, because NWP uses true paragraph style sheets rather than character styles and named rulers. (And I have checked, and the styles do not import properly into Quark XPress.)

Reading the macro manual, it is not clear to me how one determines the paragraph style of a particular paragraph. What I need is a macro that I would pseudocode as follows:

Code: Select all

FOREACH $paragraph IN $Document
  READ $paragraphStyleName
  $ParagraphStyleTag = "@" & $ParagraphStyleName & ":"
  PASTE $ParagrapgStyleTag at ThisParagraph.start
NEXT $paragraph
Any suggestions for how I get that elusive paragraph style tag?

Thanks for any ideas!
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Turning styled text into tagged text

Post by phspaelti »

In current NWP language you will need to use the formatting attributes. You can get the attributes for any location in the text of a document like so:

Code: Select all

$doc = Document.active # Put this at the very beginning of your code
$loc = … # set to the location you want to check
$attr = $doc.text.attributesAtIndex $loc
# Now you can get the paragraph style name like this
$attr.paragraphStyleName # this is just a void call at the moment
Incidentally there are several ways to get the attributes: in particular .attributesAtIndex and .displayAttributesAtIndex. The difference is the former will only give you the applied formatting. It won't give you the inherited formatting. The latter will give you everything you see. Actually for paragraph styles it shouldn't make a difference since, if there is none applied, there won't be any displayed.

So now you need the $loc for the above code, which will be the location of the paragraph. To step through all the paragraphs of the document, you have two options:

1. Do a Find all which will return an array of selections. Then you can use the foreach method.

2. Use a "Kino" loop. By this I mean; start with $loc 0; then get the first paragraph; then set the $loc to the .bound of the paragraph; then get the next paragraph; and so on till you reach the end of the document.

Here is code for the first method:

Code: Select all

$paras = $doc.text.findAll '^.+\n', 'Ea' 
foreach $para in $paras
    $attr = $doc.text.attributesAtIndex $para.location
    # Do what you have to here
end
Here is code for the second method:

Code: Select all

$loc = 0
while $loc < $doc.text.length
    $attr = $doc.text.attributesAtIndex $loc
    # Do what you have to here 
    $loc = $doc.text.rangeOfParagraphAtIndex($loc).bound
end
Finally remember that if you are going to modify the text while in the loop it's generally better to work back to front. This is definitely true with the first method, since the find selections will remain pointing at the document that was at the time of the search. The second method is probably safe in forward order, as long as you update the $loc after any changes you make. (No guarantees.)

So to do a reverse foreach you will have to write:

Code: Select all

forach $para in reversed $paras
Finally you can insert the paragraph style name using .insertAtIndex.

So putting it all together you get:

Code: Select all

$doc = Document.active
$paras = $doc.text.findAll '^.+\n', 'Ea' 
foreach $para in reversed $paras
    $attr = $doc.text.attributesAtIndex $para.location
    $para.text.insertAtIndex $para.location, '@' & $attr.paragraphStyleName & ':'
end
Here the "Kino"-loop method:

Code: Select all

$doc = Document.active
$loc = 0
while $loc < $doc.text.length
    $attr = $doc.text.attributesAtIndex $loc
    $doc.text.insertAtIndex $loc, '@' & $attr.paragraphStyleName & ':'
    $loc = $doc.text.rangeOfParagraphAtIndex($loc).bound
end
Addendum: When I tried this last one on a simple document, it worked fine. But on a more complex document it started going haywire. The Find method is probably safer. Alternately one can use the "Kino"-loop to gather the paragraph ranges into an array and then run a foreach loop on the reversed array. Or you can try to write the "Kino-loop to work in reverse. That is a little bit trickier though.
philip
waltzmn
Posts: 50
Joined: 2013-05-05 12:52:00

Re: Turning styled text into tagged text

Post by waltzmn »

phspaelti wrote:
In current NWP language you will need to use the formatting attributes. You can get the attributes for any location in the text of a document like so:
{etc.]

Amazingly impressive. I wasn't even sure there was a way, and you gave me two!

Thank you again for all your knowledge and all the help you offer to people here.
Post Reply