Get the caret out of a table

Get help using and writing Nisus Writer Pro macros.
Post Reply
js
Posts: 259
Joined: 2007-04-12 14:59:36

Get the caret out of a table

Post by js »

My document starts with a table

If the cursor is inside the table "Select Start" as expected selects the first cell of the table.
If the cursor is after the table outside of it "Select Start" quite unexpectedly also selects the first cell of the table.
Same thing after applying "Select All Document“ and then "Select Start".

It is possible to place the caret before (and not inside) the table on top of the document manually. But how to do this with a macro?
The Macro Reference, under the heading "TableSelection & Table Object Example" offers a code example to get the caret after a table. This is by using ".bound". But I am not sure how to get the caret BEFORE the table.

I have another problem with tables: I tried in vain to find out how to get a macro to apply shading to selected single cells (rather than to set shading to paragraphs which produces shading to the whole row containing the selected cells).
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Get the caret out of a table

Post by phspaelti »

There are two ways to select a table: (1) if you do "Select All" twice, Nisus will select all the cells of the table, or (2) if you use the mouse to select from right before the table to right after the table. These two ways are quite distinct from Nisus' point of view.

For Nisus a table is treated like a single character in the flow of text. All the other info, the number of rows and columns and the text objects in all the cells of the table are stored elsewhere. The single character where the table is in the document text is called the enclosing range. You can get the enclosing range from the table object using the command .enclosingTextRange. The location where the table starts can be got using .enclosingTextRange.location.

The example you cite from the macro language reference can be made to select before the table by removing (or quoting out) the line:

Code: Select all

$textRange.location = $textRange.bound
Or the whole procedure can be written more compactly like this:

Code: Select all

$doc = Document.active
if $doc.tableSelection
    $tbl = $doc.tableSelection.table
    $doc.setSelection(TextSelection.new($tbl.enclosingText, Range.new($tbl.enclosingTextRange.location, 0)))
end
Last edited by phspaelti on 2019-11-04 10:40:22, edited 1 time in total.
philip
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Get the caret out of a table

Post by phspaelti »

js wrote: 2019-11-04 06:21:20I have another problem with tables: I tried in vain to find out how to get a macro to apply shading to selected single cells (rather than to set shading to paragraphs which produces shading to the whole row containing the selected cells).
Assuming you have created some shading attributes and stored them in the variable $shadingAttributes, you can do it like this:

Code: Select all

$doc.tableSelection.applyShadingAttributes $shadingAttributes
To create shading attributes look in the macro reference in the Table Objects section. For example you could do something like this:

Code: Select all

$red = Color.red
$shadingAttributes = ShadingAttributes.newWithSolidColor $red
$shadingAttributes.blendRatio = 0.25
But maybe your problem is something else? How are you getting/making the table selection?
philip
js
Posts: 259
Joined: 2007-04-12 14:59:36

Re: Get the caret out of a table

Post by js »

Thank you, Philip. Outquoting the line "$textRange.location = $textRange.bound" works fine. Some day I might understand why )=;
Your simplified version produces a system complaint: 'The Table object does not have a "text" property'.
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Get the caret out of a table

Post by phspaelti »

js wrote: 2019-11-04 10:35:26 Your simplified version produces a system complaint: 'The Table object does not have a "text" property'.
Sorry about that. That should be fixed now.
philip
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Get the caret out of a table

Post by phspaelti »

js wrote: 2019-11-04 10:35:26 Thank you, Philip. Outquoting the line "$textRange.location = $textRange.bound" works fine. Some day I might understand why )=;
Here are the relevant lines

Code: Select all

$text = $table.enclosingText
$textRange = $table.enclosingTextRange
$textRange.location = $textRange.bound
$textRange.length = 0
The first line gets the enclosing text object of the table. This is almost certainly the document text object, unless the table is in a funky place like a text box.
The second line gets the enclosing text range. This tells us where in the text object the table is located. A range is basically a pair of numbers: one is the index of where the range starts, the other is the number of characters in the range. Earlier I said that tables were treated as a single character. This turns out to be wrong. They're more like one character for each cell, or something like that. So if your table is located at index 5000, and is a 4x5 table, the enclosing range will be something like (5000, 20). The 5000 is the location and 20 the length. The bound would be 5020.
The third line is where we start to change the selection. Basically a selection will always have a range. If you want the selection to be before the table you will want the range (5000,0) and, if you want the selection after the table you will want the range (5020,0). The length of 0 for the range means that the selection is just an insertion point.

