Search content:

 

Personal Menu
Username:
Password:
Save password

Become a member

Forgot Password?

 

Don't miss these
DirectInteraction Xtra.
Truques e Dicas
Import Linked Bitmaps
VBScript Xtra / ActiveCompanionSet
cXtraCD
Set Static Property of a Flash Member
Fake Drag Bar - Stage
SpellChecker
Check and launch dialup
IPIX
MediaMacros Xtras Mall
 

 

 

Behavior CSS Class

Added on 3/25/2004

 

Compatibilities:
D6_5 D7 D8 D8_5 D9 Mac Parent PC Shockwave

Required Xtras:
PRegEx

This item has not yet been rated

Author: fluxus

Parent script for parsing css-code (as string or as external file) and applying this style to a tagged text (html or custom tags) which will result in a text member formatted accordingly

Download PC Source
--****************************************************************************
-- Software: CSS CLASS
-- Version:  0.2 (pre-alpha)
-- Date:     2004/03/16
-- Author:   Valentin Schmidt (script uses some code from John Dowdell's html-parser
--           and Thomas Björk's php css-parser class)
-- homepage: http://staff.dasdeck.de/valentin/lingo/css_class/
-- Contact:  valentin@dasdeck.de
-- License:  Freeware
--
-- Requirements/Dependencies:
-- - fileIO Xtra for opening external css-files
-- - PRegEx Xtra (or DMX2004) for removing comments (and speeding up other search&replace actions)
--
-- You may use and modify this software as you wish.
--****************************************************************************
property pCss

property pSrcStr
property pTextMem
property pCurrentChunk
property pDefaultStyle -- applied to all text if not overwritten by css
property pStyleStack   -- used for nested tags
property pTagStack     -- used for nested tags
property pIsXHTML      -- tagged text is (x)html

property pRegExFlag    -- RegExp available
property pPRegExFlag   -- PRegEx Xtra available
property pJsRegExFlag  -- RegExp available via JavaScript (DMX2004 or newer)

property pLink


--**************************************
-- PUBLIC
--**************************************

----------------------------------------
--
----------------------------------------
on new me
  pCss=[:]
  pDefaultStyle=["font-family":"Arial","font-size":12,"color":"#000000","text-align":"left","white-space":"pre"] --"line-height":14
  pIsXHTML=FALSE
  
  -- check for utilities-script
  if member("UTILITIES").type<>#script then
    alert("CSSParser needs movie-script 'UTILITIES'!")
    halt()
  end if
  
  -- check for RegExp (PRegEx Xtra or DMX2004)
  pPRegExFlag=xtraPresent("PRegEx")
  if (NOT pPRegExFlag) AND float((the environment).productVersion)>=10 then
    if member("~regexp").memberNum<1 then
      s=new(#script)
      s.name="~regexp"
      s.scripttype=#movie
      s.scriptsyntax=#javascript
      s.scripttext="function _js_RegExReplace(s,pat,rep){return s.replace(RegExp(pat,'g'),rep);}"
    end if
    pJsRegExFlag=1
  end if
  
  pRegExFlag=(pPRegExFlag OR pJsRegExFlag)
  if NOT pRegExFlag then put "Warning: No search&replace with regular expressions available!" -- Script won't remove comments!"
  
  return me
end

----------------------------------------
-- replaces DefaultStyle with given cssStyle
-- cssStyle: proplist, e.g. ["font-family":"Arial","font-size":12,"color":"#000000"]
----------------------------------------
on setDefaultStyle (me, cssStyle)
  pDefaultStyle=cssStyle
end

----------------------------------------
-- adds cssStyle to DefaultStyle (and replaces all identical props)
-- cssStyle: proplist, e.g. ["font-family":"Arial","font-size":12,"color":"#000000"]
----------------------------------------
on addDefaultStyle (me, cssStyle)
  cnt = cssStyle.count
  repeat with i = 1 to cnt
    pDefaultStyle[cssStyle.getPropAt(i)]=cssStyle[i]
  end repeat
end

----------------------------------------
-- parses css file
----------------------------------------
on parseCSSFile (me, cssFile)  
  me.parseCSS(readTxtFile(cssFile))
end

----------------------------------------
-- parses css string
----------------------------------------
on parseCSS (me, cssStr)
  
  -- Remove comments (needs PRegEx Xtra or DMX2004)
  if pRegExFlag then
    cssStr=me._regReplace(cssStr, "/*.+?*/(
|
)*","")
  end if
  
  parts = explode("}",cssStr)
  parts.deleteAt(parts.count)
  
  repeat with part in parts
    l=explode("{",part)
    keyStr  = trim(l[1])
    codeStr = trim(l[2])
    
    keys=explode(",", keyStr)
    repeat with aKey in keys
      if aKey.length>0 then
        if pRegExFlag then
          aKey = me._regReplace(aKey, "(
|
)", "")
        else
          aKey = str_replace(numtochar(10), "", aKey)
          aKey = str_replace(numtochar(13), "", aKey)
        end if
        me._addKey(aKey,codeStr)
      end if
    end repeat
  end repeat
end

----------------------------------------
-- returns css text for given key (or empty string, if key doesn't exist)
----------------------------------------
on getKey (me, aKey)
  aKey = strtolower(aKey)
  
  l=explode(":",aKey)
  tag=l[1]
  if l.count>1 then subtag=l[2]
  else subtag=""
  
  l=explode(".",tag)
  tag=l[1]
  if l.count>1 then class=l[2]
  else class=""
  
  l=explode("#",tag)
  tag=l[1]
  if l.count>1 then id=l[2]
  else id=""
  
  res = [:]
  
  cnt=pCss.count
  repeat with i=1 to cnt
    _tag=pCss.getPropAt(i)
    
    val=pCss[i]
    
    l=explode(":",_tag)
    _tag=l[1]
    if l.count>1 then _subtag=l[2]
    else _subtag=""
    
    l=explode(".",_tag)
    _tag=l[1]
    if l.count>1 then _class=l[2]
    else _class=""
    
    l=explode("#",_tag)
    _tag=l[1]
    if l.count>1 then _id=l[2]
    else _id=""
    
    tagmatch = (tag=_tag) OR (_tag.length=0)
    subtagmatch = (subtag=_subtag) OR (_subtag.length=0)
    classmatch = (class=_class) OR (_class.length=0)
    idmatch = (id=_id)
    
    if (tagmatch AND subtagmatch AND classmatch AND idmatch) then
      if aKey starts "#" then
        temp="#"&id
      else
        temp = _tag
        if ((temp.length > 0) AND (_class.length > 0)) then
          temp = temp & "." & _class
        else if (temp.length=0) then
          temp = "." & _class
        end if
        if ((temp.length > 0) AND (_subtag.length > 0)) then
          temp = temp & ":" & _subtag
        else if (temp.length=0) then
          temp = ":" & _subtag
        end if
      end if
      
      cnt2=pCss[temp].count
      repeat with j=1 to cnt2
        res[pCss[temp].getPropAt(j)] = pCss[temp][j]
      end repeat
      
    end if
  end repeat
  return res
end

----------------------------------------
-- returns css text for given key and prop (or empty string, if key or prop doesn't exist)
----------------------------------------
on getKeyProp (me, aKey, aProp)
  l=me.getKey(aKey)
  return string(l[aProp])
end

----------------------------------------
-- apply css to text member based on tagged text
-- optional flag isXHTML sets some defaults for html-tags, turns off pre-formatted wordwrapping and
-- turns on adding of new lines after "div","/div","p","/p","h1","/h1","h2","/h2","h3","/h3"
----------------------------------------
on applyCSS (me, txtMem, taggedText, isXHTML)
  
  if pRegExFlag then
    -- remove html-comments, xml- and doctype-declarations (needs PRegEx Xtra or DMX2004)
    -- warning: simple and dirty solution: all and removed
    taggedText=me._regReplace(taggedText, "<[!?].+?>(
|
)*", "")
  end if  
  
  pIsXHTML=(isXHTML=TRUE)
  if pIsXHTML then
    -- TEST: remove HTML/HEAD/BODY
    if pRegExFlag then taggedText=me._regReplace(taggedText, "((.*?)|())(
|
)*", "")
    pDefaultStyle["white-space"]="normal" -- html wordwrapping
    
    -- add css for some html tags; you're welcome to add more (like strong, big, small, h1, ...)
    me._addKey("b", "font-weight: bold;")
    me._addKey("i", "font-style: italic;")
    me._addKey("u", "text-decoration: underline;")
    me._addKey("pre",  "white-space: pre; font-family: Courier;")
    me._addKey("a", "text-decoration: underline; color: #0000ff;")
    me._addKey("a:visited", "color: #ff00ff;")
  end if
  
  --put taggedText
  
  pSrcStr = taggedText
  pTextMem = txtMem
  pTagStack = []
  pStyleStack=[]
  pCurrentChunk = ""
  
  pTextMem.text=""
  
  -- apply defaults
  me._applyStyle(pTextMem,pDefaultStyle)
  
  repeat while length(pSrcStr)
    if pSrcStr starts "<" then me._handleTag()
    else me._appendText()
  end repeat
end

--**************************************
-- PRIVATE
--**************************************

----------------------------------------
-- adds key-codeString pair to pCss
----------------------------------------
on _addKey (me, aKey, codeStr)
  aKey = strtolower(aKey)
  codeStr = strtolower(codeStr)
  if (voidP(pCss[aKey])) then
    pCss[aKey] = [:]
  end if
  codes = explode(";",codeStr)
  repeat with code in codes
    code = trim(code)
    l=explode(":",code)
    codekey=l[1]
    if l.count>1 then codevalue=l[2]
    else codevalue=""
    
    if (codekey.length > 0) then
      pCss[aKey][trim(codekey)] = trim(codevalue)
    end if
  end repeat
end

----------------------------------------
-- deletes rest of tag
----------------------------------------
on _deleteRestOfTag me
  the itemDelimiter = ">"
  delete item 1 of pSrcStr
end

----------------------------------------
-- handles text between tags
----------------------------------------
on _appendText me
  the itemDelimiter = "<"
  pCurrentChunk = pSrcStr.item[1]
  
  -- check for wordwrap behaviour:
  -- "white-space"="pre" (or not declared): keep word-wraps
  -- "white-space"="normal": remove word-wraps
  whiteSpace=pDefaultStyle["white-space"]
  repeat with aStyle in pStyleStack
    cnt=aStyle.count
    repeat with i = 1 to cnt
      white=aStyle["white-space"]
      if not voidP(white) then whiteSpace=white
    end repeat
  end repeat
  if whiteSpace="normal" then
    if pRegExFlag then
      pCurrentChunk = me._regReplace (pCurrentChunk, "(
|
)", "")
    else
      pCurrentChunk = str_replace(numtochar(10), "", pCurrentChunk)
      pCurrentChunk = str_replace(numtochar(13), "", pCurrentChunk)
    end if
  end if
  
  delete item 1 of pSrcStr
  put the itemDelimiter before pSrcStr
  
  if pCurrentChunk<>"" AND pTagStack=[] then -- not inside any tag, format with default style
    put pCurrentChunk after pTextMem
  end if
end

----------------------------------------
-- handles start and end tags
----------------------------------------
on _handleTag me
  the itemDelimiter = ">"
  fullTag = ltrim(pSrcStr.item[1])
  delete char 1 of fullTag
  theTag = fullTag.word[1]
  
  if (theTag starts "/") then -- END TAG
        
    if pCurrentChunk<>"" then
      von=pTextMem.text.length+1
      bis=von+pCurrentChunk.length
      put pCurrentChunk after pTextMem
      
      if theTag="/a" AND pIsXHTML then -- add hyperlink
        pTextMem.char[von..bis].hyperlink=pLink
      end if
      
      -- go through stack
      cssStyle=pDefaultStyle.duplicate()
      repeat with aStyle in pStyleStack
        cnt=aStyle.count
        repeat with i = 1 to cnt
          cssStyle[aStyle.getPropAt(i)]=aStyle[i]
        end repeat
      end repeat
      
      me._applyStyle(pTextMem.char[von..bis].ref,cssStyle)
    end if
    
    pTagStack.deleteAt(pTagStack.count)
    pStyleStack.deleteAt(pStyleStack.count)
    
  else if the last char of theTag="/" then -- SINGLE TAG
    if pIsXHTML AND (theTag="br/") then put RETURN after pTextMem
    
  else -- START TAG
    
    -- find class and id
    cnt=fullTag.word.count
    if cnt>1 then
      repeat with i=2 to cnt
        w=fullTag.word[i]
        if (w starts "class=") then
          if pRegExFlag then theClass=me._regReplace(trim(w.char[7..w.char.count]), QUOTE, "")
          else theClass=str_replace(QUOTE,"",trim(w.char[7..w.char.count]))
          theClass=strtolower(theClass)
        else if (w starts "id=") then
          if pRegExFlag then theId=me._regReplace(trim(w.char[4..w.char.count]), QUOTE, "")
          else theId=str_replace(QUOTE,"",trim(w.char[4..w.char.count]))
          theId=strtolower(theId)
        else if (w starts "href=" AND pIsXHTML) then
          put "LINK"
          if pRegExFlag then pLink=me._regReplace(trim(w.char[6..w.char.count]), QUOTE, "")
          else pLink=str_replace(QUOTE,"",trim(w.char[6..w.char.count]))
        end if
        
      end repeat
    end if
    
    -- NESTED TAGS
    if pTagStack<>[] then
      if pCurrentChunk<>"" then
        von=pTextMem.text.length+1
        bis=von+pCurrentChunk.length
        put pCurrentChunk after pTextMem
        
        -- go through stack
        cssStyle=pDefaultStyle.duplicate()
        repeat with aStyle in pStyleStack
          cnt=aStyle.count
          repeat with i = 1 to cnt
            prop=aStyle.getPropAt(i)
            cssStyle[prop]=aStyle[i]
          end repeat
        end repeat
        
        me._applyStyle(pTextMem.char[von..bis].ref,cssStyle)
      end if
    end if
    
    styleTag=theTag
    
    if not voidP(theClass) then
      styleTag=styleTag&"."&theClass
    end if
    
    cssStyle=me.getKey(styleTag)
    
    if not voidP(theId) then
      aStyle=me.getKey("#"&theId)
      cnt=aStyle.count
      repeat with i = 1 to cnt
        cssStyle[aStyle.getPropAt(i)]=aStyle[i]
      end repeat
    end if
    
    -- put tag and corresponding style on stack
    pTagStack.add(styleTag)
    pStyleStack.add(cssStyle)
    
  end if
  
  if pIsXHTML then
    if ["div","/div","p","/p","h1","/h1","h2","/h2","h3","/h3"].getPos(theTag) then
      put RETURN after pTextMem
    end if
  end if
  
  me._deleteRestOfTag()
  pCurrentChunk=""
end

----------------------------------------
-- converts css-style-proplist to director-text-style-props and applies it to text-member-reference
----------------------------------------
on _applyStyle (me, txtRef, cssStyle)
  
  dirStyle=[:]
  fntStyle=[]
  
  cnt=cssStyle.count
  repeat with i = 1 to cnt
    k=cssStyle.getPropAt(i)
    v=cssStyle[i]
    
    case (k) of
      "color":
        dirStyle[#color]=RGB(v)
      "font-family":
        dirStyle[#font]=v
      "font-size":
        dirStyle[#fontsize]=integer(v)
      "line-height":
        dirStyle[#fixedLineSpace]=integer(v)
        
        
      "font-weight": -- bold, normal
        if v="bold" then fntStyle.add(#bold)
        
      "font-style": -- italic , normal
        if v="italic" then fntStyle.add(#italic)
        
      "text-decoration": -- underline, none
        if v="underline" then fntStyle.add(#underline)
        
      "vertical-align": -- super, sub, baseline
        if v="super" then fntStyle.add(#superscript)
        else if v="sub" then fntStyle.add(#subscript)
        
        
      "letter-spacing":
        dirStyle[#charSpacing]=integer(v)
        
      "text-align":
        if v="justify" then v="Full"
        dirStyle[#alignment]=symbol(v)
        
      "margin-left":
        dirStyle[#leftIndent]=integer(v)
      "margin-right":
        dirStyle[#rightIndent]=integer(v)
      "margin-bottom":
        dirStyle[#bottomSpacing]=integer(v)
      "text-indent":
        dirStyle[#firstIndent]=integer(v)
    end case
  end repeat
  
  if fntStyle=[] then fntStyle=[#plain]
  dirStyle[#fontStyle]=fntStyle
  
  cnt=dirStyle.count
  repeat with i = 1 to cnt
    txtRef.setProp(dirStyle.getPropAt(i),dirStyle[i])
  end repeat
  
  -- if no line-height in default and current style, use "natural" line-height (font-size*1.3)
  if voidP(pDefaultStyle.findPos("line-height")) AND voidP(dirStyle.findPos(#fixedLineSpace)) then
    txtRef.setProp(#fixedLineSpace,txtRef.fontsize*1.3)
  end if
  
end

----------------------------------------
-- Search & Replace with RegExp (global)
----------------------------------------
on _regReplace (me, str, pat, rep)
  if pPRegExFlag then
    l=[str]
    PRegEx_Replace(l,pat,"g", rep)
    return  l[1]
  else
    return _js_RegExReplace(str,pat,rep)
  end if
end

 


Upload Provided by ABCUpload ASP

Contact

MMI
22 West Court Sq
Suite 2C
Newnan, GA 30263
USA

Fax - (206) 339-5833

Send e-mail