ごんれのラボ

iOS、Android、Adobe系ソフトの自動化スクリプトのことを書き連ねています。

Illustratorドキュメントで使用しているフォント名をテキストに書き出す

概要

昔書いた記事が読みづらかったので、リライト。
Illustratorファイルで使用しているフォント名を、ざっくりでいいので取得できないかなーと思って書いたAppleScript。

仕様

  • フォント名とIllustratorドキュメントのフルパスをファイルに書き出す
  • フォント名は、フォントファミリーとフォントフェイスを結合して生成
  • フォントファミリーとフォントフェイスが同数じゃなかったらログファイルにはエラーを書き込む

サンプル

適当なドキュメントを作成して、キャプチャしたもの。

f:id:macneko-ayu:20171019002107j:plain
Illustratorドキュメントで確認した使用フォント

f:id:macneko-ayu:20171019002111j:plain
出力されたフォントリスト

使い方

最初にやること

  1. この記事の最後にあるダウンロードリンクからzipをダウンロード
  2. zipを解凍する
  3. IllustratorFontSearch.txt をテキストエディタで開いて内容をコピー
  4. 「スクリプトエディタ」を起動して、メニューから 新規 を選択し、開いたドキュメントにペーストボードの内容をペースト
  5. メニューから 保存 を選択
  6. 保存ダイアログのファイルフォーマットを アプリケーション にして、ダウンロードしたフォルダに保存

フォントリストを書き出したいとき

  1. Illustratorドキュメントを 最初にやること で作成したアプリケーション(特に変更しなければ IllustratorFontSearch.app のはず)にドラッグ&ドロップする
  2. デスクトップに フォントリスト.txt が作成される

ソースコード

AppleScript

on open thisList
    tell application "Finder"
        --Rubyのバージョンチェック
        if exists ((home as text) & ".bash_profile") then
            set ruby_version to do shell script "source ~/.bash_profile; ruby -e 'print \"ERROR\" if RUBY_VERSION <= \"1.8.1\"'"
        else
            set ruby_version to do shell script "ruby -e 'print \"ERROR\" if RUBY_VERSION <= \"1.8.1\"'"
        end if
        if ruby_version is "ERROR" then
            display dialog "このスクリプトはRubyバージョンが1.8.2以上で動作します"
            error number -128
        end if
        
        --変数初期化        
        set dPath to desktop as text --デスクトップのパス取得
        set textFile to dPath & "フォントリスト.txt" --ログ書き出し 用のテキストファイルの名前
        set processLog to "" --エラーが出たファイルのパスを入れる箱
        set skipFile to 0 --CS2以下のファイルのカウント用
        
        --Rubyのファイルを取得
        set my_script_name to "IllustratorFontSearch.rb"
        set my_script_folder to parent of (path to me) as Unicode text
        set my_script to my_script_folder & my_script_name
        set my_script to (quoted form of POSIX path of my_script)
        
        --ここからメイン処理
        repeat with k in thisList
            
            set input_file to (quoted form of POSIX path of contents of k) as Unicode text --Unicode textに変換しないとダメ
            
            if exists ((home as text) & ".bash_profile") then
                do shell script "source ~/.bash_profile; ruby " & my_script & " " & input_file --Rubyで処理して戻り値を取得
            else
                do shell script "ruby " & my_script & " " & input_file --Rubyで処理して戻り値を取得
            end if
            set outputList to result --変数に代入
            
            set processLog to processLog & "===" & (k as string) & "===" & (ASCII character (13))
            
            if outputList is "nil" then
                set processLog to processLog & "フォントが使用されていないようです" & (ASCII character (13))
            else if outputList is "error" then
                set processLog to processLog & "FamilyとFaceの数があいません" & (ASCII character (13))
            else
                set processLog to processLog & outputList & (ASCII character (13))
            end if
        end repeat
        
        --ログの書き出し
        if processLog is not "" then
            try
                set OutPutText to open for access textFile with write permission
                set eof OutPutText to 0
                write processLog to OutPutText
                close access OutPutText
            on error errMsg
                display dialog errMsg
                close access OutPutText
            end try
        end if
    end tell
    
    display dialog "終了しました"
