Created
April 8, 2014 08:06
-
-
Save pwaller/10100874 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #! /usr/bin/env python3 | |
| """ | |
| usage: craftviz <file.craft> | |
| """ | |
| import re | |
| from textwrap import dedent | |
| import pyparsing as P | |
| from docopt import docopt | |
| L = lambda e: P.Literal(e).suppress() | |
| noNL = lambda expr: expr.setWhitespaceChars(" \t\r") | |
| ASSIGNMENT = P.Group( | |
| P.Word(P.alphas)("name") + | |
| L("=") + | |
| P.Optional(noNL(P.Word(P.alphas + P.nums + " (),.-_:; ")))("value") | |
| ) + P.LineEnd().suppress() | |
| BLOCK = P.Forward() | |
| BLOCK << P.Group( | |
| P.Word(P.alphas + "_")("block") + | |
| L("{") + | |
| P.Group(P.ZeroOrMore(ASSIGNMENT | BLOCK))("children") + | |
| L("}")) | |
| CRAFT_FILE = P.OneOrMore(ASSIGNMENT | BLOCK) + P.StringEnd() | |
| class Block(object): | |
| def __init__(self, name, parent, elements): | |
| self.name, self.parent = name, parent | |
| self.blocks = [e for e in elements if "block" in e] | |
| self.assigns = [e for e in elements if "block" not in e] | |
| self.d = {a["name"]: a.get("value") | |
| for a in self.assigns} | |
| self.children = [Block(b["block"], self, b.children) | |
| for b in self.blocks] | |
| @property | |
| def what(self): | |
| if self.name == "PART": | |
| return self.d["part"] | |
| @property | |
| def attachments(self): | |
| for a in self.assigns: | |
| if a["name"] in "link attN srfN sym".split(): | |
| left, _, right = a["value"].partition(",") | |
| if _: | |
| yield right | |
| else: | |
| yield left | |
| if a["name"] == "cData": | |
| x = re.search("tgt: ([^;]+);", a["value"]) | |
| if x: | |
| (tgt,) = x.groups() | |
| # raise RuntimeError(tgt) | |
| yield tgt | |
| def __repr__(self): | |
| return "{} {} {}".format(self.name, self.what, list(self.attachments)) | |
| def main(): | |
| args = docopt(__doc__) | |
| with open(args["<file.craft>"]) as fd: | |
| elements = CRAFT_FILE.parseString(fd.read()) | |
| top = Block(None, None, elements) | |
| print("graph {") | |
| for block in top.children: | |
| # print(block) | |
| for a in block.attachments: | |
| print('"{}" -- "{}"'.format(block.what, a)) | |
| print("}") | |
| if __name__ == "__main__": | |
| main() | |
| """ | |
| Parses files of this form: | |
| ship = Absurd I (Crash 13) | |
| version = 0.23.5 | |
| description = | |
| type = VAB | |
| PART | |
| { | |
| part = Mark1-2Pod_4294777266 | |
| partName = Part | |
| pos = 0.04093654,20.80854,0.07038268 | |
| rot = 0,0,0,1 | |
| attRot = 0,0,0,1 | |
| mir = 1,1,1 | |
| istg = 0 | |
| dstg = 0 | |
| sidx = -1 | |
| sqor = -1 | |
| attm = 0 | |
| link = RCSTank1-2_4294776478 | |
| link = GrapplingDevice_4294777156 | |
| attN = bottom,RCSTank1-2_4294776478 | |
| attN = top,GrapplingDevice_4294777156 | |
| EVENTS | |
| { | |
| } | |
| ACTIONS | |
| { | |
| } | |
| MODULE | |
| { | |
| name = ModuleCommand | |
| isEnabled = True | |
| controlSrcStatusText = | |
| EVENTS | |
| { | |
| MakeReference | |
| { | |
| active = True | |
| guiActive = True | |
| guiIcon = Control From Here | |
| guiName = Control From Here | |
| category = Control From Here | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| RenameVessel | |
| { | |
| active = True | |
| guiActive = True | |
| guiIcon = Rename Vessel | |
| guiName = Rename Vessel | |
| category = Rename Vessel | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| } | |
| ACTIONS | |
| { | |
| } | |
| } | |
| MODULE | |
| { | |
| name = ModuleSAS | |
| isEnabled = True | |
| EVENTS | |
| { | |
| } | |
| ACTIONS | |
| { | |
| } | |
| } | |
| MODULE | |
| { | |
| name = ModuleReactionWheel | |
| isEnabled = True | |
| stateString = Active | |
| WheelState = Active | |
| EVENTS | |
| { | |
| OnToggle | |
| { | |
| active = True | |
| guiActive = True | |
| guiIcon = Toggle Torque | |
| guiName = Toggle Torque | |
| category = Toggle Torque | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| } | |
| ACTIONS | |
| { | |
| Activate | |
| { | |
| actionGroup = None | |
| } | |
| Deactivate | |
| { | |
| actionGroup = None | |
| } | |
| Toggle | |
| { | |
| actionGroup = None | |
| } | |
| } | |
| } | |
| MODULE | |
| { | |
| name = ModuleScienceExperiment | |
| isEnabled = True | |
| Deployed = False | |
| Inoperable = False | |
| EVENTS | |
| { | |
| DeployExperiment | |
| { | |
| active = True | |
| guiActive = True | |
| guiIcon = Deploy | |
| guiName = Deploy | |
| category = Deploy | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| CollectDataExternalEvent | |
| { | |
| active = True | |
| guiActive = False | |
| guiIcon = | |
| guiName = | |
| category = | |
| guiActiveUnfocused = True | |
| unfocusedRange = 1.5 | |
| externalToEVAOnly = True | |
| } | |
| ReviewDataEvent | |
| { | |
| active = True | |
| guiActive = True | |
| guiIcon = Review Data | |
| guiName = Review Data | |
| category = Review Data | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| ResetExperiment | |
| { | |
| active = True | |
| guiActive = True | |
| guiIcon = Reset | |
| guiName = Reset | |
| category = Reset | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| ResetExperimentExternal | |
| { | |
| active = True | |
| guiActive = False | |
| guiIcon = Reset | |
| guiName = Reset | |
| category = Reset | |
| guiActiveUnfocused = True | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| } | |
| ACTIONS | |
| { | |
| DeployAction | |
| { | |
| actionGroup = None | |
| } | |
| ResetAction | |
| { | |
| actionGroup = None | |
| } | |
| } | |
| } | |
| MODULE | |
| { | |
| name = ModuleScienceContainer | |
| isEnabled = True | |
| EVENTS | |
| { | |
| StoreDataExternalEvent | |
| { | |
| active = False | |
| guiActive = False | |
| guiIcon = | |
| guiName = Store Experiments (0) | |
| category = | |
| guiActiveUnfocused = True | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| CollectDataExternalEvent | |
| { | |
| active = False | |
| guiActive = False | |
| guiIcon = | |
| guiName = Take Data (0) | |
| category = | |
| guiActiveUnfocused = True | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| ReviewDataEvent | |
| { | |
| active = False | |
| guiActive = True | |
| guiIcon = Review Data | |
| guiName = Review Stored Data (0) | |
| category = Review Data | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| } | |
| ACTIONS | |
| { | |
| } | |
| } | |
| MODULE | |
| { | |
| name = FlagDecal | |
| isEnabled = True | |
| flagDisplayed = True | |
| EVENTS | |
| { | |
| ToggleFlag | |
| { | |
| active = True | |
| guiActive = False | |
| guiActiveEditor = True | |
| guiIcon = ToggleFlag | |
| guiName = ToggleFlag | |
| category = ToggleFlag | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| } | |
| ACTIONS | |
| { | |
| } | |
| } | |
| MODULE | |
| { | |
| name = ModuleTripLogger | |
| isEnabled = True | |
| EVENTS | |
| { | |
| } | |
| ACTIONS | |
| { | |
| } | |
| Surfaced | |
| { | |
| } | |
| Flew | |
| { | |
| } | |
| FlewBy | |
| { | |
| } | |
| Orbited | |
| { | |
| } | |
| SubOrbited | |
| { | |
| } | |
| } | |
| RESOURCE | |
| { | |
| name = ElectricCharge | |
| amount = 150 | |
| maxAmount = 150 | |
| flowState = True | |
| isTweakable = True | |
| hideFlow = False | |
| flowMode = Both | |
| } | |
| RESOURCE | |
| { | |
| name = MonoPropellant | |
| amount = 30 | |
| maxAmount = 30 | |
| flowState = True | |
| isTweakable = True | |
| hideFlow = False | |
| flowMode = Both | |
| } | |
| } | |
| PART | |
| { | |
| part = RCSTank1-2_4294776478 | |
| partName = Part | |
| pos = 0.04093654,19.8293,0.07038268 | |
| rot = 0,0,0,1 | |
| attRot = 0,0,0,1 | |
| mir = 1,1,1 | |
| istg = 0 | |
| dstg = 0 | |
| sidx = -1 | |
| sqor = -1 | |
| attm = 0 | |
| link = size3Decoupler_4294776412 | |
| attN = top,Mark1-2Pod_4294777266 | |
| attN = bottom,size3Decoupler_4294776412 | |
| EVENTS | |
| { | |
| } | |
| ACTIONS | |
| { | |
| } | |
| RESOURCE | |
| { | |
| name = MonoPropellant | |
| amount = 750 | |
| maxAmount = 750 | |
| flowState = True | |
| isTweakable = True | |
| hideFlow = False | |
| flowMode = Both | |
| } | |
| } | |
| PART | |
| { | |
| part = GrapplingDevice_4294777156 | |
| partName = Part | |
| pos = 0.04093654,22.14255,0.07038268 | |
| rot = 0,0,0,1 | |
| attRot = 0,0,0,1 | |
| mir = 1,1,1 | |
| istg = 0 | |
| dstg = 0 | |
| sidx = -1 | |
| sqor = -1 | |
| attm = 0 | |
| srfN = srfAttach,RCSTank1-2_4294776478 | |
| attN = top,Mark1-2Pod_4294777266 | |
| EVENTS | |
| { | |
| } | |
| ACTIONS | |
| { | |
| } | |
| MODULE | |
| { | |
| name = ModuleGrappleNode | |
| isEnabled = True | |
| state = Ready | |
| dockUId = 0 | |
| EVENTS | |
| { | |
| Release | |
| { | |
| active = False | |
| guiActive = True | |
| guiIcon = Release | |
| guiName = Release | |
| category = Release | |
| guiActiveUnfocused = True | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| ReleaseSameVessel | |
| { | |
| active = False | |
| guiActive = True | |
| guiIcon = Release | |
| guiName = Release | |
| category = Release | |
| guiActiveUnfocused = True | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| Decouple | |
| { | |
| active = False | |
| guiActive = True | |
| guiIcon = Decouple Node | |
| guiName = Decouple Node | |
| category = Decouple Node | |
| guiActiveUnfocused = True | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| MakeReferenceTransform | |
| { | |
| active = True | |
| guiActive = True | |
| guiIcon = Control from Here | |
| guiName = Control from Here | |
| category = Control from Here | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| SetLoose | |
| { | |
| active = False | |
| guiActive = True | |
| guiIcon = Free Pivot | |
| guiName = Free Pivot | |
| category = Free Pivot | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| LockPivot | |
| { | |
| active = False | |
| guiActive = True | |
| guiIcon = Lock Pivot | |
| guiName = Lock Pivot | |
| category = Lock Pivot | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| } | |
| ACTIONS | |
| { | |
| ReleaseAction | |
| { | |
| actionGroup = None | |
| } | |
| DecoupleAction | |
| { | |
| actionGroup = None | |
| } | |
| } | |
| } | |
| MODULE | |
| { | |
| name = ModuleAnimateGeneric | |
| isEnabled = True | |
| status = Locked | |
| animSwitch = True | |
| animTime = 0 | |
| animSpeed = 1 | |
| EVENTS | |
| { | |
| Toggle | |
| { | |
| active = True | |
| guiActive = True | |
| guiIcon = Toggle | |
| guiName = Arm | |
| category = Toggle | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| } | |
| ACTIONS | |
| { | |
| ToggleAction | |
| { | |
| actionGroup = None | |
| } | |
| } | |
| } | |
| MODULE | |
| { | |
| name = FXModuleLookAtConstraint | |
| isEnabled = True | |
| EVENTS | |
| { | |
| } | |
| ACTIONS | |
| { | |
| } | |
| } | |
| MODULE | |
| { | |
| name = FlagDecal | |
| isEnabled = True | |
| flagDisplayed = True | |
| EVENTS | |
| { | |
| ToggleFlag | |
| { | |
| active = True | |
| guiActive = False | |
| guiActiveEditor = True | |
| guiIcon = ToggleFlag | |
| guiName = ToggleFlag | |
| category = ToggleFlag | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| } | |
| ACTIONS | |
| { | |
| } | |
| } | |
| } | |
| PART | |
| { | |
| part = size3Decoupler_4294776412 | |
| partName = Part | |
| pos = 0.04093654,18.89515,0.07038268 | |
| rot = 0,0,0,1 | |
| attRot = 0,0,0,1 | |
| mir = 1,1,1 | |
| istg = 0 | |
| dstg = 1 | |
| sidx = 0 | |
| sqor = 0 | |
| attm = 0 | |
| link = Size3LargeTank_4294776372 | |
| attN = top,RCSTank1-2_4294776478 | |
| attN = bottom,Size3LargeTank_4294776372 | |
| EVENTS | |
| { | |
| } | |
| ACTIONS | |
| { | |
| } | |
| MODULE | |
| { | |
| name = ModuleDecouple | |
| isEnabled = True | |
| isDecoupled = False | |
| EVENTS | |
| { | |
| Decouple | |
| { | |
| active = True | |
| guiActive = True | |
| guiIcon = Decouple | |
| guiName = Decouple | |
| category = Decouple | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| } | |
| ACTIONS | |
| { | |
| DecoupleAction | |
| { | |
| actionGroup = None | |
| } | |
| } | |
| } | |
| } | |
| PART | |
| { | |
| part = Size3LargeTank_4294776372 | |
| partName = Part | |
| pos = 0.04093654,14.71859,0.07038268 | |
| rot = 0,0,0,1 | |
| attRot = 0,0,0,1 | |
| mir = 1,1,1 | |
| istg = 2 | |
| dstg = 2 | |
| sidx = -1 | |
| sqor = -1 | |
| attm = 0 | |
| link = Size3EngineCluster_4294776344 | |
| attN = top,size3Decoupler_4294776412 | |
| attN = bottom,Size3EngineCluster_4294776344 | |
| EVENTS | |
| { | |
| } | |
| ACTIONS | |
| { | |
| } | |
| RESOURCE | |
| { | |
| name = LiquidFuel | |
| amount = 6480 | |
| maxAmount = 6480 | |
| flowState = True | |
| isTweakable = True | |
| hideFlow = False | |
| flowMode = Both | |
| } | |
| RESOURCE | |
| { | |
| name = Oxidizer | |
| amount = 7920 | |
| maxAmount = 7920 | |
| flowState = True | |
| isTweakable = True | |
| hideFlow = False | |
| flowMode = Both | |
| } | |
| } | |
| PART | |
| { | |
| part = Size3EngineCluster_4294776344 | |
| partName = Part | |
| pos = 0.04093654,9.451339,0.07038268 | |
| rot = 0,0,0,1 | |
| attRot = 0,0,0,1 | |
| mir = 1,1,1 | |
| istg = 1 | |
| dstg = 2 | |
| sidx = 0 | |
| sqor = 1 | |
| attm = 0 | |
| attN = top,Size3LargeTank_4294776372 | |
| EVENTS | |
| { | |
| } | |
| ACTIONS | |
| { | |
| } | |
| MODULE | |
| { | |
| name = ModuleEnginesFX | |
| isEnabled = True | |
| staged = False | |
| flameout = False | |
| EngineIgnited = False | |
| engineShutdown = False | |
| currentThrottle = 0 | |
| thrustPercentage = 100 | |
| manuallyOverridden = False | |
| thrustPercentage_UIFlight | |
| { | |
| controlEnabled = True | |
| minValue = 0 | |
| maxValue = 100 | |
| stepIncrement = 0.5 | |
| } | |
| EVENTS | |
| { | |
| Activate | |
| { | |
| active = True | |
| guiActive = True | |
| guiIcon = Activate Engine | |
| guiName = Activate Engine | |
| category = Activate Engine | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| Shutdown | |
| { | |
| active = False | |
| guiActive = True | |
| guiIcon = Shutdown Engine | |
| guiName = Shutdown Engine | |
| category = Shutdown Engine | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| } | |
| ACTIONS | |
| { | |
| OnAction | |
| { | |
| actionGroup = None | |
| } | |
| ShutdownAction | |
| { | |
| actionGroup = None | |
| } | |
| ActivateAction | |
| { | |
| actionGroup = None | |
| } | |
| } | |
| } | |
| MODULE | |
| { | |
| name = ModuleAlternator | |
| isEnabled = True | |
| EVENTS | |
| { | |
| } | |
| ACTIONS | |
| { | |
| } | |
| } | |
| MODULE | |
| { | |
| name = ModuleGimbal | |
| isEnabled = True | |
| gimbalLock = False | |
| EVENTS | |
| { | |
| LockGimbal | |
| { | |
| active = True | |
| guiActive = True | |
| guiActiveEditor = True | |
| guiIcon = Lock Gimbal | |
| guiName = Lock Gimbal | |
| category = Lock Gimbal | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| FreeGimbal | |
| { | |
| active = False | |
| guiActive = True | |
| guiActiveEditor = True | |
| guiIcon = Free Gimbal | |
| guiName = Free Gimbal | |
| category = Free Gimbal | |
| guiActiveUnfocused = False | |
| unfocusedRange = 2 | |
| externalToEVAOnly = True | |
| } | |
| } | |
| ACTIONS | |
| { | |
| ToggleAction | |
| { | |
| actionGroup = None | |
| } | |
| } | |
| } | |
| MODULE | |
| { | |
| name = ModuleAnimateHeat | |
| isEnabled = True | |
| EVENTS | |
| { | |
| } | |
| ACTIONS | |
| { | |
| } | |
| } | |
| RESOURCE | |
| { | |
| name = ElectricCharge | |
| amount = 0 | |
| maxAmount = 0 | |
| flowState = True | |
| isTweakable = False | |
| hideFlow = True | |
| flowMode = Both | |
| } | |
| } | |
| """ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment