#!/bin/sh # MetaCard 2.3 stack # The following is not ASCII text, # so now would be a good time to q out of more exec mc $0 "$@"  mcRipperwwhite54 U helvetica U helvetica U helvetica card bozo P function encode theData #--replace "/" with "//" in theData #--put numtoChar(250) into stopChar --put "|" into stopChar --replace stopChar with "/" & stopChar in theData --replace cr with stopChar&stopChar in theData put "|" into stopChar replace stopChar with stopChar & stopChar in theData if cr is in theData then replace "]]" with stopChar & "]" & stopChar & "]" in theData put "" into theData else replace "<" with stopChar & "[" in theData end if return theData end encode function decode theData #--put numtoChar(250) into stopChar --put "|" into stopChar --replace stopChar & stopChar with cr in theData --replace "/" & stopChar with stopChar in theData #--replace "//" with "/" in theData put "|" into stopChar put empty into replaceString repeat put random(999) after replaceString if replaceString is not in theData then exit repeat if the length of replaceString > 30 then put empty into replaceString end repeat replace stopChar & stopChar with replaceString in theData if char 1 to 9 of theData is "" then put char 10 to -4 of theData into theData replace stopChar & "]" & stopChar & "]" with "]]" in theData else replace stopChar & "[" with "<" in theData end if replace replaceString with stopChar in theData return theData end decode 4testthis is property testtest2these are the contents of test2testset testsetonethis is testsetone testsettwothis is testsettwo  RipEp--Ripper Script --this script creates an XML file based on a stack global ripText, theStack on mouseUp put fld "stack" into theMainStack if theMainStack is empty then put askStack("Choose a stack to rip...") into theMainStack put theMainStack into fld "stack" end if if theMainStack is empty then answer "You must specify a stack to rip" exit to top end if put "" into fld "description" put " " into rawIndent put 4 into indentVal put "" into indentSpace["stack"] put char 1 to (1*indentVal) of rawIndent into indentSpace["background"] put char 1 to (1*indentVal) of rawIndent into indentSpace["card"] put "" & cr & "" & cr into ripText put cr into groupIDs put the subStacks of stack theMainStack into theStackList if theStackList is empty then put theMainStack into theStackList else if theMainStack is not among the lines of theStackList then put theMainStack & cr before theStackList end if end if repeat for each line theStack in theStackList put "stack" && kwote(theStack) into theStackObject rip ("stack" && kwote(theStack)),"" repeat with i = 1 to (the number of bgs of stack theStack) put "bg" && i && "of" && theStackObject into theBG put the name of theBG into theBGName put theBGName into bgList put " " into theBGSpaces rip (theBG),theBGSpaces repeat with j = 1 to (the number of controls of bg i of stack theStack) put "control" && j && "of bg" && i && "of" && theStackObject into theControl repeat until the owner of theControl is theBGName put theBGSpaces & "" & cr after ripText delete char 1 to 3 of theBGSpaces delete the last line of bgList put the last line of bgList into theBGName end repeat rip (theControl),(" "&theBGSpaces) put the name of theControl into theControlName put word 1 of theControlName into theObjectType if theObjectType is "group" then put "background" into theObjectType put " " before theBGSpaces put theControlName into theBGName if bgList is not empty then put cr after bgList put theBGName after bgList else put theBGSpaces & " " & cr after ripText end if end repeat put " " & cr after ripText end repeat repeat with i = 1 to (the number of cds of stack theStack) rip ("cd" && i && "of" && theStackObject)," " repeat with j = 1to (the number of controls of cd i of stack theStack) put the name of control j of cd i of stack theStack into theObject if word 1 of the owner of control j of cd i of stack theStack is "card" then if word 1 of theObject is "group" then put " "& cr after ripText else rip ("control" && j && "of cd" && i && "of" && theStackObject)," " put " " & cr after ripText end if else if word 1 of theObject is "field" then put the htmlText of control j of cd i of stack theStack into fldText put " " & cr after ripText put " " & encode(fldText) & "" & cr & " " & cr after ripText end if end if end repeat put " " & cr after ripText end repeat put "" & cr after ripText end repeat put "" & cr after ripText put ripText into fld "description" put the length of ripText put "" into ripText beep end mouseUp on rip theObject theSP put theObject & cr after fld "commands" of stack "mcRipper" put the properties of theObject into props put the keys of props into theKeys put the name of theObject into theName if word 1 of theObject is "bg" then put "background" into word 1 of theName end if if word 4 of theObject is "bg" and word 1 of theName is "group" then put "background" into word 1 of theName end if put word 1 of theName into theType put word 2 to -1 of theName into theShortName --put the opening tag of the object after the ripText put theSP & "<" & theType after ripText --Test if the object actually have the name, or is the name returning the id if theName contains quote then --it has a name put " name=" & theShortName after ripText else put "" into props["name"] --get rid of the id end if put ">" & cr after ripText --if it's an image then if word 1 of theName is "image" then put "" into props["colors"] --don't record colors end if --if it's a stack then if word 1 of theName is "stack" then put "" into props["substacks"] --don't record substacks end if --get script do ("put the script of" && theObject && "into theScript") put (theSP & " " & cr) after ripText --do ("put the contents of" && theObject && "into theContents") --put ("contents" && encode(theContents) & cr) after ripText --get the basic properties of the object put theSP & " " & cr after ripText repeat for each line i in theKeys put theSP & " <" & i & ">" & encode(props[i]) & "" & cr after ripText end repeat put theSP & " " & cr after ripText --get the custom properties of the default set of the object #do ("set the customPropertySet of" && theObject && "to empty") #do ("put the customProperties of" && theObject && "into customProps") #put the keys of customProps into theCustomKeys #repeat for each line i in theCustomKeys #put theSP & " <" & i & ">" & encode(customProps[i]) & "" & cr after ripText #end repeat --get the custom properties of each of the custom property sets of the object do ("put the customPropertySets of" && theObject && "into customPropSets") if customPropSets is empty then put cr after customPropertySets else put cr & cr after customPropSets end if repeat for each line L in customPropSets put theSP & " " & cr after ripText --do ("set the customPropertySet of" && theObject && "to L") set the customPropertySet of theObject to L --do ("put the customProperties of" && theObject && "into customProps") put the customProperties of theObject into customProps put the keys of customProps into theCustomKeys repeat for each line i in theCustomKeys put theSP & " <" & i & ">" & encode(customProps[i]) & "" & cr after ripText end repeat put theSP & " " & cr after ripText end repeat end rip function askStack comment -- version 7.0 if comment is empty then put "Select a stack." into comment end if put empty into longStackName answer file comment of type "MSTK" if the result is empty then put line 1 of it into longStackName end if return longStackName end askStack function kwote string -- version latest,15/4/01 return quote & string & quote end kwote  @/Click here to rip the stack named to the right  description)`XP,The description of a stack and its contents  `QaYBurnEp*--Burner Script --this creates a stack based on XML input on mouseUp put "" into fld "commands" put fld "description" into burnText --put lineOffset(",,,,,,,,," into endObjectList put "size,layer,number,id" into readOnlyProps --lock messages, since we don't need them lock messages --get a line repeat for each line L in burnText --if the line isn't empty if L is not "" then --switch based on what L is and what we're doing switch ------------------------- --if collecting a cdata case cDataText is not empty --add it to the cdata put L & cr after cDataText --if line ends cdata put offset("]]>",L) into theOffset if theOffset > 0 then --get rid of the end tags put char 1 to (theOffset - 1) of L into the last line of cDataText --decode it put decode(cDataText) into cDataText --set it put "set the" && theProp && "of theObject to cDataText" into theCommand put theObject & ":" && theProp && "=" && cDataText & cr after logText put theObject & ":" && theProp && "=" && cDataText put theCommand && cDataText & cr after logText --put theCommand && cDataText try do theCommand catch someErr put someErr & cr after logText end try --empty the holding variable (ends the cdata process) put "" into cDataText --end if end if --break break ------------------------- --else if L is the opening or closing tags for properties case word 1 of L is among the items of ",," --break, to discard it break ------------------------- --else if line starts an object case word 1 of L is among the items of newObjectList --get the type of the object put char 2 to -1 of word 1 of L into theObjectType --if the object didn't have a name, then we have something like "card>" if the last char of theObjectType is ">" then delete the last char of theObjectType end if --if it's a stack, background, or a background field, get the name if theObjectType is among the items of "stack,bgField,background" then put offset("name=",L) + 6 into theNameStart --make sure it has a name, otherwise can't refer to it if theNameStart > 0 then put char theNameStart to -3 of L into theObjectName else answer "Stack, BG, or BG Field with no name error:" && L end if end if --if it's not a bg field, create the object --answer "Creating:" && L if theObjectType is "bgField" then put "field" && quote & theObjectName & quote into theObject else try if theObjectType is among the items of "stack,background" then do ("create" && theObjectType && quote & theObjectName & quote) set the name of it to theObjectName put theObjectType && quote & theObjectName & quote into theObject else do ("create" && theObjectType) put it into theObject put word 1 to 3 of theObject into theObject if theObjectType is "background" then put "background" into word 1 of theObject end if if theObjectType is "card" then repeat (the number of groups of this cd) put the name of group 1 of this cd into theRemoveBG put "background" into word 1 of theRemoveBG remove theRemoveBG from this cd end repeat end if end if catch someErr put someErr & cr after logText end try put "create" && theObject & cr after logText end if --put the object name after the object stack if theObjectStack is empty then put theObject into theObjectStack else put cr & theObject after theObjectStack end if --answer theObjectStack --if it's a stack, go to it and make it default if "stack" is theObjectType then try do ("go" && theObject) set the defaultStack to theObjectName catch someErr put someErr & cr after logText end try end if --if it's a background, start editing it if "background" is theObjectType then try --add the background to the background list if bgList is not empty then put cr after bgList put theObject after bgList stop editing start editing theObject catch someErr put someErr & cr after logText end try end if --break break ------------------------- --else if it ends an object case word 1 of L is among the items of endObjectList --get the type of the item specified in L put char 3 to -2 of word 1 of L into theObjectEnd --check to see if its the last item on the list --and raise an alert if it isn't if theObjectType is not theObjectEnd then answer "XML mismatch -- start:" && theObjectType && "end:" && theObjectEnd end if --if it's a background, stop editing it if theObjectType is "background" then try stop editing delete the last line of bgList if bgList is not empty then put the last line of bgList into theBG start editing theBG end if catch someErr put someErr & cr after logText end try end if --if it's a stack then delete the first card if theObjectType is "stack" then try --answer theObject delete cd 1 catch someErr put someErr & cr after logText end try end if --remove it from the object stack delete line -1 of theObjectStack --make the next item on the object stack the current object if theObjectStack is empty then put empty into theObject else put line -1 of theObjectStack into theObject put word 1 of theObject into theObjectType end if --break break ------------------------- --else if it's a custompropertyset case (word 1 of L) is "(.*)",theProp,theValue) then --set it if it isn't read only if theProp is not among the items of readOnlyProps then put "set the" && theProp && "of theObject to theValue" into theCommand put decode(theValue) into theValue put theObject & ":" && theProp && "=" && theValue & cr after logText put theObject & ":" && theProp && "=" && theValue try do theCommand catch someErr put someErr & cr after logText end try --end if end if --end if end if --end if end if --end switch end switch --end if end if --end repeat end repeat --put logText into the commands field go stack "mcRipper" set the defaultStack to "mcRipper" put logText into fld "commands" of stack "mcRipper" end mouseUp h@/Creates a stack based on the stack description stack)`X(Enter the name of the stack to rip here     commands)`X+Describes steps taken during stack burning  `aY   PX Stack Description:lineK?$@*@   X Stack Name:   X Burn Log: Version .5 (click for details)Ex 3on mouseUp show fld "version notes" end mouseUp /Creates a stack based on the stack description  version notesx "on mouseUp hide me end mouseUp $p mcRipper info -- click to hide.  )Click anywhere in this field to hide it.  *Version -- This is version .5 of mcRipper  History -- Brief -- version .1 was a first shot. Version .2 handled custom properties (including custom property sets!) and substacks. Version .3 changes the file format, so all bets are off. On the other hand, it does XML. <> Version 4 handles stack names with spaces in them, has buttons to open and save xml files, handles contents of background fields, and takes a stab at nested backgrounds. Version 5 handles nested backgrounds and cleans up the code.  3What it Does -- It rips and burns MetaCard stacks.  What is "Ripping a MetaCard stack?" -- It goes through the stack and notes all the objects contained in the stack, and most of their properties. It records all this information in XML text format, where it can be modified easily.  What is "Burning a MetaCard stack?" -- It can take the XML text it outputs and use it to recreate the stack from scratch, creating the stack, the backgrounds, the cards, and the objects.  Warning -- This hasn't been tested well yet -- please use only on copies of stacks. It hasn't done anything harmful to any of my test stacks, but I don't want you to be the first casualty.  =Does it also work on Revolution stacks? -- yes, it seems to.  !What good is it? -- You need to ask? :-) MetaCard stacks in XML -- it can be used as a way of editing MetaCard stacks in any of the available XML editors or text editors, without their scripts running. It was inspired by SuperEdit, which edits SuperCard files without running any scripts.  How do I use it? -- Open mcRipper. Open the stack you want to rip. Enter the name (not the file name, but the stack name) in the top field. Click the Rip button. Click the save button or copy out the text and save it as a text file with .xml on the end of it.  tBugs -- Could be many. Seems to work so far, but check the web page at http://www.inspiredlogic.com/mc/ripper.html.  Open Source -- mcRipper is open source, under no license. Feel free to do whatever you like with it. I request that if you make improvments, you flow that code back to me to be incorporated into mcRipper  EmcRipper can be found at http://www.inspiredlogic.com/mc/ripper.html  2Comments can be sent to gcanyon@inspiredlogic.com  `%_ aLoadEx on mouseUp answer file "File to open:" if the result is empty then --put it put url ("file:" & it) into fld "description" end if end mouseUp 0$ SaveEx on mouseUp ask file "Save results as:" with (fld "stack" &".xml") if the result is empty then --put it put fld "description" into url ("file:" & it) end if end mouseUp $  MCRipperwwhite4  @4