end open

Ruby

#! ruby -Ku

require 'CGI'
require 'kconv'

temp = ""
fontFamilyList = [] ; #フォントのファミリーの入れ物
fontFaceList = [] ; #フォントの太さの入れ物
fontList = []

#XMP情報を抽出して変数に代入
def xmpRead(fileObj, temp)
    begin
        while line = fileObj.gets 
            line = line.toutf8
            line = CGI.unescapeHTML(line)#HTMLエスケープされてるのでアンエスケープ
            
            #XMP終了時に例外を発生させる
            if /^<\/x:xmpmeta>/ =~ line then
                raise "loop stop" #raiseで例外を発生できる
            end

            if temp == ""
                temp = line
            else
                temp = temp + line
            end
        end
    rescue
        return temp #tempを返す
    end
end

def IllustratorFontSearch(temp, fontFamilyList, fontFaceList, fontList)
    if /Adobe Illustrator CS2/ =~ temp
        raise "before CS2"
    end
    
    #ファミリーとフェイスを検索して配列にする
    fontFamilyList = temp.scan(/^\s+?<stFnt:fontFamily>(.+?)<\/stFnt:fontFamily>/)
    fontFaceList = temp.scan(/^\s+?<stFnt:fontFace>(.+?)<\/stFnt:fontFace>/)
    
    #空だったら
    if fontFamilyList == [] && fontFaceList == [] 
        fontList = "nil"#nilを文字として返す
    elsif fontFamilyList.length == fontFaceList.length
        #配列の数だけ繰り替えす
        i = 0
        while i < fontFamilyList.length
            fontFamily = fontFamilyList[i][0]#配列のネストなので[0]が必要
            fontFace = fontFaceList[i][0]
            fontList.push(fontFamily + " " +fontFace)#ファミリーとフェイスを繋げてフォント名を作成
            i += 1
        end
    #数が合わないときはエラーを返す
    else
        fontList = "error"
    end 
    return fontList #fontListを返す
rescue
    
end

temp = xmpRead(ARGF, temp)
result = IllustratorFontSearch(temp, fontFamilyList, fontFaceList, fontList)
puts result

ダウンロード

https://box.yahoo.co.jp/guest/viewer?sid=box-l-qk3texvluwbqgcyxkherewskwe-1001&uniqid=0f62f3dd-0320-4b0e-b949-8271afa040bb&viewtype=detail

DTPerのスクリプトもくもく会 #4 を開催します

申し込みページ

dtpmkmk.connpass.com

