Illustrators RE 7

| コメント(1) | トラックバック(0)

せんじつ「ウェブク」なんての見つけて適当にアドレス放り込んでみました。サイトの評価額が表示されるのですが、どういった評価なのでしょう???
色々と数字が並べられているのですが、いったいどこから引っぱってきているのか興味津々です。恐らく大半の数値は予測値とかなのでしょうが一日のページビューそんなにありませんってば!全くもう適当すぎますw
話は変わりますが、このクソ暑い中エアコンが止まっています。外気温35℃、室内は31℃とかもう集中して物事に取り組める状態を逸脱しているような気もします。机の下に水入りバケツでも置いとこうかしらんw
と言う訳で、このネタ最終です。

さて、最後の大物です。まず基本的な動作をご説明致しましょう。replacerなんて名前を付けちゃったこのファンクション、引数はtextRangeオブジェクトとgrepperから帰ってきた2次元配列及び差し替え文字列の3つです。変数の設定後スタイル絡みの振い分けが行われ、alternateGryphやスタイル当てたりした後置換されます。

var replacer = function (txRange, tg, str){ //txRange:textRange, tg:targetArray, str:swapString,
    var c = new Array();
    var i,j,cstyle,tmp;
    var fl = 0;
    var num =tg.length;
    if (ls2.selection.index==0){
        cstyle= null;
        } else {
            cstyle = charStyles.list()[ls2.selection.index-1];
            }
    if (cstyle==null&&!r0.value||ls3.selection.index==0&&!r0.value){
        alert("No Style selected.");
        return false
        }
    for (i=0;i<num;i++){
        c = tg.pop();
        centerView (getFrame(txRange,c[0]));
        tgtSlection (txRange.parent.textRange, c[0], c[1]);
        if (!allReplace) {
            fl = confirmReplace();
            if (fl==-1) return null;
            if (fl==0) continue;
            if (fl==2) allReplace= true;
            }
        if (r2.value||ls3.selection.index!=0&&ckbx.value) {
            str = txRange.parent.textRange.characters[c[0]].contents, tmp = "";
            for (j=c[0]+c[1]-1;j>c[0];j--) {
                tmp = txRange.parent.textRange.characters[j].contents + tmp;
                txRange.parent.textRange.characters[j].remove();
                }
            str += tmp;
            } else {
                for (j=c[0]+c[1]-1;j>c[0];j--) txRange.parent.textRange.characters[j].remove();
                }
        if(r1.value||r2.value) {
            cstyle.applyTo(txRange.parent.textRange.characters[c[0]], true);
            }
        if(ls3.selection.index!=0&&ckbx.value){
            txRange.parent.textRange.characters[c[0]].characterAttributes.alternateGlyphs
            = getGryph();
                }
        txRange.parent.textRange.characters[c[0]].characters.addBefore(str);
        txRange.parent.textRange.characters[c[0]+str.length].remove();
        doReplace++;
        redraw();
        }
    return true;
    }

こんな感じのファンクションですが、取りあえずメインのループだけ解説しましょう。

    for (i=0;i<num;i++){
        c = tg.pop();
        centerView (getFrame(txRange,c[0]));
        tgtSlection (txRange.parent.textRange, c[0], c[1]);
        if (!allReplace) {
            fl = confirmReplace();
            if (fl==-1) return null;
            if (fl==0) continue;
            if (fl==2) allReplace= true;
            }
        if (r2.value||ls3.selection.index!=0&&ckbx.value) {
            str = txRange.parent.textRange.characters[c[0]].contents, tmp = "";
            for (j=c[0]+c[1]-1;j>c[0];j--) {
                tmp = txRange.parent.textRange.characters[j].contents + tmp;
                txRange.parent.textRange.characters[j].remove();
                }
            str += tmp;
            } else {
                for (j=c[0]+c[1]-1;j>c[0];j--) txRange.parent.textRange.characters[j].remove();
                }
        if(r1.value||r2.value) {
            cstyle.applyTo(txRange.parent.textRange.characters[c[0]], true);
            }
        if(ls3.selection.index!=0&&ckbx.value){
            txRange.parent.textRange.characters[c[0]].characterAttributes.alternateGlyphs
            = getGryph();
                }
        txRange.parent.textRange.characters[c[0]].characters.addBefore(str);
        txRange.parent.textRange.characters[c[0]+str.length].remove();
        doReplace++;
        redraw();
        }

