Character width

Discuss AppleScripting for QuarkXPress 10, 9 & 8 (and before)
mathews
Posts: 0
Joined: 20 Oct 2009, 09:55

Character width

Post by mathews » 18 Mar 2012, 10:21

Hi Guys,

I am using Quark Xpress 8.

How can i know the exact character width (measurement) of the selected text.
Is there any script for that?
If any one helps it will be more helpful.

Thanks,
Mathews

Jean-Marie Schwartz
Posts: 1174
Joined: 23 Nov 2004, 04:30

Character width

Post by Jean-Marie Schwartz » 18 Mar 2012, 23:24

I'll let you fine tune the script to match your needs, but you simply have to sum up the width of avery character of selection like this:
tell application "QuarkXPress9.2"
tell document 1
set total_width to 0
repeat with i from 1 to count of characters [b]of selection
[b]set this_width [b]to (width [b]of character i [b]of selection) [b]as real
[b]set total_width [b]to total_width + this_width
[b]end [b]repeat
[b]return total_width
[b]end [b]tell
[b]end [b]tell

EDIT: I see just now you're on v8. Sorry. So no warantee. Please let me know if it works or not.

quarkslave
Posts: 95
Joined: 19 Sep 2008, 04:05

Character width

Post by quarkslave » 19 Mar 2012, 04:47

Hi Jean,
it seems that you with some applescript-expirience can bring me on the right track:
I want to generate a line at a text selection, crossing out the text from lower-left to upper-right.
Our IT has the proxy under a tight restrictment, so I cant browse for a ActionScript reference, but I think with a little help, what variables I can use, would guide me along.
So I have selected text, and I need from this: The lower-left X/Y of the first character in my selection. Is this possible?
If I have that, I can use the height of character to get the next values from the last character. Now I can draw a line from X1/Y1 to X2/Y2
But I cant find out if there are variables/values for each character, how I use them for this.

Jean-Marie Schwartz
Posts: 1174
Joined: 23 Nov 2004, 04:30

Character width

Post by Jean-Marie Schwartz » 19 Mar 2012, 06:07

Well first of all I'm not Scripting_Ace so I'll try to tell you what I know and think about it.
You can get horizontal offset of a character that is its position from the left edge of the text box it's contained in. So you could easily get horizontal offset of the last character of selection.
You can get height of a character that is its size point actually. So you'd just have to mind the upper right corner is not that vertical offset of the baseline.
You can get width of character as you've seen in the previous message.
You can get baseline of text that is the vertical offset from the upper edge of the text box it's in.
I think with all of that you can calculate the different points you need, can't you?
Oh! just to make things clear, variables, in AS language, is sth you set. For example: set my_variable to offset of character 1. You cannot use whatever word as a variable since all the words present in a dictionary are reserved. A value is what is read. For instance: in the previous example, the value of my_variable could be "2,455 mm". Depending on what you are reading, the value could be almost anything (text, string, list, color, number, whatever). A value can be read straight with no need of a variable. So you can get whatever value an application lets AS reading. Sometimes (most of the time), you can set a value and so modify an object (set character 3 of selection to "a"). But sometimes it's R/O (read only).

quarkslave
Posts: 95
Joined: 19 Sep 2008, 04:05

Character width

Post by quarkslave » 20 Mar 2012, 00:21

Hi, thanks for your help, i'm down to this: (sorry, I dont know how to post this like yours formatted)
(* Y1=LOWER LEFT *)
set MyPageOffset to (top of bounds of current box as real)
set myY1 to (baseline of character 1 of selection) as real
set myY1 to (MyPageOffset + myY1)
(* Y2=TOP RIGHT *)
set MyPageOffset to (top of bounds of current box as real)
set myY2 to (baseline of character 1 of selection) as real
set myY2 to (MyPageOffset + myY2)
set TEMPvar to (size of character 1 of selection) as real
set TEMPvar to (((TEMPvar * 0.35275) / 100) * 80)
set myY2 to myY2 - TEMPvar
(* X1 LEFT *)
set MyPageOffset to (left of bounds of current box as real)
set myX1 to (horizontal offset of character 1 of selection) as real
set myX1 to (myX1 + MyPageOffset)
(* X2 RIGHT *)
set MyPageOffset to (left of bounds of current box as real)
set total_width to 0
repeat with i from 1 to count of characters of selection
set this_width to (width of character i of selection) as real
set total_width to (total_width + this_width)
end repeat
set myX2 to (myX1 + total_width)


