【问题标题】:ExtendScript Parse resource string to create variable pathsExtendScript 解析资源字符串以创建变量路径
【发布时间】:2015-02-16 11:55:42
【问题描述】:

我希望通过解析资源字符串来自动创建我的变量路径来加快我的工作流程。不仅查看大型 UI 会让人感到困惑,而且写出访问每个元素的路径更糟糕。 ExtendScript 有很多我们称之为“怪癖”的东西。因此,为了简单起见,下面的示例被剪掉了。

var res = "group{,\
itemsToRenameGrp: Group{,\
    itemsToRenameDD: DropDownList{},\
    help: Button{},\
},\
listTabPnl: Panel{,\
    listOfItemsTab: Panel{,\
        listOfItemsPnl: Panel{,\
            listOfItemsLB: ListBox{},\
        },\
        confirmChanges: Button{},\
    },\
    badItemsTab: Panel{,\
        errorLogET: EditText{},\
    },\
},\
}";

我需要为变量赋值创建这样的路径:

itemsToRenameGrp.itemsToRenameDD
itemsToRenameGrp.help

listTabPnl.listOfItemsTab.listOfItemsPnl
listTabPnl.listOfItemsTab.listOfItemsPnl.listOfItemsLB
listTabPnl.listOfItemsTab.confirmChanges

listTabPnl.badItemsTab
listTabPnl.badItemsTab.errorLogET

我知道必须有一种方法通过 RegExp 来解析制表符空格或“},\”部分结尾才能使这项工作正常进行,但我自己无法弄清楚解决方案。任何帮助表示赞赏。谢谢。

【问题讨论】:

  • 请不要在您的问题中添加“已解决”和解决方案。它使 Stack Overflow 的整个点作为 问答 资源无效。如果您自己的解决方案与当前答案有很大不同,您可以随时自己添加一个。
  • Appologies,试图让人们不必为我已经解决的问题花费时间而头疼。
  • 添加您自己的答案!只是不要将其编辑到问题中。

标签: javascript regex extendscript resourcestring


【解决方案1】:

这很乱,但我终于找到了能满足我想要的东西。

解决方案:

var res = "group{,\
    itemsToRenameGrp: Group{,\
        itemsToRenameDD: DropDownList{},\
        help: Button{},\
    },\
    listTabPnl: Panel{,\
        listOfItemsTab: Panel{,\
            listOfItemsPnl: Panel{,\
                listOfItemsLB: ListBox{},\
            },\
            confirmChanges: Button{},\
        },\
        badItemsTab: Panel{,\
            errorLogET: EditText{},\
        },\
    },\
}";

var lines = res.split("\n");
var numLines = lines.length;
var variablePaths = new Array();
var val, newVal, firstColon, firstBrace, lastBrace, tabLength, oldTabLength, path, splitPath;
path = "";
oldTabLength = 0;
if(numLines > 0){
    for(var r=0; r<numLines; r++){
        val = lines[r];
        firstColon = val.indexOf(":");
        firstBrace = val.indexOf("{");
        lastBrace = val.lastIndexOf("}");
        try{tabLength = val.match(/\t/g).length}catch(err){};   /*  Count tabs  */
        if(firstColon > 0 && firstBrace > 0){   /*  Valid possible element line */
            if(firstColon < firstBrace){    /*  Confirmed element line  */
                newVal = val.substring(0, firstColon);  /*  Strip line down to just name and leading tabs   */
                if(tabLength > oldTabLength){   /*  Checks for line indent (child element)  */
                    path += "." + newVal.replace(new RegExp("\t", "g"), "");
                }else if(tabLength == oldTabLength){    /*  Checks for line indent match (same parent as previous element)  */
                    path = path.substring(0, path.lastIndexOf(".")) + "." + newVal.replace(new RegExp("\t", "g"), "");
                }else  if(tabLength < oldTabLength){    /*  Checks for line indent (new parent to add)  */
                    splitPath = path.split(".");
                    try{    /*  This section adjusts how far back in heirarchy to remove    */
                        if(tabLength > 0){
                            splitPath.length -= ((oldTabLength - tabLength)+1);
                        }else{
                            splitPath.length -= (oldTabLength - tabLength);
                        }
                    }catch(err){};
                    path = splitPath.join(".").toString() + "." + newVal.replace(new RegExp("\t", "g"), "");    /*  Creates new cleaned up string path (tabs removed)   */
                }
                oldTabLength = tabLength;
                if(tabLength >= oldTabLength){
                    variablePaths.push(path);   /*  Populates array */
                }
            }
        }
    }
}else{
    alert("Nothing to process");
}

