NISUS Archives

December 2010

NISUS@LISTSERV.DARTMOUTH.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Reply To:
Date:
Sat, 25 Dec 2010 03:23:52 +0900
Content-Type:
text/plain
Parts/Attachments:
text/plain (184 lines)
On Dec 24, 2010, at 9:43 PM, Nobumi Iyanaga wrote:

> Although I don't understand well what is the point of your macro (I have never made an index with NWP...),

Ah, perhaps I need such macros just because I'm now struggling to create indexes for a new edition of old books *not* written by me? The author is supposed to be contemplating the eternal and separate Intellects now. Or even enjoying the direct connection with them, I think! So I cannot ask him about my doubts. And he does not seem to have done any effort to facilitate someone future's task to build an index for his works. Oh well.

(You, Nobumi, and some others on the list can easily identify his name, I think, but *please* don't mentioned it on the list, of which the archives is indexed by Google. I don't know if the publication plan has been already announced or not.)

> I think that the new Nisus macro language (which is now not so new...) is a very powerful tool offered to users, but its usefulness remains very limited, because it appears to many of us excessively difficult to understand. The lack of an easy tutorial is a very important shortcoming in NWP as a product.

I agree with you. But at the same time, I tend to think the most efficient way to understand and master the NWP macro language, or script languages in general, is to write macros which show how macro commands work and how a document is structured from the macro interpreter's point of view. Seeing is knowing.

For example, someone may have difficulties in understanding the zero-based character index, the concept of Text object, that of Text Selection object, etc. Also, it may be contra-intuitive that every and each table cell is an individual and separate Text Selection object although explained in the Macro Reference. Then, let's write a short and simple macro and run it with different insertion points and single or multiple selections.

$doc = Document.active
$sels = $doc.textSelections
exit $sels

BTW, for such a purpose, I prefer "exit" command to "Prompt" for the Exit dialog box allows you to copy text displayed in it while the latter does not. And I have "TestMacro.nwm" with a shortcut so that I can try this kind of investigations easily.

> It seems to me that your macro parses the entire texts of a document looking for a specific attribute (the existence of a link in this case), making a "list" of all the instances of texts with a link, then goes through it from the end to the beginning, inserting after each instance a text consisting of the "prefix" plus the link text plus the "postfix". Is this right?

Yes, exactly. And it merges continuous Text Selection objects. As I explained before, "Author's <i>Title<i>" is treated as two Text Selection objects by attributesAtIndex and displayAttributesAtIndex commands because of the italic style because of the italic style although it is irrelevant for the macro. If you don't merge them, you will get "Author's [url text]<i>Title<i>[url text]" which is undesirable.

Perhaps ShowAttributes macro may be helpful to understand the difference between Attributes and Display Attributes. I wrote this one to understand that difference. 
<http://www2.odn.ne.jp/alt-quinon/files/NWPro/misc/ShowAttributes_nwm.zip>

And you have some Debug commands which, "Debug.log <value>" especially, should be helpful when you want to *see* how a macro works. 