ここでひとつ注意が必要なのはストーリーの頭から処理しちゃうと文字の位置が変わっちゃう点です。検索する文字列と置換する文字列が同じ文字数という保証はありませんので。なので処理は次の様に配列の後ろから抜き出しつつ行います。

        c = tg.pop();

続いて置換処理の是非を問うのですが、その前に該当箇所を判り易くしましょう。

        centerView (getFrame(txRange,c[0]));
        tgtSlection (txRange.parent.textRange, c[0], c[1]);

先日のファンクションを使います。該当箇所を画面中央に持ってきて、なおかつ選択した状態にします。
で、問題になるのはtextRangeに対するアクセス速度の問題です。textRangeに対してstyleを適用する等のアクセスを行う場合、信じられない程の実行時間を要します。まあ、ここらへんがインタープリタの限界かとも思うのですがそうも言ってられません。(お前のコードがまずいんだよってのはなしの方向で)
でどうするかと言うとプロパティをいじる対象を最小にします。下記をご覧下さい。

swapProceess.png


要は一文字だけ残してあとは削除。プロパティいじって...という流れ。

        txRange.parent.textRange.characters[c[0]].characters.addBefore(str);
        txRange.parent.textRange.characters[c[0]+str.length].remove();

置換処理自体もcontentsをいじらずaddBforeメソッドを使います。最後に残しておいた文字を削除して置換終了。

最後にスクリプト全体を掲載しておきましょう。

var grepper = function(obj, ofst, tglen, re){ //obj:Story ofst:CharacterOffset tglen:targets length re:REObject
    var result =new Array();
    var swp,st,ed;
    var pos = 0, len = 0;
    var tgcStyle,tgpStyle,cstyle,pstyle,tg,tgtStr;

    if (ls0.selection.index==0){ //get target characterStyle
        cstyle= null;
        } else {
            cstyle = charStyles.list()[ls0.selection.index-1];
            }
    if (ls1.selection.index==0){ //get target paragraphStyle
        pstyle= null;
        } else {
            pstyle = paraStyles.list()[ls1.selection.index-1];
            }

    var tmp="";
    for (var j=0;j<ofst;j++) tmp+="`";
    tgtStr = tmp + obj.textRange.contents.substr(ofst,tglen);
    while(re.test(tgtStr)){
        st = tgtStr.match(re)+"";
        swp = "";
        for(var i=0;i<st.length;i++) swp += "`";
        pos = tgtStr.indexOf(st);
        len = st.length;
        if (r0.value||(cstyle==null&&pstyle==null)){
            result.push([pos, len]);
            } else {
                tgcStyle = obj.characters[pos+ofst].characterStyles;
                tgpStyle = obj.characters[pos+ofst].paragraphStyles;
                if (tgcStyle!=cstyle&&cstyle!=null) continue;
                if (tgpStyle!=pstyle&&pstyle!=null) continue;
                result.push([pos, len]);
                }
        tgtStr = tgtStr.replace(st, swp);
        }
    return result;
    }