What might be confusing about this macro is that they are using the same variable to get the original enclosing range, and then they just overwrite it with the range for the selection they are trying to create. If it were me I would have written something like:

Code: Select all

$selTextRange = Range.new $textRange.bound, 0
…and then used this new variable to create the selection.
philip
js
Posts: 259
Joined: 2007-04-12 14:59:36

Re: Get the caret out of a table

Post by js »

Thanks for explaining in detail. I think my problem was that I took the index of the table's start to be it's first cell.
About your short form of the macro you say "that should be fixed now". Did you maybe intend to post the fixed code?
js
Posts: 259
Joined: 2007-04-12 14:59:36

Re: Get the caret out of a table

Post by js »

You showed how to create shading attributes with a macro, and then asked:
But maybe your problem is something else? How are you getting/making the table selection?
To answer that: I made selections manually, by selecting (some or all) text within some cells. The menu "Show Paragraph Shading Palette" then permits to shade those cells by producing a color table to chose from. Now I try to do this with a macro which marks some cells by a Find All command (but without a color table).
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Get the caret out of a table

Post by phspaelti »

js wrote: 2019-11-05 09:21:22About your short form of the macro you say "that should be fixed now". Did you maybe intend to post the fixed code?
I just fixed the code in the original post.
philip
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Get the caret out of a table

Post by phspaelti »

js wrote: 2019-11-05 09:36:29 You showed how to create shading attributes with a macro, and then asked:
But maybe your problem is something else? How are you getting/making the table selection?
To answer that: I made selections manually, by selecting (some or all) text within some cells. The menu "Show Paragraph Shading Palette" then permits to shade those cells by producing a color table to chose from. Now I try to do this with a macro which marks some cells by a Find All command (but without a color table).
Just to be clear, you can shade paragraphs and you can shade table cells. Usually in a table the latter is preferred.

As for applying shading using a macro: Due to long-standing tradition Nisus has two ways to write macros Menu Command 'dialect' and Macro Language 'dialect'. The former is usually easier, but often subject to limitations, because features are sometimes only accessible in dialogs , palettes, etc. On the other occasionally a feature is 'reachable' on a menu, but not implemented in the macro language. You [js] have often cited the Macro Language Reference, so I have taken that to mean that you are comfortable with the macro language, and have made suggestions accordingly.

So back to shading.
Table Shading can actually be applied via the menu commands, so it's possible to write a macro to apply shading to all the cells that are currently selected (all or in part).

Code: Select all

:Table:Shading Color:Cornflower Blue
:Table:Shading Pattern:25% Blend
The first line sets the color and the second the blend. You could choose a pattern if you prefer. But some combinations will probably not be achievable. Also you are limited to the colors listed in the menu.

Paragraph Shading can't be done in this way at all, since the features are 'hidden' in a palette, and require clicking and pop-ups, etc.

With the macro language you can do either of these things in any combination, and apply it to any cells/paragraphs you want, as long as you have some describable way to get there. This will work through the two-step process of creating shading attributes and then applying them.

To create the shading attributes, you first have to create a ShadingAttributes object (with any one of the about 6 variant commands), and then 'tweak' it by setting any attributes that are still not to your liking. For colors you will first have to create a color object, which you will have to do via the RGB codes (Straight-up Black, White, Red, Blue, Green have simple commands). That's your color-palette. The other attributes can be set by number, or for patterns by name.

Then to apply the shading attributes you can proceed according to the following methods: For paragraphs, select the relevant paragraphs (e.g. using Find) in part or completely. Then use the Set Paragraph Shading Attributes command. For table cell shading, the easiest method is using the table selection command which I described earlier in this thread. Table Selections can be created by Find (using text you know is in the cells you want) or by directly creating table selections using the commands described in the macro reference.

I hope this clarifies things.
philip
js
Posts: 259
Joined: 2007-04-12 14:59:36

Re: Get the caret out of a table

Post by js »

Thank you Philip. This was very helpful indeed. Everthings works fine now, including your macro earlier revised. (Didn't know that you can modify earlier posts, so I didn't check). Of course it's far easier to shade cells than paragraphs in a table. But I am glad to know how it works for paragraphs anyway. Why don't you write that Nisus macro cookbook which many of us are still hoping to get one day ...
Post Reply