Also, I'd like to recommend a regular expression tutorial available at:
<http://www.regular-expressions.info/tutorial.html>
(A few regex features are not supported by NWP or supported with a different meta character. So don't be surprised if some examples do not work in our beloved word processor.)

Make Link Visible macro does not use any regular expression, or rather no find (and replace) command is used in it. But this is exceptional. Many macros do use and require regular expressions and NWP is an ideal environment for make yourself acquainted with them. What is nice with the regex is that it is platform/application independent. If you will have mastered its basics, you can use it anywhere.

> Can I ask you to add comments to your macro lines, so that we would be able to understand a little better their meaning; then perhaps I would ask you more questions about some of the points which will be more difficult to understand, etc.

Oh, I cannot ignore such a request, especially those from you. Like many others, I began to learn the macro language, that of NW Classic in my case, by modifying macros written by others so that they fit my needs, macros supplied by Nisus soft and posted here. And your fully commented macros were very, very helpful. Also, sometimes you gave me off-list lessons of NW macro and regex. Without your help, surely I could not finish my macro apprenticeship successfully and in a relatively short time. I cannot thank you more. Then, it is a mystery to me that you seem to have some difficulties with the new macro language. I think you are too busy to dedicate some *continuous* time (say, four or five days) to explore it.

Anyway, below is a commented version of the macro. And I replaced the uploaded file with this one which may look more legible (comments in dark green).
<http://www2.odn.ne.jp/alt-quinon/files/NWPro/link/MakeLinkVisible_nwm.zip>

It's too late here... Good night, good day,


Kino

--

### Make Link Visible ###

# Insert link destination text after each link with $prefix and $suffix, e.g.
# Apple will be Apple [http://www.apple.com/]
# Language of the current insertion point will be applied on texts to be inserted.


# define $prefix, $suffix, $highLightColor and $textColor used for the output
# the purpose of "Cast to String" is to prevent style attributes
# in the macro file from affecting the output
$prefix = Cast to String ' ['
$suffix = Cast to String ']'
$highLightColor = Color.newWithRGB255 234, 235, 255
$textColor = Color.newWithRGB255 0, 0, 127

$doc = Document.active  # Get Document object of the frontmost document.
if $doc == undefined  # i.e. if no document is open...
	# exit silently for the macro is supposeed to have been run accidentally.
	exit
end

# Get the active (and first) Text Selection object.
$selActive = TextSelection.active

# Get the display attributes of $selActive.
# It is *display* attributes in order to cover attributes defined in styles too.

$attr = $selActive.text.displayAttributesAtIndex $selActive.location
$lang = $attr.language  # will be applied on the output.
$fontSize = $attr.fontSize - 1  # will be applied on the output.

# Create/initialize a new array to store Text Selection objects
# for text portions having hyperlink.
# Each Text Selection object consists of a Text object ID,
# a character index of the location and the length of the selection.
$sels = Array.new

# The foreach loop below will go through every $text (Text object of the document).
# A document consists of multiple Text objects, body text, header, footer,
# footnotes, endnotes, table cells (a table cell is an independent text object).

foreach $text in $doc.allTexts
	# Set $i (character index) to 0 (the very begining of $text [Text object])
	$i = 0
	# As character index is zero based, the index of the last character
	# of a Text object is always "$text.length - 1"
	while $i < $text.length
		# Get attributes at $i.
		# Instead of attributesAtIndex, you can use displayAttributesAtIndex
		# command which is safer when you are not sure if attribute(s) you are
		# looking for can be detected by attributesAtIndex command.
		$attr = $text.attributesAtIndex $i
		# Get range of text having the same attributes.
		# You can use rangeOfDisplayAttributesAtIndex command as well and
		# it may be preferable for the reason mentionned in the last comment.
		$range = $text.rangeOfAttributesAtIndex $i
		# if $attr.link is defined, i.e. if $i has hyperlink url...
		if Defined $attr.link
			# Create a Text Selection object corresponding with
			# $text (Text object) and $range (location and length)
			$sel = TextSelection.new $text, $range
			# See if this Text Selection object is continuous to
			# to the previous and last Text Selection object.
			# Let's suppose it is not continuous.
			$isContinuous = false
			# If $sels is empty, there is no possibility of the continuity
			# for there is no previous Text Selection object.
			if $sels.count  # i.e. if $sels.count is one or more...
				# AND if the end of the last Text Selection object
				# coincides with the beginning of $sel
				# (newly created Text Selection object)...
				if $sels.lastValue.bound == $sel.location
					# AND if both of them belong to the same Text object...
					if $sels.lastValue.text.isSameObject $text
						# then, they are continuous.
						# So extend the length of the last Text Selection object
						# instead of adding this $sel to $sels.
						$sels.lastValue.length += $sel.length
						# Change the value of $isContinuous to true
						# to prevent "$sels.appendValue $sel" below
						# from being executed.
						$isContinuous = true
					end
				end
			end
			# If $isContinuous remains false, this means
			# that this $sel is NOT continuous to the previous and last
			# Text Selection object.
			if $isContinuous == false
				# So let's add this $sel to $sels.
				$sels.appendValue $sel
			end
		end
		# Move $i to just after $range.
		$i = $range.bound
	end
end

if ! $sels.count  # i.e. if $sels.count is zero...
	exit 'No link found, exiting...'
end


# Inset hyperlink destination text (url) with $prefix and $suffix
# just after each text portion having hyperlink from the document end
# to the document start.

# It is convenient to process from the end to the beginning
# for inserting something will change the location of
# the remaining document text.

foreach $sel in reversed $sels
	# Get attributes at the location (starting point) of $sel.
	$attr = $sel.text.attributesAtIndex $sel.location
	# Put $prefix and $attr.link (hyperlink destination) in $linkText.
	$linkText = $prefix & $attr.link
	# Append $suffix to $linkText.
	# You cannot use "$linkText = $prefix & $attr.link & $suffix"
	# for the macro interpreter does not allow youto put
	# more than a single command (& in this case) on the right of =.
	$linkText &= $suffix
	# Use "Push Target Text $linkText ... Pop Target Text"
	# to apply style attributes on a variable ($linkText).
	Push Target Text $linkText
		$lang.apply
		Set Font Size $fontSize
		Set Text Color $textColor
		Set Highlight Color $highLightColor
	Pop Target Text
	# Inset $linkText at the end of $sel
	$sel.text.insertAtIndex $sel.bound, $linkText
end

### end of macro ###

ATOM RSS1 RSS2