var replacer = function (txRange, tg, str){ //txRange:textRange, tg:targetArray, str:swapString,
    var c = new Array();
    var i,j,cstyle,tmp;
    var fl = 0;
    var num =tg.length;
    if (ls2.selection.index==0){
        cstyle= null;
        } else {
            cstyle = charStyles.list()[ls2.selection.index-1];
            }
    if (cstyle==null&&!r0.value||ls3.selection.index==0&&!r0.value){
        alert("No Style selected.");
        return false
        }
    for (i=0;i<num;i++){
        c = tg.pop();
        centerView (getFrame(txRange,c[0]));
        tgtSlection (txRange.parent.textRange, c[0], c[1]);
        if (!allReplace) {
            fl = confirmReplace();
            if (fl==-1) return null;
            if (fl==0) continue;
            if (fl==2) allReplace= true;
            }
        if (r2.value||ls3.selection.index!=0&&ckbx.value) {
            str = txRange.parent.textRange.characters[c[0]].contents, tmp = "";
            for (j=c[0]+c[1]-1;j>c[0];j--) {
                tmp = txRange.parent.textRange.characters[j].contents + tmp;
                txRange.parent.textRange.characters[j].remove();
                }
            str += tmp;
            } else {
                for (j=c[0]+c[1]-1;j>c[0];j--) txRange.parent.textRange.characters[j].remove();
                }
        if(r1.value||r2.value) {
            cstyle.applyTo(txRange.parent.textRange.characters[c[0]], true);
            }
        if(ls3.selection.index!=0&&ckbx.value){
            txRange.parent.textRange.characters[c[0]].characterAttributes.alternateGlyphs
            = getGryph();
                }
        txRange.parent.textRange.characters[c[0]].characters.addBefore(str);
        txRange.parent.textRange.characters[c[0]+str.length].remove();
        doReplace++;
        redraw();
        }
    return true;
    }


function get_stRange(slct){
    var frms = new Array();
    var strys = new Array();
    var st = new Array();
    var tmp = new Array();

    //get textFrames in each stories
    for (var i=0;i<slct.length;i++) if (slct[i].typename=='TextFrame') frms.push(slct[i]);
    var j=0,k=0;
    while (frms.length>0){
        st[j] = new Array();
        loop = frms[0].textRange.parent.textFrames.length;
        for (i=0;i<loop;i++){
            for (k=0;k<frms.length;k++){
                if (frms[0].textRange.parent.textFrames[i]==frms[k]){
                    st[j].push(frms[k]);
                    frms.splice(k,1);
                    break;
                    }
                }
            }
        if (st[j].length>0) j++;
        }

    for (i=0;i<st.length;i++){
        ofst = st[i][0].textRange.characterOffset - 1;
        len = st[i][0].characters.length;
        if (st[i].length>1){
            for (j=1;j<st[i].length;j++){
                if (st[i][j-1].nextFrame==st[i][j]){
                    len += st[i][j].characters.length;
                    } else {
                        strys.push([st[i][0].textRange.parent, ofst, len]);
                        ofst = st[i][j].textRange.characterOffset - 1;
                        len = st[i][j].characters.length;
                        }
                }
            strys.push([st[i][0].textRange.parent, ofst, len]);
            } else {
                strys.push([st[i][0].textRange.parent, ofst, len]);
                }
        }
    strys.sort();
    strys.reverse();
    return strys;
    }

function getPosition(txFrame){ //txFrame:TextFrame  return texRanges characteroffset and contents length
    var tgtRange = txFrame.textRange;
    var st = txFrame.textRange.characterOffset-1;
    var len = txFrame.characters.length;
    return [tgtRange, st, len];
    }


function getGryph(){
    var result;
    switch(ls3.selection.index){
        case 1:
        result = AlternateGlyphsForm.DEFAULTFORM;
        break;
        case 2:
        result = AlternateGlyphsForm.EXPERT;
        break;
        case 3:
        result = AlternateGlyphsForm.FULLWIDTH;
        break;
        case 4:
        result = AlternateGlyphsForm.HALFWIDTH;
        break;
        case 5:
        result = AlternateGlyphsForm.JIS04FORM;
        break;
        case 6:
        result = AlternateGlyphsForm.JIS78FORM;
        break;
        case 7:
        result = AlternateGlyphsForm.JIS83FORM;
        break;
        case 8:
        result = AlternateGlyphsForm.JIS90FORM;
        break;
        case 9:
        result = AlternateGlyphsForm.PROPORTIONALWIDTH;
        break;
        case 10:
        result = AlternateGlyphsForm.QUARTERWIDTH;
        break;
        case 11:
        result = AlternateGlyphsForm.THIRDWIDTH;
        break;
        case 12:
        result = AlternateGlyphsForm.TRADITIONAL;
        break;
        default:
        result = AlternateGlyphsForm.DEFAULTFORM;
        break;
        }
    return result
    }


//building user interface
//--------gets Document styles---------------------------------------------
var  items0,items1 = new Array();

