1 Reply Latest reply on May 11, 2003 3:39 AM by (Dave_Saunders)

    [AS] Fractions script

      A very long time ago I adapted a "Make Fractions" written by Sal Sogohian for Quark.

      There are a variety of things that can be improved upon. But as it is it works

      -peter

      (*
      
      *** User modifiable variables
      useFractionGlyphs has two possible values:
      none:      *fractions are created by modifying the attributes of the actual text
      normal:      *fractions that have glyphs in normal fonts are replaced with those glyphs
                *other fractions are created by modifying the attributes of the actual text
      *)
      property useFractionGlyphs : "normal" -- one of these values:"none","normal"
      -- *** End user modifiable variables

      -- When replacing a fraction that contains mulitple characters with one glyph,
      -- then the offsets we calculate when we start become incorrect. This
      -- propery keeps track of the difference in offset.
      property extraOffset : 0

      -- This maps the fractions found in all fonts and their unicode value
      property fractionGlyphMap : {¬
           {"1/4", "00BC"}, ¬
           {"1/2", "00BD"}, ¬
           {"3/4", "00BE"} ¬
                }

      tell application "InDesign 2.0.1"
           set extraOffset to 0
         
           -- Make sure a text box is selected
           set theSelection to selection
           if (count of theSelection) is 0 or class of item 1 of theSelection is not text frame then
                beep
                tell me to display dialog "Please select a text box." buttons {"OK"} default button 1
                return
           end if
         
           set theFrame to item 1 of selection
           tell theFrame --only work on the selected frame
              
                -- get the indicess of all the slash characters
                set slashCharacterList to (index of (every character whose contents is "/")) as list
                if slashCharacterList is {} then
                     tell me to display dialog "No fractions in this text flow to format."
                     return
                end if
              
                set theCounter to 0 -- keep track of how many factions we process
                repeat with i from 1 to the number of items in slashCharacterList
                     set slashCharIndex to (item i of slashCharacterList) as number
                   
                     set wordBefore to object reference of word 1 of character (slashCharIndex - extraOffset - 1) of theFrame
                     set wordAfter to object reference of word 1 of character (slashCharIndex - extraOffset + 1) of theFrame
                   
                     tell me to set IsFraction to VerifyIsFraction(wordBefore, wordAfter)
                   
                     tell me to set replacedWithGlyphs to HandleUseFractionGlyphs(wordBefore, wordAfter)
                   
                     if IsFraction is true then
                          -- if we already replaced it with a built-in fraction, just increment the counter
                          if replacedWithGlyphs is true then
                               set theCounter to theCounter + 1
                          else -- If this is a fraction, and we haven't already replaced with a built in fraction
                               -- Handle the slash
                               tell character (slashCharIndex - extraOffset)
                                    set contents to ASCII character 218 --virgule
                                    set kerning value to -15
                               end tell
                             
                               -- Handle the first character before the slash
                               tell character (slashCharIndex - extraOffset - 1)
                                    set leadingSize to leading
                                    if leadingSize = "auto" then
                                         set mySize to point size
                                         set myAutoPct to auto leading
                                         set leadingSize to mySize * (myAutoPct * 0.01)
                                    end if
                                  
                                    set fontSize to point size * 0.5
                                    set point size to fontSize
                                    set baseShift to leadingSize * 0.3
                                    set baseline shift to baseShift
                                    if contents is in {"3", "1", "5"} then
                                         set kerning value to -30
                                    else
                                         set kerning value to -15
                                    end if
                               end tell
                             
                               -- Handle the first character after the slash
                               tell character (slashCharIndex - extraOffset + 1)
                                    set point size to fontSize
                                    if contents is in {"1"} then
                                         set kerning value to -10
                                    end if
                               end tell
                             
                               -- Handle the second character before the slash
                               tell character (slashCharIndex - extraOffset - 2)
                                    set point size to fontSize
                                    set baseline shift to baseShift
                                    set kerning value to -5
                               end tell
                             
                               -- Handle the second character after the slash
                               tell character (slashCharIndex - extraOffset + 2)
                                    set point size to fontSize
                               end tell
                               --beep
                               set theCounter to theCounter + 1
                          end if
                     end if
                end repeat
              
                beep 2
                tell me to display dialog "Scan complete." & return & theCounter & ¬
                     " fractions formatted." buttons {"OK"} default button 1
           end tell
      end tell

      (*
      VerifyIsFraction takes the characters before and after a slash and
      determines whether this meets the criteria for a fraction
      *)
      on VerifyIsFraction(wordBefore, wordAfter)
           tell application "InDesign 2.0.1"
                -- we only support fractions with up to 2 digits for the numerator/demoninator
                if (count of characters of wordBefore) > 2 or (count of characters of wordAfter) > 2 then return false
              
                -- To qualify as a fraction, all the charactere of the numerator/demoninator must be numbers
                set characterList to every character of wordBefore & every character of wordAfter
                repeat with oneCharacter in characterList
                     if oneCharacter is not in {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"} then return false
                end repeat
              
                -- if we got this far, then it all checks out
                return true
           end tell
      end VerifyIsFraction

      (*
      HandleUseFractionGlyphs takes the characters before and after a slash and
      if they match 1/4, 1/2 or 3/4, then they are replaced by the unicode value
      for the appropriate glyph
      *)
      on HandleUseFractionGlyphs(wordBefore, wordAfter)
           tell application "InDesign 2.0.1"
                if useFractionGlyphs is "normal" then
                     repeat with oneFractionMap in fractionGlyphMap
                          if contents of wordBefore is item 1 of item 1 of oneFractionMap and contents of wordAfter is item -1 of item 1 of oneFractionMap then
                               tell me to HandleOneGlyph(wordBefore, wordAfter, "<" & item 2 of oneFractionMap & ">")
                               return true
                          end if
                     end repeat
                end if
                return false
           end tell
      end HandleUseFractionGlyphs

      (*
      HandleOneGlyph is called from HandleUseFractionGlyphs. It takes the
      characters before and after a slash and
      a unicode value for the replacement glyph.
      It replaces thefraction with the unicode value
      and updates the extraOffset property
      *)
      on HandleOneGlyph(wordBefore, wordAfter, unicodeChar)
           tell application "InDesign 2.0.1"
                set shouldReplace to true
              
                set theParent to parent of wordBefore
                set wordBeforeIndex to index of wordBefore
                set wordAfterIndex to index of wordAfter
              
                set contents of text from character wordBeforeIndex to character wordAfterIndex of theParent to unicodeChar
              
                set extraOffset to extraOffset + 2
           end tell
      end HandleOneGlyph