Information

  • 前回と同じく、株式会社YUIDEA さんの会議室をお借りしています
  • 今回はサプライズはありません
  • 大型モニタをお借りしているので、画面を使って質問したいこと、発表したいことがあればハッシュタグ(#dtpscriptmkmk4)に流してください
    • モニタはDサブとHDMIに対応しています。Thunderbolt2→HDMIの変換ケーブルを1本ご用意します。
  • Git について、なにか質問があれば当日お聞きします

最後に

ご参加お待ちしております!

DTPの勉強会(東京) 第26回で登壇します

概要

DTPの勉強会(東京) 第26回で「バージョン管理システムの概要と使い方」についてお話します。

内容(予定)

バージョン管理システムとはどんなものか、どのように使うか、使うことでどんなメリットがあるかなどを、デモをまじえてお話させていただく予定です。

勉強会の申込みページ

【DTPの勉強会 第26回】開催のお知らせ&参加受付 - DTPの勉強会(東京) 今回はスクリプト回です。
申込みが開始されておりますので、スクリプトに興味のある方、バージョン管理システムについて興味のある方は、ぜひご参加くださいませ。

DTPerのスクリプトもくもく会 #3 を開催しました

前説

DTPerのスクリプトもくもく会 #3 を開催しました。

dtpmkmk.connpass.com

参加者は私を含め17名でした。
connpass 上は14名になっていますが、会場をお貸しいただいた 株式会社YUIDEA さんから二名ご参加いただいているため、不整合が生じています。
また、初心者枠の申し込み希望者が多かったため、最終的に4名に増員しました。

当日の雰囲気

共同開催者の id:uske-s さんが完璧なまとめを書かれておりますので、そちらをご参照ください。 uske-s.hatenablog.com

Tweetのまとめ

Togetter でまとめました。
togetter.com

会場について

今回の会場をお借りしたのは 株式会社YUIDEA さん。 www.yuidea.co.jp

とても綺麗な会場で、大型モニタ、Webカメラ、USB接続のスピーカーなど、いろいろお貸しいただいて、充実したもくもく会が開催できました。
この場をお借りしてお礼申し上げます。

発表について

大型モニタをお借りしたので、私含め数人で発表をしてみました。
勉強会という形態はとっていないので、もくもくいたい方々にはちょっとご迷惑だったかもしれませんが、「面白いことはやってみよう!」という主催のわがままにお付き合いいただいてありがとうございます。
次回以降も機会があれば、なにかしら発表する場を設けようかと思っています。
成果発表的なものができたら面白いと思うのですが、参加者の皆さん、いかがでしょうか?
なお、私の発表した内容については、時間ができたときに記事にする予定です。

今後の予定

11月に開催予定です。
ご参加お待ちしております。

iOSDC Japan 2017 1日目に参加してきた

概要

こちらの勉強会(カンファレンス)に参加してきた。
iosdc.jp

前夜祭の記事は下記。 www.macneko.com

セッションの感想

会場で聞きながらメモをとったものを貼り付け。
スピーカーが発言した内容と、私の独り言が入り混じってるけど、ご容赦を。
なお、MBA のバッテリーが力尽きたため、途中で終わっています。
無念。

Auto Layout のアルゴリズム(Track A)

  • スライド speakerdeck.com
  • AutoLayout、いまだによくわかってないので、知りたい欲ある
  • Abema から8人登壇! すごいなぁ
  • このスライド、とてもほしいやつだ
  • コードで書くならサードパーティのライブラリを使ったほうがいいとのこと
    • たしかに素で書いたやつ、読めませんね
  • 行列計算の話がここでも出てきて、数学は学ばないといけない問題が再燃
  • 線形計画問題?初めて聞くぞ…
  • わかった、これは数学のセッションだ!
  • Cassowary
    • UI のための制約プログラミング手法
    • ヒクイ鳥
  • なるほど、わからん
  • スライドをあとから読み直そう。時間内に理解することは無理だわ
  • スライド通り、AutoLayout のアルゴリズムを解析ってことなんだな

インタラクティブ画面遷移の実践的解説(Track A)

  • こちらも Abema の人
  • 今回の内容はiOS9以降に対応
  • インタラクティブトランジションはSafariのエッジスワイプなど
    • 移動量に応じてアニメーションが変わる。シャドウの濃さとか
  • ユーザーの操作にあわせてアニメーションさせるってことか(たしかにそんなこと言ってたけど、ピンとこなかった)
  • 画面全面のモーダルはユーザーとしても邪魔なときがあるので、ユーザーが画面半分だけ表示できるように仕込んであげるのはいい手だな
  • ソースコードが見えないけど、あとでサンプルコードがあがるのかな
    • あとで公開されるそう
  • 画面外タップ、画面外スワイプで画面を閉じるのはよくあるけど、わりと面倒くさい印象
  • チュートリアルのように横にスクロールして画面遷移するのにも、インラクティブさを求められるのか
    • サンプルの動作を見せてもらったら「なるほど、これはやってみたい」って思った
    • 自分の目で見てみないと良し悪しはわからないね
  • UIScrollView をスクロール量を取得して、progress に変換しているとのこと
    • progress とはなんぞや。あとで調べよう
    • UIScrollView の移動量を他のなにかに転用するというのは、良い手段だな
  • 聞きやすくてよいセッションだった

Build high performance and maintainable UI library(Track A)

  • 岸川さんのセッション
  • 番組表のようなレイアウトを簡単に実現できる SpreadsheetView というライブラリを公開している
    • とても滑らかに動いていた
    • のちほどチェックしよう
  • パフォーマンスチューニングはトレードオフ。ちゃんと計測しよう
  • 画面内に表示しきれないViewの影響で、シンプルにViewをたくさん作ると動作が遅くなる(固まる)
  • 最低限必要な範囲のみViewを生成する、Viewを再利用すると良い
  • トレードオフを知る
    • コードの読みやすさ、テストのしやすさを犠牲にすることが多い
    • 得るものと失うもののバランスの見極めが腕の見せどころ
  • UIコンポーネントのテストは難しい
    • 内部状態が多く複雑
    • 状態を変化させる要因が多い
    • 状態が相互作用を及ぼす
    • 正しい挙動が明確ではない
  • テストしやすい構造とは
    • データの流れを1方向にする
      • ひとつのクラス内でロジックが書かれている場合でも1方向の流れにすることが重要
    • 状態をモデルに分離する
    • 振る舞いをモックに振り替える
  • 状態の瞬間瞬間もモデルに定義して(座標とかをパラメータにもつ)テストする
  • テスト対象が大きいとテストコードをあとから読んでもわからなくなる
    • 可能な限りテスト対象を小さくする
  • モック化の過渡期などに static をつけて、インスタンス変数にアクセスできなくするという手もあるのか
  • パフォーマンスチューニングはよく頼まれるので、参考になる良いセッションだった
  • テスト、書かないと…

Swift で数学のススメ 〜 プログラミングと数学を同時に学べ(Track B)

Swift プログラマのための今さら聞けない計算量の話し(Track B)

  • 続いて、数学のセッションに参加
  • スピーカーは RubyCocoa を作られた方。聞いたことあるな
  • 計算量とか初めて聞いた
  • 配列の値の取り出し方で o(1)、o(n) の説明。わかりやすい
  • Swiftのドキュメントで計算量について書かれているところ
    • コレクションに関するドキュメントに書かれている
    • Sequence、count
  • Sequence プロトコル
    • 期待される値のところに記載あり(Expected Peformance)
  • Count プロパティ
    • コレクションが空かどうかは isEmpty() プロパティを使うように書いてある
    • 計算量が異なる可能性があるので、意識して実装すると、効率良い実装ができる

Swift と Kotlin(Track B)

  • どっちが優れているとかそういう話じゃないと明言されてて安心
  • Swift と Kotlin は似ているけど、根底が異なるものもあり、一様に似ているとはいえないんだな
    • たとえば、Swift は型を拡張する感じ、Kotlin は型に追加する感じ
    • 構文だけぱっと見て似てると思ったけど、セッション聞いていると、構文似ているだけにいろいろハマる気がする
    • 実際に書いてみないとやっぱりわからんな
  • Kotlin のforeach は return で抜ける、Swift のforeach は return でスキップ

懇親会

何人かのスピーカーの方とお話ができて、「セッション超良かったです!」とお伝えした。 私の数少ない登壇でも聞いてくださった方々に感想を言ってもらえると嬉しかったので、機会があるときは頑張ってお伝えするようにしている。

来年開催時の希望

  • 懇親会チケットを申し込み忘れている人がかなりいたので、もっとわかりやすくアナウンスがされるといいな *チケットを「懇親会あり」「懇親会なし」でわけて申し込んでもらうのも手かなぁ
  • 電源席がほしかった
  • ノベルティを減らして、チケット代がもう少し安くなるといいなぁ

まとめ

お祭り感があって、セッションも多岐にわたっていろいろな内容があって、とても楽しかった。
来年も参加したい。

iOSDC Japan 2017 前夜祭に参加してきた

概要

iosdc.jp

こちらの勉強会(カンファレンス)に参加してきた。

参加した経緯とか

昨年、iOSDC リジェクトコンのスタッフをやって、iOSDC にも参加すれば良かったなーと思ったので、今年は個人スポンサーチケットを購入してみた。
久しぶりの iOS の勉強会である。
この勉強会は前夜祭含め、3日間開催されるんだけど、今日はそのうちの前夜祭だった。
そして、前夜祭なのに300人以上が受付をされたそうで、勉強会というよりお祭りに近い感じ。
スタッフもたくさんいて、随所で道案内などしてくれるので、道に迷うことで定評のある私も、会場に入ってからは迷わないで済んだ。
try! swift とはちょっと違う雰囲気。
明日からの本番?ではまた違った雰囲気になるのかも。
というのも、今日は Track A のみだったけど、明日からは Track A 〜 Track D まであるんですよ。

iosdc.jp

すごいですね。
どれくらいの人数が集まるんだろうか。

ノベルティ

iOSDC ではたくさんのノベルティがもらえます。
私は個人スポンサーなので、一般特典にプラスして、個人スポンサー特典のパーカーやノベルティもゲット。
パーカーは M サイズが思ったよりも小さかったのが残念。
ノベルティはいろんなものをいただいて全部書くのは大変なので適当に紹介。
デニムのトートバッグは普段使いでも使えるんじゃないかな。

f:id:macneko-ayu:20170915225351j:plain
トートバッグ

特に嬉しかったのは、デバイスのチートシート、今治タオルかな。

f:id:macneko-ayu:20170915220817j:plainf:id:macneko-ayu:20170915220807j:plain
チートシート

f:id:macneko-ayu:20170915220825j:plain
今治タオル

肝心のセッションの感想

会場で聞きながらメモをとったものを貼り付け。
スピーカーが発言した内容と、私の独り言が入り混じってるけど、ご容赦を。

SiriKit and Me

  • togetterまとめ togetter.com
  • Siriを使ったことはあるけど、開発で使ったことはない(キリッ
  • SiriKitを使うアプリが結構ある
    • LINEのトーク送信
    • 日本交通のタクシー配車
      • これいいなぁ。ごんたまが健在なうちに知ってたら使ってたかも
  • Message Intentを使う場合は、追加されたコードの中にサンプルコードがあるので、それを参考に書ける
    • サンプルコードがあるのはありがたい
  • SiriKitを使ってる場合のデバッグはどうやるんだろう?
    • 明確なエラーが帰ってこない
    • 文字列をスキーマで渡せるそう
  • Siriにはタイムアウト制限があるので、ネットワークが絡むときなどはキャッシュファイルを利用するなどしないといけない

Objective-C++を使ってMRCで快適に開発する

  • togetterまとめ togetter.com
  • 前夜祭に参加した理由がこのセッションがあるからだったりする
    • たまにMRCな案件もあるのでメモリ管理の話は聞きたい
    • とはいえ、Objective-C++を書いたことはない
  • Obj-Cのメソッドの引数にC++の型が渡せたり、C++のメソッドの関数にObj-Cの型が渡せたりする
    • おおう、これはわかってないと読めないやつや
  • メモリ解放の手法がObjCとC++とで入り混じってて、地雷を踏む予感しかない
  • メモリの扱いについては良さげな手法があるようだ
  • ARCとMRCをobjc_ptrで解決できる?
  • ARCじゃない理由はなぜか?
    • 音のスピード・質などがARCがONだと良くない気がする
    • 気のせいかもしれない

Swaggerで始めるAPI定義管理とコードジェネレート

  • スライド speakerdeck.com
  • togetterまとめ togetter.com
  • swagger-codegen、使ってみたい github.com
  • APIへのリクエスト、モデルは手動で作らずに、機械的に定義に沿って作ってほしい
    • サーバ側、クライアント側の齟齬をなくしたいのと、都度都度手で直していくと破綻するから

節子、それViewControllerやない…、FatViewControllerや…。

  • 発表資料的なやつ dev.classmethod.jp
  • togetter togetter.com
  • これも聞きたかったやつ
  • 自分が実装するとFatViewControllerになりがちなので
  • テストも書きたいのでテストしやすくしたい(でも書いてない)
  • 開発のスピードがあがることってそこまで重要かなぁ。品質上げることのほうが重要で、だからテストするんじゃないのかしら
    • サイクルが早くなればバグを見つけやすいってことなのかな
  • MVP(Presenter、interface、viewcontorller)をソースコードで見せてくれるの、ありがたい
    • いつもどう切り分けるべきかわかんなくなるので
  • 登壇者が最近面白いと思った記事

余談

フロントエンドでObjective-Cっぽいものを書くやつを教えてもらった。
いやー、すごい。 github.com

まとめ

明日は10時開場なので、早く寝よう。
でも、「今日ブログ書いてもいいんだよ!」ってクロージングで言ってたので、かなり雑だけどブログ書いた。
勢い大事。
詳細な内容が知りたい方はクラスメソッドさんの記事を読んだらいいんだよ!

InDesign に配置されたPDF形式ファイルの配置オプション「背景を透明に」のチェックの状態を確認するスクリプトを書いた

概要

InDesign に配置されたPDF形式ファイルの配置オプション「背景を透明に」のチェックの有無を確認するスクリプトを書いた。

www.macneko.com 上記の CEP Extensions は InDesign CC 2015 以降対応だったので、スクリプトにすることで InDesign CS6 以降のバージョンで使用できる。

使い方

CEP Extensions の記事とほぼ同じだが、異なる点はスクリプトなので、スクリプトパネルから起動する必要がある。

仕様的なもの

CEP Extensions の記事とほぼ同じ。

対応バージョン

InDesign CS6以降。

ソースコード

#targetengine 'session'

(function () {
    var palette = new Window('palette', '背景を透明にチェック', undefined);
    var titleArea = palette.add('statictext', undefined, '配置オプションの「背景を透明に」:');
    var messageArea = palette.add('statictext', undefined, 'グラフィックフレーム、または画像を1つだけ選択してください');

    var eventListener = app.addEventListener('afterSelectionChanged', function (event) {
        // try 〜 catch しないとドキュメントを閉じたときにエラーになる
        try {
            messageArea.text = checkTransparentBackground();
        } catch (e) {
        }
    });

    palette.onClose = function () { eventListener.remove(); };
    palette.show();

    // 配置オプションの「背景を透明に」の状態を返す
    var checkTransparentBackground = function () {
        if (app.documents.length === 0) return 'グラフィックフレーム、または画像を1つだけ選択してください';
        if (app.selection.length !== 1) return 'グラフィックフレーム、または画像を1つだけ選択してください';
        var selObj = app.selection[0];
        if (selObj.constructor.name === 'Rectangle'
            && selObj.graphics.length === 1
            && selObj.graphics[0].imageTypeName.indexOf("PDF") > -1) {
            // pdfAttributesはisValidが動作しない...
            try {
                if (selObj.graphics[0].pdfAttributes.transparentBackground) {
                    return 'ON';
                } else {
                    return 'OFF';
                }
            } catch (e) {
                return '背景を透明にオプションがない形式の配置画像です';
            }
        }
        if (selObj.constructor.name === 'TextFrame') {
            return '配置画像ではありません';
        }
        try {
            if (selObj.pdfAttributes.transparentBackground) {
                return 'ON';
            } else {
                return 'OFF';
            }
        } catch (e) {
            return '背景を透明にオプションがない形式の配置画像です';
        }
        return 'OFF';
    };
}());

ダウンロード

https://yahoo.jp/box/pXTJSk