As you see, I used your snippet and read around in the quark-reference, and after long trynerror I'm at a point where I have my values and I want to draw a linebut have no actual clue how to do it. I tried to puzzle from quarks examplescripts, but I'm not even sure what I'm, doing there. Please take your time and have a look I feel i'm not far away from finishing this veryvery helpful script.
(* DO THE LINE *)
set Point1 to {myX1, myY1}
set Point2 to {myX2, myY2}
tell page (index of page 1 of current box)
set current box to make new line at before current box
with properties {start point:Point1, end point:Point2, width:1, style:solid line, color:red}
end tell


My doubts here are:
I dont know if "line" is the name for the tool, the one below the box-tool.
I dont know whats happening here and why no line is drawed:
tell page (index of page 1 of current box)
set current box to make new line at before current box
dont know how to set the line to a red 0/100/100/0
is it possble to be more flexible and give instead of all line-properties an object-ss for lines?
Maybe its not too difficult to do a check: If object-ss "my line" is present, use it. If not, do a line with standard-properties?

Jean-Marie Schwartz
Posts: 1174
Joined: 23 Nov 2004, 04:30

Character width

Post by Jean-Marie Schwartz » 20 Mar 2012, 01:37

OK, sorry but I haven't check the 1st part of your code. I suppose the different points you need are OK.
As for drawing a line, here is the code :
on MakeLineBox(SP_Y1, SP_X1, EP_Y1, EP_X1) -- SP stands for Start Point; EP stands for End Point my values are numbers and I coerce those to string later on
tell application "QuarkXPress9.2"
tell document 1
make line box at beginning with properties {start point:
{(SP_Y1 as string) & " mm", (SP_X1 as string) & " mm"}, end point:{(EP_Y1 as string) & " mm", (EP_X1 as string) & " mm"}, color:"Black", shade:"100%", width:1, style:dotted line, end caps:right arrow} -- adapt the properties to your needs, check QuarkXPress AS dictionary
end [b]tell
[b]end [b]tell
[b]end MakeLineBox