var charStyles= {
    styles: app.activeDocument.characterStyles,
    list: function(){
        var result = new Array();
        for (var i=0;i<this.styles.length;i++){
            result.push(this.styles[i]);
            }
        return result;
        },
    names: function(){
        var result = new Array();
        for (var i=0;i<this.styles.length;i++){
            result.push(this.styles[i].name);
            }
        return result;
        }
    }

var paraStyles = {
    styles: app.activeDocument.paragraphStyles,
    list: function(){
        var result = new Array();
        for (var i=0;i<this.styles.length;i++){
            result.push(this.styles[i]);
            }
        return result;
        },
    names: function(){
        var result = new Array();
        for (var i=0;i<this.styles.length;i++){
            result.push(this.styles[i].name);
            }
        return result;
        }
    }

var items0 = charStyles.names();
var items1 = paraStyles.names();
items0.unshift('----------');
items1.unshift('----------');
var gryphfrm = ["----------","DEFAULTFORM","EXPERT","FULLWIDTH","HALFWIDTH",
                "JIS04FORM","JIS78FORM","JIS83FORM","JIS90FORM",
                "PROPORTIONALWIDTH","QUARTERWIDTH","THIRDWIDTH",
                "TRADITIONAL"];

var allReplace=false;
var doReplace = 0;

//-----make window object-----------------------------------------------------------------------------
var targetObj = ['selection', 'document', 'activeLayer'];
var d = new Window ('dialog', 'RE Grep for AI', [100,100,600,430]);
    var pnl0 = d.add('panel', [10,10,490,110] , 'RegExp Strings');
        var stTx0 = pnl0.add('statictext', [10,10,60,25], 'find');
        var vTx0 = pnl0.add('edittext', [70,10,460,45] , '', {multiline:true});
        var stTx1 = pnl0.add('statictext', [10,50,60,75] , 'replace');
        var vTx1 = pnl0.add('edittext', [70,50,460,85], '', {multiline:true});

     var pnl1 = d.add('panel', [10,120,490,280], 'Options');
        var r0 = pnl1.add('radiobutton', [10,10,150,41], "don't change styles");
        var r1 = pnl1.add('radiobutton', [10,30,150,61], 'change with styles');
        var r2 = pnl1.add('radiobutton', [10,50,150,81], 'change only styles');
        r0.value = true;
        var ckbx = pnl1.add('checkbox',[10,70,150,101], 'change with gryphs');
        ckbx.value = false;
        var p0 = pnl1.add('panel',[150,5,470,70], 'search styles')
            var ls0 = p0.add('dropdownlist', [100,10,310,25], items0);
            var ls1 = p0.add('dropdownlist', [100,30,310,45], items1);
            ls0.selection=0;
            ls1.selection=0;
            var stTx2 = p0.add('statictext', [10,10,100,25] , 'character style');
            var stTx3 = p0.add('statictext', [10,30,100,45] , 'paragraph style');
        var p1 = pnl1.add('panel', [150,75,470,145], 'replace styles')
            var ls2 = p1.add('dropdownlist', [100,10,310,25], items0);
            var ls3 = p1.add('dropdownlist', [100,30,310,45], gryphfrm);
            ls2.selection=0;
            ls3.selection=0;
            var stTx4 = p1.add('statictext', [10,10,100,25] , 'character style');
            var stTx5 = p1.add('statictext', [10,30,100,45] , 'alternate gryph');
        var stTx6 = pnl1.add('statictext', [10,100,100,115] , 'select target');
        var ls4 = pnl1.add('dropdownlist', [10,120,125,140], targetObj);
        ls4.selection = 0;
    var btn0 = d.add('button', [330,290,400,310], 'cancel', {name:'cancel'});
    var btn1 = d.add('button', [410,290,480,310] , 'apply', {name:'ok'});
    btn1.onClick = function (){
        if(main()){
            alert ("Total replaced targets = " + doReplace);
            }
        };
d.show();


