Illustratorには文字スタイル・段落スタイル・グラフィックスタイルという3つのスタイル機能があります。
それぞれあらかじめ書式や色などを定義しておいて,それをオブジェクトに適用すると決めた通りの設定に変わるというものです。
ただ単に見た目を楽に統一できるだけではありません。スタイルの設定を上書きすれば,そのスタイルが割り当てられているすべてのオブジェクトで同じように変更されるという特徴もあり,後からの修正にとても強くなります。
そんな強力なスタイル機能ですが,Illustratorではキーボードショートカットを割り当てることができません。「InDesignならできるんだからIllustratorもがんばってよ」と言いたくなってしまいますよね。
そこで今回は,JavaScriptとスクリプトにショートカットを割り当てるソフトの組み合わせで,文字・段落・グラフィックスタイルのショートカットを使えるようにします。
準備
この記事を読むような方はすでに知っているかと思いますが,以下のようなソフトを使うとスクリプトにキーボードショートカットを割り当てることができます。事前にダウンロードし,使える状態にしておいてください。
- SPAi(mac)
- ScriptKeyAi(mac)
- Keyboard Maestro(mac)
- Karabiner(mac)
- Automator(mac)
- Script Slot Lite(mac/win)
- Ai Script Assist(win)
- AutoHotkey(win)
それから,こちらのファイルをダウンロードしてください。
applyStyleViaShortcutKey.zip
サンプルとして3つのファイルが入っています。それぞれ[標準文字スタイル]・標準段落スタイル・グラフィックスタイル[デフォルト]を適用するJavaScriptで,ファイル名以外の中身はまったく同じです。
設定方法
以下の方法でスタイルにキーボードショートカットを割り当てます。
- スタイルを適用するJavaScriptのファイル名を p=スタイル名.jsx のような特定の形式にすることで,文字/段落/グラフィック等スタイルの種類と,適用するスタイル名を指定(ファイル名の再編集により,それらの設定を変えることができる)
- スクリプトファイルをショートカット設定ソフトに登録し,自分の好きなキーを割り当てる
- 割り当てたいスタイルの数だけ前のステップを繰り返す
つまりスタイルの数だけスクリプトファイルを複製しなくてはいけないのですが,ファイル名を変えるだけで,割り当てたキーはそのままに適用するスタイルを変更できます。そのためスクリプト自体を修正するより少し楽に管理できるというわけです。
ファイル名の形式
スタイルの種類文字=スタイル名.jsx
スタイルの種類文字は,文字(character)スタイルの場合c,段落(paragraph)スタイルの場合p,グラフィック(graphic)スタイルの場合gが入ります。
スタイル名はIllustratorのスタイルパネルに出ている名前そのものです。
例えば「白フチ」というグラフィックスタイルの場合 g=白フチ.jsx となります。
ファイル名の変更
通常ではスクリプトのファイル名を変更してしまうと,ショートカット設定ソフトでファイルが行方不明になり,使用できなくなってしまいます。
その点もし使っているソフトがSPAiなら,エイリアスというファイル名の変更を追跡してくれる形式で管理してもらえます。なので何も考えずに登録してください。ファイル名を変えても,キー割当はそのまま使うことができます。
その他のソフトの場合,ファイル本体でなくそのファイルのエイリアス(Windowsで言うショートカット)を自分で作って登録すると同じ効果があります。登録できるかどうかはそのソフトによるのですが…。
例えばKeyboard Maestroの場合は以下のようにします。
ただし「c=[標準文字スタイル].jsx のエイリアス」のように名前をつけてしまうと,本体のファイルを改名したときややこしくなるので,エイリアスには「ctrl+1」など割り当てたキーを入れるのがおすすめです。
変更例
c=[標準文字スタイル].jsx を ctrl+1 で登録した後,そのファイルの名前を g=白フチ.jsx に変えると(エイリアスは変えない),ctrl+1 でグラフィックスタイル「白フチ」を適用するようになります。
使用方法
こちらは単純で,スタイルを適用したいオブジェクトを選択して設定したキーボードショートカットを押すだけです。オーバーライドはクリアする設定になっています。なんとも軽快!
これでまた少し仕事が速くなりました。今日もさっさと仕事を切り上げて好きなことをしましょう!
コードはこちら
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
/** * @fileOverview スクリプトのファイル名からスタイル名を取り出し,選択しているアイテムに適用する。<br /> * p=styleName.jsx のpがスタイルの種類,styleNameがスタイル名を表す。=は区切り文字として必要。<br /> * cで文字スタイル,pで段落スタイル,gでグラフィックスタイルを適用 * @version 1.0.1 * @author sttk3.com */ #target 'illustrator' (function() { if(app.documents.length <= 0) {return ;} var doc = app.documents[0] ; // 実行中のスクリプトのファイル名を取得 var tempName = new File($.fileName).name ; // 濁点・半濁点結合処理。macの場合,しないとそれらを使っているスタイルが見つからない tempName = combineDakuten(tempName) ; // ファイル名から引数を生成 var filenameStr = decodeURIComponent(tempName.replace(/\.js(?:x|xbin)?$/i, '')) ; var matchObj = filenameStr.match(/^([cpgcpgCPG])[\s ]*[==](.+)$/i) ; if(matchObj) { var modeFlag = matchObj[1] ; modeFlag = modeFlag.replace(/[A-Za-z0-9_]/g, function(s) {return String.fromCharCode(s.charCodeAt(0) - 0xFEE0)}) ; modeFlag = modeFlag.toLowerCase() ; var styleName = matchObj[2] ; } else { return ; } // selectionとスタイルを取得 var styleObj, targetItems ; try { switch(modeFlag) { case 'c' : // XXXStyles[styleName]にした場合,[0]と['0']を区別できないのでgetByNameを使う styleObj = doc.characterStyles.getByName(styleName) ; targetItems = getTextSelection() ; break ; case 'p' : styleObj = doc.paragraphStyles.getByName(styleName) ; targetItems = getTextSelection() ; break ; case 'g' : styleObj = doc.graphicStyles.getByName(styleName) ; targetItems = app.selection ; break ; default : return ; break ; } } catch(e) { return ; } // selectionにスタイルを適用する。オーバーライドはクリアする for(var i = 0, len = targetItems.length ; i < len ; i++) { styleObj.applyTo(targetItems[i], true) ; } })() ; /** * selectionを常にtextRangeのArrayとして返す * @return {Array} 選択なしの場合[]を返す */ function getTextSelection() { var sel = app.selection ; var selLength = sel.length ; var res = [] ; switch(sel.constructor.name) { case 'Array' : if(!sel[0]) {return res ;} for(var i = 0 ; i < selLength ; i++) { var itemType = sel[i].constructor.name ; if(itemType == 'TextFrame') { res.push(sel[i].textRange) ; } else if(itemType == 'TextRange') { res.push(sel[i]) ; } } break ; case 'TextRange' : res.push(sel) ; break ; } return res ; } /** * 分割された濁点・半濁点を結合された文字にする。ウムラウトなどは無視する * @param {String} str 対象の文字列。URIエンコードされたもの * @return {String} 変換されたテキスト */ function combineDakuten(str) { // 置換対象の文字とその順番 // ゔがぎぐげござじずぜぞだぢづでどばぱびぴぶぷべぺぼぽヴガギグゲゴザジズゼゾダヂヅデドバパビピブプベペボポ // 分割された文字 var nfd = ['%E3%81%86%E3%82%99', '%E3%81%8B%E3%82%99', '%E3%81%8D%E3%82%99', '%E3%81%8F%E3%82%99', '%E3%81%91%E3%82%99', '%E3%81%93%E3%82%99', '%E3%81%95%E3%82%99', '%E3%81%97%E3%82%99', '%E3%81%99%E3%82%99', '%E3%81%9B%E3%82%99', '%E3%81%9D%E3%82%99', '%E3%81%9F%E3%82%99', '%E3%81%A1%E3%82%99', '%E3%81%A4%E3%82%99', '%E3%81%A6%E3%82%99', '%E3%81%A8%E3%82%99', '%E3%81%AF%E3%82%99', '%E3%81%AF%E3%82%9A', '%E3%81%B2%E3%82%99', '%E3%81%B2%E3%82%9A', '%E3%81%B5%E3%82%99', '%E3%81%B5%E3%82%9A', '%E3%81%B8%E3%82%99', '%E3%81%B8%E3%82%9A', '%E3%81%BB%E3%82%99', '%E3%81%BB%E3%82%9A', '%E3%82%A6%E3%82%99', '%E3%82%AB%E3%82%99', '%E3%82%AD%E3%82%99', '%E3%82%AF%E3%82%99', '%E3%82%B1%E3%82%99', '%E3%82%B3%E3%82%99', '%E3%82%B5%E3%82%99', '%E3%82%B7%E3%82%99', '%E3%82%B9%E3%82%99', '%E3%82%BB%E3%82%99', '%E3%82%BD%E3%82%99', '%E3%82%BF%E3%82%99', '%E3%83%81%E3%82%99', '%E3%83%84%E3%82%99', '%E3%83%86%E3%82%99', '%E3%83%88%E3%82%99', '%E3%83%8F%E3%82%99', '%E3%83%8F%E3%82%9A', '%E3%83%92%E3%82%99', '%E3%83%92%E3%82%9A', '%E3%83%95%E3%82%99', '%E3%83%95%E3%82%9A', '%E3%83%98%E3%82%99', '%E3%83%98%E3%82%9A', '%E3%83%9B%E3%82%99', '%E3%83%9B%E3%82%9A'] ; // 結合された文字 var nfc = ['%E3%82%94', '%E3%81%8C', '%E3%81%8E', '%E3%81%90', '%E3%81%92', '%E3%81%94', '%E3%81%96', '%E3%81%98', '%E3%81%9A', '%E3%81%9C', '%E3%81%9E', '%E3%81%A0', '%E3%81%A2', '%E3%81%A5', '%E3%81%A7', '%E3%81%A9', '%E3%81%B0', '%E3%81%B1', '%E3%81%B3', '%E3%81%B4', '%E3%81%B6', '%E3%81%B7', '%E3%81%B9', '%E3%81%BA', '%E3%81%BC', '%E3%81%BD', '%E3%83%B4', '%E3%82%AC', '%E3%82%AE', '%E3%82%B0', '%E3%82%B2', '%E3%82%B4', '%E3%82%B6', '%E3%82%B8', '%E3%82%BA', '%E3%82%BC', '%E3%82%BE', '%E3%83%80', '%E3%83%82', '%E3%83%85', '%E3%83%87', '%E3%83%89', '%E3%83%90', '%E3%83%91', '%E3%83%93', '%E3%83%94', '%E3%83%96', '%E3%83%97', '%E3%83%99', '%E3%83%9A', '%E3%83%9C', '%E3%83%9D'] ; for(var i = 0, len = nfd.length ; i < len ; i++) { str = str.replace(new RegExp(nfd[i], 'ig'), nfc[i]) ; } return str ; } |
このサイトで配布しているスクリプトやその他のファイルを,無断で転載・配布・販売することを固く禁じます。それらの使用により生じたあらゆる損害について,私どもは責任を負いません。
スクリプトやファイルのダウンロードを行った時点で,上記の規定に同意したとみなします。