You [b]cannot set current box to make new line! (The current box is the box that is actually selected in QuarkXPress. The only thing you can do with it is to get properties or to set some.) What you can do is to assign the line a name good for the script itself so you can target the line later on more easily by calling it by its name (set my_line_box to make line box at beginning, and later on in your script you could change that box' properties by telling set properties of my_line_box to {new_properties}). Do you get what I mean?
If you want to apply a color to the line, you must first create it then apply it.As for the Item Styles, I'm not sure it is actually scriptable. Check documentation. HTH.

quarkslave
Posts: 95
Joined: 19 Sep 2008, 04:05

Character width

Post by quarkslave » 21 Mar 2012, 04:34

Thank you for your help. I was busy yesterday doing actually stuff for my employer, but now I've got some time on my hands and want to report how brilliant this is by now.
So, i worked the linedrawing in, superb.
I looked around for item styles, but only found using style spec for paragraphs and chars. Poor Quark seems to ignore a keyfeature here
So I decided, that for our workflow I only need one type of line, so i discarded the item styles.
But the color can differ, so I thought it would be a good idea, to check if a specific color is present ("Linienfarbe Script") and if not, generate it. So none of my collegues should care about having the color.
Depending on the backgroundcolor of our projects, we use sometimes red or magenta or black to cross-out text.
Now, again, I need a little hint, what is wrong here:
if not (exists (color spec ("Linienfarbe Script"))) then
set MYcyan to 0 as integer
set MYmag to 0 as integer
set MYyell to 0 as integer
set MYblk to 0 as integer

display dialog "Which color? CYAN =" default answer "0" buttons {"next"} default button 1
copy the result to MYcyan

-- display dialog "MAGENTA=" default answer "100" buttons {"Weiter"} default button 1
-- copy the result to MYmag
-- display dialog "YELLOW=" default answer "100" buttons {"Weiter"} default button 1
-- copy the result to MYyell
-- display dialog "SCHWARZ=" default answer "0" buttons {"Danke!"} default button 1
-- copy the result to MYblk

make color spec at beginning with properties {name:"Linienfarbe Script", CMYK color value:{MYcyan * 655.35, MYmag * 655.35, MYyell * 655.35, MYblk * 655.35}, separation:true}


The Problem is: When I instead of the dialog hardcode the color in there (CMYK color value:{80 * 655.35,) then it works.
But if I use copy the result to MYcyan and later CMYK color value:{MYcyan * 655.35, the dialog seems to get a wrong type of var like string or something. I know a bit from my lost turbopascale expierience, but I don't get it in Quark.

Can you find, why I cant use the dialog-result for the color?

It's not perfect, but its getting there. Some things you could wrap your head around, which would be my next questions:
I was on a double-sides doc when I tested my script today, and the Line was generated on page 1. Not page 4 I was on. And if I use a doublesided doc, the line will be generated on the left page instead of the right. Maybe the same problem here.

Jean-Marie Schwartz
Posts: 1174
Joined: 23 Nov 2004, 04:30

Character width

Post by Jean-Marie Schwartz » 21 Mar 2012, 05:06

Glad it works! Its always a great joy to see a script running properly, isnt it?
Then 2 things: The result of a dialog contains 2 elements. The hidden error is: Cant get result of {text returned:"82", button returned:"OK"}. So you need to extract the value of the field like this:set MyResult to text returned of (display dialog "Magenta = ?" default answer {""}). Then you must also coerce the text returned to an integer (better I think) or a real, like this:set MyResult to text returned of (display dialog "Magenta = ?" default answer {""}) as integer
This said, since you inserted a button named "Next", you should also insert an action related to that button in case it is pressed by the User. (Isn't it what you actually want? Hum?) So you'd need to add sth like:if button returned [b]is "OK" [b]then I let you decide where to add it and how to handle it all. (I think you should rather set a variable first to the dialog itself then separate both results, the text reurned and the button returned.) HTH.

quarkslave
Posts: 95
Joined: 19 Sep 2008, 04:05

Character width

Post by quarkslave » 21 Mar 2012, 06:16

So, im nearly donei guess.
I would post the code here nicly formatted like you did, how is it possible? Copy/paste from AS-Editor to Firefox doesnt do the trick.
So, before I post my result and paste this to my workmates, i want to iron some kinks out.
The Dialog:
I just want a easy way to read your four values for cmyk. Hitting enter will use the default-value (0,100,100,0 a bright red) and typing will use your numbers. So I use 4 dialogs after another to phish your colors. So I dont really need an event handler for this. Or do I?
But 1 Thing: When I close a dialog by the red X, Quark will crash, which would be fatal. This has to go.
When I think about it: Is it somewhat easy to repeat a dialog until the value is in a specific range and is a specific type of value, in my example 0100?
The Line:
Is missplaced if my document is doublesided or has more than 1 page. I didnt stumble upon this because my testdoc had only one page.
The Wishlist:
When I highlight characters over the end of the line, breaking around, and start my script, the carriage return is not thought about. Is there a way to get to know if my selected text is overspanning the textrow-end?Therefor drawing the line only to the end of the textrow?


I dont know how I could thank you enough, seeing this script come together makes mefeeling awesome somehow (not without your help!).
So, maybe we could iron out the crash and the misplacement, and you would be my hero!

Jean-Marie Schwartz
Posts: 1174
Joined: 23 Nov 2004, 04:30

Character width

Post by Jean-Marie Schwartz » 21 Mar 2012, 23:00

quarkslave wrote:formatted like you did, how is it possible? Copy/paste from AS-Editor to Firefox doesnt do the trick.

What I do is copy from ScriptDebugger and paste in Text Edit (RTF), then copy from there and paste in Safari under Firefox User Agent. Simple, isn't it?
The Dialog:
I just want a easy way to read your four values for cmyk. Hitting enter will use the default-value (0,100,100,0 a bright red) and typing will use your numbers. So I use 4 dialogs after another to phish your colors. So I dont really need an event handler for this. Or do I?

I'm afraid you do. Simple things are often the result of very complex code behind the scenes. What you must code is the action resulting from hitting the "Next" button. So you must handle that with a if block: if button returned is "Next" then else end if. Keeping in mind the last dialog has no "Next" button, you'll have to handle that dialog differently. (There might be several ways of handling all that.)
When I close a dialog by the red X, Quark will crash, which would be fatal.

You probably need to add a return instruction somewhere in the code or an error handler, but I'm not sure as why Quark would crash on closing a window.
When I think about it: Is it somewhat easy to repeat a dialog until the value is in a specific range and is a specific type of value, in my example 0100?

Sure! you'll need to check the text returned via a if block: if (0 less than (MyValue as integer)) and ((MyValue as integer) less than 100) then -- where MyValue is text returned of the dialog
Test this:
set Check to "0"
repeat while Check is "0"
set MyValue to text returned of (display dialog "Please type the value for Cyan:" default answer "")
if (0 MyValue [b]as integer)) [b]and ((MyValue [b]as integer)
[b]set Check [b]to "1"
[b]end [b]if
[b]end [b]repeat


[b]beep 2

The Line:
Is missplaced if my document is doublesided or has more than 1 page. I didnt stumble upon this because my testdoc had only one page.

You probably need to get the right page number you're on. Also add the page width if you're on a right-hand page. (Depending on the result you get from the get statements.)
The Wishlist:
When I highlight characters over the end of the line, breaking around, and start my script, the carriage return is not thought about. Is there a way to get to know if my selected text is overspanning the textrow-end?Therefor drawing the line only to the end of the textrow?

Again, you have to insert a check handler: if count of lines of the selection is greater than 1 then or sth like that.

Post Reply

Return to “QuarkXPress 8, 9 & 10: AppleScript”