Crunching Text Not Working in a Loop

  • Thread starter Richard Fairbanks
  • Start date
R

Richard Fairbanks

Greetings, folks!

I need to be able to capitalize words inside quote marks, as part of a
string of words. I need to use proper publishing capitalization
protocols which is more involved than simply making the first letter of
each word uppercase. Thus the appended script is greatly truncated!

I would be very grateful if someone could please advise me on why the
following doesn’t work as part of a repeating loop or with typographic
quote marks, but does work as a simple standalone script.

Blessings and thank you!

Richard Fairbanks

----

The following does work, but only if the first quote is a straight
quote: ' or ". It doesn’t work with typesetter marks: ‘ or “

#!/usr/bin/env ruby

require 'rubygems'
require "jcode"; $KCODE = "UTF8"
require 'appscript'; include Appscript
require 'osax'; include OSAX

# copy the text: "abc"
item = osax.the_clipboard()
item1 = item[0,1]
item2 = item[1..-1]
item = item1 + item2.capitalize!
osax.set_the_clipboard_to(item) #=> "Abc"s

----

BUT it doesn’t work at all as part of a loop:

#!/usr/bin/env ruby

require 'rubygems'
require "jcode"; $KCODE = "UTF8"
require 'appscript'; include Appscript
require 'osax'; include OSAX

openingQuoteMark = ["'", "\"", "‘", "’", "“"]

# get the text to be processed:
theString = osax.the_clipboard()

theWords = theString.split # convert the text to an array of the
words

theWords.each do |item|
charList = item.split(//) # create an array of the word’s
characters
# first check to see if there is an opening quote mark
unless openingQuoteMark.include?(charList[0]) # if the word doesn’t
start with a quote mark. If it does, this will only try to capitalize
the quote mark!
# this works fine
item = item.capitalize!
else
# but the following doesn’t work
# to test: copy me to the clipboard with "abc"
item1 = item[0,1]
item2 = item[1..-1]
item = item1 + item2.capitalize!
osax.say "but it does run!"
end
end

# convert the full list to a string with a space between each item
theWords = theWords * ' '

# set the clipboard to the processed string
osax.set_the_clipboard_to(theWords)
 
J

Jesús Gabriel y Galán

Greetings, folks!

I need to be able to capitalize words inside quote marks, as part of a
string of words. I need to use proper publishing capitalization
protocols which is more involved than simply making the first letter of
each word uppercase. Thus the appended script is greatly truncated!

I would be very grateful if someone could please advise me on why the
following doesn=92t work as part of a repeating loop or with typographic
quote marks, but does work as a simple standalone script.

Blessings and thank you!

Richard Fairbanks

----

The following does work, but only if the first quote is a straight
quote: ' or ". It doesn=92t work with typesetter marks: =91 or =93

=A0#!/usr/bin/env ruby

=A0require 'rubygems'
=A0require "jcode"; $KCODE =3D "UTF8"
=A0require 'appscript'; include Appscript
=A0require 'osax'; include OSAX

=A0# copy the text: "abc"
=A0item =3D osax.the_clipboard()
=A0item1 =3D item[0,1]
=A0item2 =3D item[1..-1]
=A0item =3D item1 + item2.capitalize!
=A0osax.set_the_clipboard_to(item) =A0#=3D> "Abc"s

----

BUT it doesn=92t work at all as part of a loop:

=A0#!/usr/bin/env ruby

=A0require 'rubygems'
=A0require "jcode"; $KCODE =3D "UTF8"
=A0require 'appscript'; include Appscript
=A0require 'osax'; include OSAX

=A0openingQuoteMark =3D ["'", "\"", "=91", "=92", "=93"]

=A0# get the text to be processed:
=A0theString =3D osax.the_clipboard()

=A0theWords =3D theString.split =A0# convert the text to an array of the
words

=A0theWords.each do |item|
=A0 =A0charList =3D item.split(//) =A0# create an array of the word=92s
characters
=A0 =A0 =A0# first check to see if there is an opening quote mark
=A0 =A0unless openingQuoteMark.include?(charList[0]) =A0# if the word doe= sn=92t
start with a quote mark. If it does, this will only try to capitalize
the quote mark!
=A0 =A0 =A0# this works fine
=A0 =A0 =A0item =3D item.capitalize!
=A0 =A0else
=A0 =A0 =A0# but the following doesn=92t work
=A0 =A0 =A0# to test: copy me to the clipboard with "abc"
=A0 =A0 =A0item1 =3D item[0,1]
=A0 =A0 =A0item2 =3D item[1..-1]
=A0 =A0 =A0item =3D item1 + item2.capitalize!
=A0 =A0 =A0osax.say "but it does run!"
=A0 =A0end
=A0end

One thing comes to mind: you are iterating over theWords, passing each
word into the block as the variable "item". The object referenced to
that variable is never modified, or the modified version assigned back
into the theWords array. So after the "each" loop, the array the Words
is the original one. The first branch of the unless conditional works,
because you are calling a self modifying method on item
(item.capitalize!). In fact, it will work even if you leave out the
assignment, cause you are assigning to the block local variable item,
which is then reassigned in the following iteration.

On the other branch, when you do item2 =3D item[1..-1] you are doing a
copy of the string, and when you call item2.capitalize!, the original
string is not modified:

irb(main):005:0> s =3D "abcde"
=3D> "abcde"
irb(main):006:0> a =3D s[1..-1]
=3D> "bcde"
irb(main):007:0> a.capitalize!
=3D> "Bcde"
irb(main):008:0> s
=3D> "abcde"

So, the object referenced by item is not modified, and then you only
do item =3D item1 + item2.capitalize!, which does nothing to the
original string, but only assign the local variable. One way to do it
if you don't need the original the_words array:

the_words =3D the_string.split

the_words.map! do |item|
charList =3D item.split(//) # create an array of the word=92s characte=
rs
# first check to see if there is an opening quote mark
unless openingQuoteMark.include?(charList[0])
item.capitalize
else
item1 =3D item[0,1]
item2 =3D item[1..-1]
item1 + item2.capitalize
end
end

p the_words

map! will modify the array, substituting each entry with the result of
the block for that entry. Notice how I don't assign the the item
variable anymore. And by the way, the common Ruby convention is to use
camel_case, not snakeCase. If you want to keep both the original array
and the new one, you can do this:

the_words =3D the_string.split

new_words =3D the_words.map do |item|
charList =3D item.split(//) # create an array of the word=92s characte=
rs
# first check to see if there is an opening quote mark
unless openingQuoteMark.include?(charList[0])
item.capitalize
else
item1 =3D item[0,1]
item2 =3D item[1..-1]
item1 + item2.capitalize
end
end

p the_words
p new_words

map will create a new array, assigning the result of the block to each entr=
y.

Hope this helps,

Jesus.
 
R

Richard Fairbanks

Bless you, Jesús; you saved the day again!

The script now works great, and while playing with it, I learned than
you may even have intended!

;-)

THANK YOU!!

Richard Fairbanks
 
R

Richard Fairbanks

 . . .  I learned than

Sorry; I got too excited! That should have been:

“I learned more than . . . â€

THANK YOU!!

Richard Fairbanks
 
J

Jesús Gabriel y Galán

2010/8/10 Jes=FAs Gabriel y Gal=E1n said:
And by the way, the common Ruby convention is to use
camel_case, not snakeCase.

Notice the brainfart !

this_is_snake_case
thisIsCamelCase

The Ruby convention is to use snake_case.

:)

Jesus.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top