InDesignには、ソケット通信機能が搭載されています!但し、ほぼほぼ使えるものではない。取得した結果に文字が欠けたり、文字化けしたりすることがよくあります。
以前は、
1.Pythonから文字のルビを取得し、jsonファイルに保存
2.Javascriptからjsonを解析してInDesignにルビを振る
のふうに処理した。
今回appscriptを用いて、Pythonのみで処理のスクリプトを作成した。相変わらずコードが短くて、シンプル。唯一足りないのは、スピードがちょっと遅いです。
API KEY申し込み:
- https://developer.yahoo.co.jp/webapi/jlp/furigana/v2/furigana.html
- https://developer.yahoo.co.jp/webapi/jlp/sample/sample10.html
サンプルコードDL: 03_set_ruby_to_textframe/readme.md
使い方:
- pyスクリプト起動
- InDesignドキュメント上のテキストフレームを選択(複数可)(例はInDesign 2020)
- 「set ruby」ボタンをクリック
import re import tkinter import json from urllib import request from appscript import * def fetch_ruby(query): # https://developer.yahoo.co.jp/webapi/jlp/furigana/v2/furigana.html APPID = "***** replace your app id here *****" URL = "https://jlp.yahooapis.jp/FuriganaService/V2/furigana" headers = { "Content-Type": "application/json", "User-Agent": "Yahoo AppID: {}".format(APPID) } param_dic = { "id": "1234-1", "jsonrpc": "2.0", "method": "jlp.furiganaservice.furigana", "params": { "q": query, "grade": 1 } } params = json.dumps(param_dic).encode() req = request.Request(URL, params, headers) with request.urlopen(req) as res: body = res.read() lists = json.loads(body.decode())["result"]["word"] ruby_data = [] # --> [[漢字1, ルビ1], [漢字2, ルビ2]...] for x in lists: if "furigana" in x: if "subword" in x: for sub in x["subword"]: if sub["surface"] != sub["furigana"]: ruby_data.append([sub["surface"], sub["furigana"]]) else: ruby_data.append([x["surface"], x["furigana"]]) return ruby_data def set_ruby(): sel = indd.selection() for obj in sel: _class = obj.class_() if _class != k.text_frame: print(f"Not a text frame: {_class}") continue contents = obj.contents.get() ruby_data = fetch_ruby(re.sub(r'\r\n|\r', '', contents)) if not ruby_data: continue start = 0 characters, texts = obj.characters, obj.text for x in ruby_data: word, ruby = x pos1 = contents.index(word, start) # first position: zero-indexed pos2 = pos1 + len(word) # second position text_range = texts[characters[pos1 + 1]: characters[pos2]] text_range.ruby_string.set(ruby) text_range.ruby_type.set(1249011570) # group ruby text_range.ruby_flag.set(True) start = pos2 if __name__ == "__main__": # indd = app('Adobe InDesign 2020') # root = tkinter.Tk() root.resizable(False, False) root.title("set ruby") root.geometry("200x100") Button = tkinter.Button(text='set ruby', width=15, height=5, command=set_ruby) Button.pack(padx=10, pady=10) root.mainloop()