%!PS % AUTO TRACKING & AUTO ENTRY ACROBAT PDF LINKS % ============================================ % by Don Lancaster % Copyright c 2002 by Don Lancaster & Synergetics, Box 809, Thatcher, AZ, 85552 % (928) 428-4073 Email: don@tinaja.com Website: http://www.tinaja.com % Consulting services available http://www.tinaja.com/info01.html % All commercial rights and all electronic media rights ~fully~ reserved. % Linking usually welcome. Reposting expressly forbidden. Version 1.5 % Sourcecode and technique to allow Acrobat to auto enter and auto % track url links under direct program control. % IMPORTANT NOTE: Don Lancaster's file gonzo.ps is required for this program. % After obvious location mods, uncomment ONE of the following two lines: (C:\\windows\\desktop\\gonzo\\gonzo.ps) run % use internal gonzo % (A:\\gonzo.ps) run % use external gonzo % NOTE THAT ALL PS FILENAME STRINGS !!!DEMAND!!! DOUBLE REVERSE SLASHES. % GONZO20A Guru Gonzo PostScript power tools (Interim release) % Includes gonzo justification and layout utilities. % Copyright c 1990, 1996, 2001 by Don Lancaster and Synergetics, Box 809, % Thatcher Arizona, 5552 (928) 428-4073 don@tinaja.com support % via http://www.tinaja.com All commercial rights and all electronic % media rights **FULLY** reserved. Reposting is expressly forbidden. %%%%%%%%%%% links menu directory %%%%%%%%%%%% % This code locks pdfmark commands out of a PostScript printer. /pdfmark where {pop}{userdict /pdfmark /cleartomark load put} ifelse % /surl "start url" marks the beginning of a text sequence to be urled. % It also paints the text blue... /surl {mark /blue cvx 0.33 /setgray cvx % change text to blue /currentpoint cvx % remember box start /urly /exch cvx /store cvx /urlx /exch cvx /store cvx ] cvx % complete deferred command printlist exch 3 index exch put % stuff into gonzo printlist exch 1 add exch % increment gonzo list count } def % /eurl "end url" unmarks the end of a text sequence and sets up % the pdfmark needed to define the Acrobat web link. /eurl {mark % start deferred proc exch % position url string % /black cvx 0 /setgray cvx % turn blue marker off % maintextcolor /setrgbcolor cvx % reset to main text color??? /aqua cvx /black cvx /makeurl cvx % defer call of url builder ] cvx % complete deferred proc printlist exch 3 index exch % stuff into gonzo printlist put exch 1 add exch % increment gonzo list count } def % /makeurl generates the pdfmark, receiving a {(urlstring) makeurl}. % Note that it is not called until formatted printlist time... /urlover 0.2 def % fraction of hot area over bounds /makeurl { /cururlname exch store % save the url string mark % start pdfmark currentfont /ScaleMatrix get 3 get /fsize exch store % guess height /Rect [ urlx fsize urlover mul sub % set box left x urly fsize urlover mul sub % set box left y currentpoint exch fsize urlover mul add exch fsize add ] /Border [ 0 0 0] % [0 0 0 ] = none; [0 0 2] = debug /Color [ .7 0 0 ] /Action <> /Subtype /Link /ANN % annotation type pdfmark % call pdf operators } def % /makeurlx generates the box specific pdfmark, receiving % a {(urlstring) makeurl}. % Note that it is not called until formatted printlist time... /makeurlx { /cururlnamex exch store % save the url string mark % start pdfmark /Rect [ xpos % set box left x ypos 0.9 sub % set box left y xpos 2.8 add % box right x ypos 0.9 sub 2.8 add % box right y ] /Border [ 0 0 0] % [0 0 0 ] = none; [0 0 2] = debug /Color [ .7 0 0 ] /Action <> /Subtype /Link /ANN % annotation type pdfmark % call pdf operators } def /maintextcolor {0 0 0 } def % text link specific data -- use dictionary instead below /tinaja {(http://www.tinaja.com) eurl} def /cubic01 {(http://www.tinaja.com/cubic01.asp) eurl} def /hack62 {(http://www.tinaja.com/glib/hack62.pdf) eurl} def /post01 {(http://www.tinaja.com/post01.asp) eurl} def /increment {(http://www.tinaja.com/text/bezgen3.html) eurl} def /interpolate {(http://members.bellatlantic.net/~vze2vrva/design.html) eurl } def /info01 {(http://www.tinaja.com/info01.asp) eurl} def /bezmath {(http://www.tinaja.com/text/bezmath.html) eurl } def /table {(http://www.tinaja.com/psutils/imtable.psl) eurl } def /maildon {(mailto:don@tinaja.com) eurl} def % dictionary method << %zzzzz %% these are urls only... /adobe (http://www.adobe.com) /netscape (http://www.netscape.com) /gallypsl (http://www.tinaja.com/galley1.psl) /gallypdf (http://www.tinaja.com/galley1.pdf) /atn5150 (http://partners.adobe.com/asn/developer/acrosdk/docs/createpdfapi/pdfmarkReference.pdf) /nutour (http://www.tinaja.com/bargains/nutour02.pdf) /nutoursource (http://www.tinaja.com/bargains/nutour02.psl) /bwhistle (http://www.tinaja.com/glib/bwhistle.pdf) /gonzo1 (http://www.tinaja.com/post01.asp#gonzo) /acrob01 (http://www.tinaja.com/acrob01.asp) /barg01 (http://www.tinaja.com/barg01.asp) /weblib01 (http://www.tinaja.com/weblib01.asp) /z1 (http://www.tinaja.com/bargains/thumb/albradz2.jpg) /z2 (http://www.tinaja.com/bargains/sbtesteq.asp) /z3 (http://www.tinaja.com/images/bargs/albrad02.jpg) /z4 (http://www.tinaja.com/bargains/thumb/tutenaz2.jpg) /z5 (http://www.tinaja.com/bargains/sbphone.asp) /z6 (http://www.tinaja.com/images/bargs/tutena02.jpg) /sourceme (http://www.tinaja.com/glib/gallery.psl) /sourceme2 (http://www.tinaja.com/glib/autourl.psl) >> {mark exch /eurl cvx ] cvx def} forall %%%%%%%%%%%%%%%% New colorizer patches %%%%%%%%%%%%%%%%%% /boxgrays 0.899 def /grayshade boxgrays def /mastergray boxgrays def /staytint {0.33 setgray} def /staytint1 {0.25 setgray} def /showadgrays true def /red {0 settint} def /Zmacro {staytint /ypos ypos 2 add def 72 300 div setlinewidth xpos ypos moveto txtwide 0 rlineto stroke /ypos ypos -2 add def tintoff} def % hair rule /amacro {(zy0) stringmacro /ypos ypos ypara add def 0.33 setgray } def % start drop cap /bmacro {(iFy1) stringmacro /ypos ypos ypara add def black} def % finish drop cap % Gonzo character colorizer /blueon {mark /blue cvx 0.33 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /blueoff {mark /beige cvx 0 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton {mark 0.33 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1 {mark 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1b {mark beige cvx % try for aqua after url??? 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1a {mark /aqua cvx % try for aqua after url??? 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1p {mark /burple cvx % try for aqua after url??? 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1r {mark /red cvx % try for aqua after url??? 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1b {mark /beige cvx % try for beige after url??? 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tintoff {mark 0 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def %%%%%%%%%%%%%% COMPACT VERSION OF COLORIZER II %%%%%%%%%%%%%%%%%%%%%% /settint {dup /currenttint exch store 5.999 mul dup floor cvi /&cbar exch store dup floor sub /&cwt exch store [ {/setgray [ /dup cvx 0.3 &cwt 0.59 mul add /ge cvx [1 /exch cvx &cwt 0.59 mul 0.30 add /sub cvx 1 &cwt sub 0.59 mul 0.11 add /div cvx /dup cvx 1 &cwt sub /mul cvx &cwt /add cvx /exch cvx ] cvx [ &cwt 0.59 mul 0.3 add /div cvx /dup cvx &cwt /mul cvx 0] cvx /ifelse cvx /setrgbcolor cvx] cvx /def cvx} {/setgray [/dup cvx 0.59 1 &cwt sub 0.3 mul add /ge cvx [1 &cwt sub 0.3 mul 0.59 add /sub cvx &cwt 0.3 mul 0.11 add /div cvx /dup cvx &cwt /mul cvx 1 &cwt sub /add cvx /exch cvx 1 /exch cvx] cvx [1 &cwt sub 0.3 mul 0.59 add /div cvx /dup cvx 1 &cwt sub /mul cvx /exch cvx 0] cvx /ifelse cvx /setrgbcolor cvx] cvx /def cvx} {/setgray [/dup cvx 0.59 &cwt 0.11 mul add /ge cvx [&cwt 0.11 mul 0.59 add /sub cvx 1 &cwt sub 0.11 mul 0.30 add /div cvx /dup cvx 1 &cwt sub /mul cvx &cwt /add cvx 1 /exch cvx] cvx [0 /exch cvx &cwt 0.11 mul 0.59 add /div cvx /dup cvx &cwt /mul cvx] cvx /ifelse cvx /setrgbcolor cvx] cvx /def cvx} {/setgray [/dup cvx 0.59 1 &cwt sub mul 0.11 add /ge cvx [1 &cwt sub 0.59 mul 0.11 add /sub cvx &cwt 0.59 mul 0.30 add /div cvx /dup cvx &cwt /mul cvx 1 &cwt sub /add cvx 1] cvx [0 /exch cvx 1 &cwt sub 0.59 mul 0.11 add /div cvx /dup cvx 1 &cwt sub /mul cvx /exch cvx] cvx /ifelse cvx /setrgbcolor cvx] cvx /def cvx} {/setgray [/dup cvx 0.11 &cwt 0.30 mul add /ge cvx[&cwt 0.30 mul 0.11 add /sub cvx 1 &cwt sub 0.30 mul 0.59 add /div cvx /dup cvx 1 &cwt sub /mul cvx &cwt /add cvx /exch cvx 1] cvx [ &cwt 0.30 mul 0.11 add /div cvx /dup cvx &cwt /mul cvx /exch cvx 0 /exch cvx ] cvx /ifelse cvx /setrgbcolor cvx ] cvx /def cvx} {/setgray [ /dup cvx 0.30 1 &cwt sub 0.11 mul add /ge cvx[ 1 /exch cvx 1 &cwt sub 0.11 mul 0.30 add /sub cvx &cwt 0.11 mul 0.59 add /div cvx /dup cvx &cwt /mul cvx 1 &cwt sub /add cvx ] cvx [ 1 &cwt sub 0.11 mul 0.30 add /div cvx /dup cvx 1 &cwt sub /mul cvx 0 /exch cvx] cvx /ifelse cvx /setrgbcolor cvx ] cvx /def cvx} ] &cbar get exec exec} bind def /beige {0.10 settint} def % examples of convenience operators /aqua {0.52 settint} def /blue {0.67 settint} def /lime {0.44 settint} def /burple {0.75 settint} def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /guru { gonzo begin ps.util.1 begin printerror nuisance begin} def % guru % activate gonzo utilities 50 50 10 setgrid % create grid % 56 61 showgrid /setpagefonts { /cstretch 0.015 def /sstretch 0.015 def /font0 /StoneSans-Bold 1.6 gonzofont /font1 /StoneSans 0.95 gonzofont /font4 /StoneSans 0.85 gonzofont /font3 /StoneSans-Bold 0.85 gonzofont /font8 /StoneSans-Bold [0.65 0 0 0.65 0 0.4] gonzofont /txtwide 36 store /yinc 1.2 store /kern 0.1 store /pm 1.5 store /tabs [7 -2] store aqua 0.33 setgray font1 black font2 /amacro { mark /aqua cvx 0.33 /setgray cvx ] cvx printlist exch 3 index exch % stuff into gonzo printlist put exch 1 add exch } def /bmacro { mark /black cvx ] cvx printlist exch 3 index exch % stuff into gonzo printlist put exch 1 add exch } def /shiftin {xpos /xposhold exch store /xpos xpos 3 add store} def /shiftout {/xpos xposhold store} def /texttop 51 store /textleft 3 store /fmacro % try and fake | {mark /gsave cvx /currentpoint cvx /moveto cvx 0.1 /setlinewidth cvx 0 0.65 /rlineto cvx /stroke cvx /grestore cvx ] cvx printlist exch 3 index exch put % stuff into gonzo printlist exch 1 add exch % increment gonzo list count } def } def setpagefonts % -2 50.5 (optional header here \274) cl aqua 0.33 setgray font0 20 47.3 0.7 add ("Auto-entry" and "Auto-tracking") cc 20 45.3 0.7 add (Acrobat PDF web Links) cc black font2 textleft 43 (|3Don Lancaster Synergetics, Box 809, Thatcher, AZ 85552 |/surl http://www.tinaja.com|/tinaja |/surl don@tinaja.com|/maildon (928) 428-4073 |h |a|0I|b|1|jt is a fairly simple matter to add a web url link to an |/surl |3Acrobat|1|/acrob01 PDF document. Simply get into full Acrobat, select your link area, and enter your url. Then resave. |h The problems come about when you have hundreds or thousands of links in your document, when you want to link from a master data base list, when you want the editable links to look and behave like |4HTML|1, or when you want the links to automatically "follow" or track any edit repositioning or font size changes. |h I've long had a fast, simple, and convenient |/surl |3PostScript|1|/post01 fully automatic smart-font entry and autotracking PDF linking code as part of my |/surl |3Gonzo Utilities|1|/gonzo1 . What I thought I'd do here is show you exactly what these routines do and how they work. Chances are the same or similar concepts can be applied to your own raw PostScript formatting, or to any content editor or layout program in which you have at least some control over plug-ins, macros, or sourcecode. |h Let's start with an example of how your text gets marked to include a url\274 |3|/shiftin |h|/burple |/staytint1 \274part of my |f|j/surl |f|j3Gonzo Utilities|j|j|f|j1|j|f|j/gonzo01 . What\274 |h|/shiftout |/aqua |/black |1In this case, |/tinton1 |f|j|3/surl |1|/tintoff or "start url" and its trailing space tells Gonzo that "a url link is about to begin. The |/tinton1 |3|f|j3|1|/tintoff calls for a font change to the bold font needed for the url. The |j|j|/tinton1 |3|f|j1|1 |/tintoff returns us to normal text. And the |/tinton1 |f|j|3/gonzo01|1|/tintoff and its trailing space calls for a specific url linking. |h Your url linkings can come from a data base, from a list, or be generated on the fly. Each url linking proc must have a unique name. The simplest and most obvious way is to just do it\274 |3|/shiftin |h|/burple |/staytint1 /gonzo1 {(|jhttp://www.tinaja.com/post01.asp#gonzo|j) eurl } def |h|/shiftout |/aqua |/black |1Which passes the url name string to a linking proc called |/tinton1 |3eurl|1|/tintoff or "end url" that we will look at shortly. Known or common url's can be precombined into an external or internal file. Should you have lots of urls, using a "dictionary" or some "batch process" method can be cleaner and uses fewer characters\274 ) cl black beige 0.35 setgray 21 -2.5 (|3\320|j1|j\320) cc aqua 0 57 mt line1 40 r % temp align showpage %% start page two 50 50 10 setgrid % create grid setpagefonts /tabs [16.5] store textleft texttop (|3|/shiftin |h|/burple |/staytint1 << /acrob01 (http://www.tinaja.com/acrob01.asp) /barg01 (http://www.tinaja.com/barg01.asp) /gonzo01 (http://www.tinaja.com/post01.asp#gonzo) . . . . . . /weblib01 (http://www.tinaja.com/weblib01.asp) |h >> {|jmark exch /eurl cvx ] cvx def} forall |h|/shiftout |/aqua |/black |1OK. We now have a way to mark text where we want a link to appear. And have a list of places for each individual url to go. We need three routines to complete the process, |/tinton1 |3surl|1|/tintoff to start the entry and |/tinton1 |3eurl|1|/tintoff to complete the url generation. Followed by a |/tinton1 |3makeurl|1|/tintoff that does the actual Acrobat stuff. Here's |/tinton1 |3surl|1|/tintoff \274 |3|/shiftin |h|/burple |/staytint1 |h /surl {mark /blue cvx 0.33 /setgray cvx |t% change text to blue /currentpoint cvx |t % remember box start /urly /exch cvx /store cvx /urlx /exch cvx /store cvx ] cvx |t% complete deferred command |h printlist exch 3 index exch put |t% stuff into gonzo printlist exch 1 add exch |t% increment gonzo list count } def |h|/shiftout |/aqua |/black |1All |/tinton1 |3surl|1|/tintoff does is change the link color and font. It then remembers the currentpoint at which the linked text message starts. But this gets subtle and tricky in a big hurry. Why? Because you need to known the text start currentpoint |/tinton1 |3at imaging |/tinton1 time|1|/tintoff . The reason is that |/surl |3Gonzo|1|/gonzo1 or most other typical layout programs will analyze its lines on the first pass and then only put them down after text justification and repositioning calculations are complete. Thus, |/tinton1 |3the currentpoint calculation must |/tinton1 be deferred till actual imaging takes place|1. |h |1In the case of Gonzo, we create an executable color change and "find the currentpoint" proc and stuff it into the printlist where it will execute at the proper time. Exact details will vary with your choice of layout code. |h |1We have thus saved the position of the start of the url linking message with |/tinton1 |3surl|1|/tintoff . Specifically, we have two new start coordinates named |/tinton1 |3urlx|1|/tintoff and |/tinton1 |3urly|1|/tintoff that mark the exact url text start positions. On to |/tinton1 |3eurl|1|/tintoff \274 |3|/shiftin |h|/burple |/staytint1 /eurl {|jmark |t% start deferred proc exch |t% position url string /aqua cvx /black cvx |t% reset to main text color /makeurl cvx |t% defer call of url builder ] cvx |t% complete deferred proc |h|/shiftout |/aqua |/black ) cl black beige 0.35 setgray 21 -2.5 (|3-|j2|j-) cc aqua 0 57 mt line1 40 r % temp align showpage %% start page three 50 50 10 setgrid % create grid setpagefonts /tabs [17.5 ] store textleft texttop (|3|/shiftin |h|/burple |/staytint1 printlist exch 3 index exch |t% stuff into gonzo printlist put exch 1 add exch |t% increment gonzo list count } def |h|/shiftout |/aqua |/black |1This is somewhat similar to our previous code. All it does is change the text color back and pass a url string on to |/tinton1 |3makerurl|1|/tintoff . As before, execution get deferred until imaging time by joining the Gonzo printlist. |h At this point, we need an ordinary |/surl |3PostScript|1|/post01 proc named |/tinton1 |3makerurl|1|/tintoff to do the actual url magic. Such a proc relies heavily on the |/tinton1 |3PDFmark|1|/tintoff operator described in depth in |/surl |3ATN 5150|1|/atn5150 from |/surl |3Adobe|1|/adobe . Any layout or editing program capable of sending PostScript code to Distiller should be able to use (or least adapt) what follows. |h |1|/tinton1 |3makerurl|1|1|/tintoff works with seven pieces of information: The |/tinton1 |3urlx|1|/tintoff and |/tinton1 |3urly|1|/tintoff position info for the start of the url caption; the |/tinton1 |3currentpoint|1|/tintoff info that holds the position for the end of the url caption; the font height info extractable from |/tinton1 |3currentfont|1|/tintoff ; a |/tinton1 |3urlover|1|/tintoff constant that somewhat magnifies the hot box; and the url name string found on the stack top. Here's some code\274 |3|/shiftin |h|/burple |/staytint1 /urlover 0.2 def |t% fraction of hot area over bounds |h /makeurl { /cururlname exch store |t% save the url string mark |t% start pdfmark |h currentfont /ScaleMatrix get 3 get /fsize exch store |t% guess font height |h /Rect [ urlx fsize urlover mul sub |t % set box left x urly fsize urlover mul sub |t % set box left y currentpoint exch fsize urlover mul add exch fsize urlover mul add ] /Border [ 0 0 0] |t% [0 0 0 ] = none; [0 0 2] = debug /Color [ .7 0 0 ] /Action <> /Subtype /Link /ANN |t% annotation type pdfmark |t% call pdf operators } def |h|/shiftout |/aqua |/black |1The |/tinton1 |3cururlname|1|/tintoff is first grabbed. A guess is made at the font height by using the fourth value in the font's |/tinton1 |3ScaleMartix|1|/tintoff . This value is then expanded by |/tinton1 |3urlover|1|/tintoff to make a hot box somewhat larger than the actual text itself, extending slightly on all four sides. An invisible hot box is chosen, giving the illusion of an HTML link. ) cl black beige 0.35 setgray 21 -2.5 (|3-|j3|j-) cc aqua 0 57 mt line1 40 r % temp align showpage %% start page four 50 50 10 setgrid % create grid setpagefonts /tabs [17.5 ] store textleft texttop (|1There are one or two minor glitches: If a multi-word url extends over more than one line, you can either recode the second line or else activate each word as a separate url. With Gonzo, you also may have to add some padding end-of-line spaces to make sure |/tinton1 |3/surl|1|/tintoff ends up on the right line. |h |1Note that the hot boxes automatically move around on the page as text is lengthened or shortened, and that they automatically scale as font size increases or decreases. As well as automatically repositioning on fill- or other justification changes. No post-Distilling treatment is usually needed. |h Sourcecode for this document is |/surl |3Found Here|1|/sourceme2 . |h |1Additional consulting services available per |/surl |3www.tinaja.com/info01.asp|1|/info01 . ) cl black beige 0.35 setgray 21 -2.5 (|3-|j4|j-) cc aqua 0 57 mt line1 40 r % temp align showpage %%%%%%%%%%%%%%%%%%%% % EOF