alert("Element Names:\n" + variablePaths.join("\n"));

– 大卫·托尔诺

【讨论】:

    【解决方案2】:

    另一种可能是解析完成的窗口而不是字符串,如下所示:

    function loadNamedWidgets(cont, _target){
        // cont : ScruitUI container
        // _target : Object
        var k, K, child, id;
        K=cont.children.length;
        for (k=0; k<K; k++){
            child = cont.children[k];
            if (/^(Window|Panel|Group)$/.test(child.constructor.name)){
                loadNamedWidgets(child, _target);
                }
            else{
                // check that a ownProperty of cont is same as child
                for (id in cont){
                    if (cont.hasOwnProperty(id)){
                        if (cont[id] === child) {_target[id] = child; break;};
                        }
                    else break;
                    };
                };
            };
        return;
        };
    

    测试: 在下面的测试中, *radio1 和 radio2 将被写入两次,但来自 p2 的那些将覆盖来自 p1 的那些(名称冲突), *titleST(未命名)添加在末尾不会出现,而 valueET(命名)会出现。

    var w = new Window("palette{\
                text : 'hi',\
                header : Group{\
                            superBtn : Button{},\
                            extraBtn : Button{},\
                            helpBtn : Button{},\
                            },\
                body: Group{\
                            p1 : Panel{\
                                        _tag : 1,\
                                        radio1 : RadioButton{},\
                                        radio2 : RadioButton{},\
                                        },\
                            p2 : Panel{\
                                        _tag : 2,\
                                        radio1 : RadioButton{},\
                                        radio2 : RadioButton{},\
                                        },\
                            },\
                console : Group{\
                            consoleET : EditText{text: '', properties: {readonly: true}},\
                            },\
                footer : Group{}\
                }");
    var titleST = w.footer.add("statictext{text : 'title'}");
    var valueET = w.footer.valueET = w.footer.add("edittext{text : '0000'}");
    var binds = {};
    loadNamedWidgets(w, binds);
    
    $.writeln(binds.toSource());
    

    【讨论】:

      【解决方案3】:

      我同意查看复杂的资源字符串然后必须将“路径”写入要使用的 UI 元素是相当麻烦的。我不确定 RegEx 是不是方法,我也没有深入研究它,但我想出的解决方案是创建一个函数,该函数返回元素的“扁平路径”,以便我可以参考他们轻松。如果资源字符串发生变化,那么我所要做的就是修改“扁平路径”函数来解决这些变化——这样我就不需要在代码的其他地方进行任何更改。

      例如,给定您发布的代码,我会创建一个看起来像这样的函数:

      function getGUI(ui){
      
        var gui = {};
      
        gui.lRename  = ui.itemsToRenameGrp.itemsToRenameDD;
        gui.bHelp    = ui.itemsToRenameGrp.help;
        gui.lItems   = ui.listTabPn1.listOfItemsTab.listOfItemsPn1.listOfItemsLB;
        gui.bConfirm = ui.listTabPn1.listOfItemsTab.confirmChanges;
        gui.eLog     = ui.listTabPn1.badItemsTab.errorLogET;
      
        return gui;
      }
      

      然后,当您使用 Window 对象“构建”完您的 UI 后,像这样调用该函数:

      var _mainGUI = getGUI({variable that holds your Window object});
      

      现在,当您想要访问元素时,只需像这样调用它们:

      _mainGUI.lRename
      _mainGUI.bConfirm
      _mainGUI.lItems
      

      ...等等。因此,如果您对资源字符串进行了更改,则只需修改 getGUI 函数,您的应用程序代码就可以保持不变。希望这会有所帮助,对于最初的、不完整的回答帖子,我深表歉意——我不小心太早地点击了提交按钮。

      【讨论】:

        【解决方案4】:

        那些反斜杠应该是不需要的,当你用三个双引号开始一个字符串时,会有一种特殊的多行模式。

        与其解析源代码,我会将其留给 ExtendScript 并迭代生成的 UI 对象。

        【讨论】:

        • 解析背后的原因是帮助自动创建要在脚本中使用的附加文本。试图为我节省一些打字时间。在 ExtendScript 中迭代 UI 对象的问题是,我无法访问分配给每个元素的实际资源名称。它只允许访问根据元素分配的已创建元素的“文本”、“标题”或“名称”。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-21
        • 1970-01-01
        • 1970-01-01
        • 2018-03-08
        • 2021-12-29
        • 2013-01-08
        • 1970-01-01
        相关资源
        最近更新 更多