//---------main function-------------------------------------------------------
function main(){
    d.close();
    var REPLACE = vTx1.text;
    var seTgt = eval('/' + vTx0.text + '/');

    switch(ls4.selection.index){
        case 0: //selection
        var tgArray = new Array();
        var targets = app.activeDocument.selection;
        if (targets.typename=='TextRange') {
            resultArray = grepper(targets.parent, targets.characterOffset-1, targets.length, seTgt);
            if (replacer(targets, resultArray, REPLACE)==null) return false;
            return true;
            }
        var tgRange = new Array();
        tgRange = get_stRange(targets);
        for (var i=0;i<tgRange.length;i++){
            resultArray = grepper(tgRange[i][0], tgRange[i][1], tgRange[i][2], seTgt);
            if (resultArray.length==0) continue;
            if (replacer(tgRange[i][0].textRange, resultArray, REPLACE)==null) return false;
            }
        return true;
        break;

        case 1: //document
        var targets = app.activeDocument.stories;
        for (var i=0;i<targets.length;i++){
            resultArray = grepper(targets[i], 0, targets[i].characters.length, seTgt);
                if (resultArray.length==0) continue;
                if (replacer(targets[i].textRange, resultArray, REPLACE)==null) return false;
            }
        return true;
        break;

        case 2: //layer
        var targets = app.activeDocument.activeLayer.stories;
        for (var i=0;i<targets.length;i++){
            resultArray = grepper(targets[i], 0, targets[i].characters.length, seTgt);
            if (resultArray.length==0) continue;
            if (replacer(targets[i], resultArray, REPLACE)==null) return false;
            }
        return true;
        break;            

        default:
        return false;
        }
    }

//--make view-------------------------------------------------------------------
function getFrame(tg, pos){ //tg:TextRanges
    var result = new Array();
    var frame = tg.parent.textFrames;
    var tgLen = tg.characters.length;
    var ofst = tg.characterOffset;
    for (var i=0;i<frame.length;i++){
        ofst -= frame[i].characters.length;
        if (ofst<=0) return frame[i];
        }
    }

function tgtSlection(obj, fstPos, len){
    obj.characters[fstPos].select(false);
    for (var i=fstPos+1;i<fstPos+len;i++){
        obj.characters[i].select(true);
        }
    redraw();
    }

function centerView(obj){
    var x = obj.position[0] + obj.width/2;
    var y = obj.position[1] + obj.height/2;
    app.activeDocument.activeView.centerPoint = [x, y];
    app.activeDocument.activeView.zoom= 1.5;
    }

//--confirm window----------------------------------------------------------------
function confirmReplace(){
    var result
    var cWin = new Window('dialog', 'Replace the target?', [100,100,400,170]);
    var stTx = cWin.add('statictext', [10,10,250,25] , "");
    var bt0 = cWin.add('button', [10,35,60,55], 'cancel', {name:'exit'});
    var bt1 = cWin.add('button', [70,35,130,55], 'skip', {name:'skip'});
    var bt2 = cWin.add('button', [140,35,200,55], 'replace', {name:'replace'});
    bt2.active = true;
    var bt3 = cWin.add('button', [210,35,270,55], 'all', {name:'all'});
    bt0.onClick = function (){
        result=-1;
        cWin.close();
        };
    bt1.onClick = function (){
        result=0;
        cWin.close();
        };
    bt2.onClick = function (){
        result=1;
        cWin.close();
        };
    bt3.onClick = function (){
        result=2;
        cWin.close();
        };
    cWin.show();
    return result;
    }

無駄に長いです。なんだか、いまいちなのです。どうしたものか...
まあ、皆さんは他にしっかりしたモノが世に出回っていますので参考程度にしておいて下さい。
話は全く関係ないのですが、CS_SDK系のコードを集約する為にgithubにパブリックなリポジトリ開設しています。

トラックバック(0)

トラックバックURL: /368

コメント(1)

コード見ている限りではCS3でも動きそう。

コメントする

このブログ記事について

このページは、tenが2011年8月10日 12:18に書いたブログ記事です。

ひとつ前のブログ記事は「QR codeにまつわる色々」です。

次のブログ記事は「Extension Builder trial is now available」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

OpenID対応しています OpenIDについて
Powered by Movable Type 5.12

    follow? twitter...     
    available on exchange