Help us understand the problem. What is going on with this article?

IllustratorからHTML、CSSに書き出すツール

More than 3 years have passed since last update.

段落スタイル名をHTMLタグと見立てコーディングしCSSを生成します。
操作、取得するプロパティは以下。

Illustrator文字属性 JS property CSS property
段落スタイル名 name -
サイズ size font-size
フォントファミリー textFont.family font-family
フォントウェイト textFont.style font-weight
カラー fillColor color
行揃え justification text-align
行送り leading line-height

JSXコードは以下。

Illustrator2HTML_CSS.jsx
var myDoc = app.activeDocument; //ドキュメント
var mySel = myDoc.selection; //選択しているテキストフレーム
var myPara = myDoc.selection[0].paragraphs; //選択しているフレームの段落スタイル
var myParaStyle = myDoc.paragraphStyles; //ドキュメントの段落スタイル

var myHTMLArray = []; //HTMLタグ用配列
var myCSSArray = []; //CSS用配列
var myPropArray = []; //CSSプロパティ用配列
var mySizeArray = []; //サイズ用配列
var myFontFamilyArray = []; //フォントファミリー用配列
var myFontWeightArray = []; //フォントウェイト用配列
var myColorArray = []; //カラー用配列
var myLeadingArray = []; //行送り用配列
var myJustificationArray = []; //行揃え用配列

function zeroPad(myNum) { //ゼロパディング関数定義
    var myNum = ('00' + myNum).slice(-2);
    return myNum;
}

function myRound(number, n) { //四捨五入関数定義
    var myPow = Math.pow(10, n);
    return Math.round(number * myPow) / myPow;
}

for (var i = 0; i < mySel.length; i++) {
    var myCont = mySel[i].contents; //コンテンツ内容全体

    var myParaLen = mySel[i].paragraphs.length; //段落数を取得
    for (var j = 0; j < myParaLen; j++) {
        var myPraContents = mySel[i].paragraphs[j].contents; //段落ごとのコンテンツを取得
        var myParaName = mySel[i].paragraphs[j].paragraphStyles[0].name; //コンテンツごとの段落スタイル名(タグ名)を取得
        var myStartTag = "<" + myParaName + ">"; //開始タグ
        var myEndTag = "</" + myParaName + ">"; //終了タグ       
        var myHTMLSentence = myStartTag + myPraContents + myEndTag; //開始タグ+コンテンツ+終了タグ
        myHTMLArray.push(myHTMLSentence); //配列に追加
    }
}

for (var k = 1, myParaStyleLen = myParaStyle.length; k < myParaStyleLen; k++) {
    var myDocParaStyleName = myParaStyle[k].name; //ドキュメントの段落スタイル名取得
    myCSSArray.push(myDocParaStyleName);

    var myFontSize = myParaStyle[k].size; //サイズ 
    var myFontSize = "font-size: " + myRound(myFontSize, 2) + "px;"; //myFontSizeに四捨五入関数実行
    mySizeArray.push(myFontSize); //配列に追加

    var myFontFamily = myParaStyle[k].textFont.family; //フォントファミリー。※ps名が取得できない 20170102課題
    var myFontFamily = "font-family: " + myFontFamily + ";";
    myFontFamilyArray.push(myFontFamily); //配列に追加

    var myFontWeight = myParaStyle[k].textFont.style; //フォントウェイト
    var myFontWeight = "font-weight: " + myFontWeight + ";";
    myFontWeightArray.push(myFontWeight); //配列に追加

    var myColorRed = myParaStyle[k].fillColor.red.toString(16).toUpperCase(); //red値を取得(大文字のHEX値)
    var myColorRed = zeroPad(myColorRed); //ゼロパディング関数実行
    var myColorGreen = myParaStyle[k].fillColor.green.toString(16).toUpperCase(); //green値を取得(大文字のHEX値)
    var myColorGreen = zeroPad(myColorGreen); //ゼロパディング関数実行
    var myColorBlue = myParaStyle[k].fillColor.blue.toString(16).toUpperCase(); //blue値を取得(大文字のHEX値)
    var myColorBlue = zeroPad(myColorBlue); //ゼロパディング関数実行
    var myColor = "color: #" + myColorRed + myColorGreen + myColorBlue + ";"; //rgb値として取得
    myColorArray.push(myColor); //配列に追加

    var myJustification = myParaStyle[k].justification; //行揃え
    switch (myJustification) {
    case Justification.LEFT:
        myJustification = "text-align: left;";
        break;
    case Justification.CENTER:
        myJustification = "text-align: center;";
        break;
    case Justification.RIGHT:
        myJustification = "text-align: right;";
        break;
    case Justification.FULLJUSTIFYLASTLINELEFT:
        myJustification = "text-align: justify;";
        break;
    }
    myJustificationArray.push(myJustification); //配列に追加
}

var myParaStyleObj = {}; //オブジェクト生成
for (var l = 0, myParaLen = myPara.length; l < myParaLen; l++) {
    var myParaStyleName = myPara[l].paragraphStyles[0].name; //段落から段落スタイル名取得
    var myParaLeading = myPara[l].paragraphs[0].leading; //段落から行送り値取得
    myParaStyleObj.myDocParaStyleName = myParaLeading; //ドキュメントのkeyに"オブジェクトの段落スタイル名
    var myLeading = "line-height: " + myRound(myParaStyleObj.myDocParaStyleName, 2) + "px;"; //myParaStyleObj.myDocParaStyleNameに四捨五入関数実行
    myLeadingArray.push(myLeading); //配列に追加
}

for (var m = 0, myCSSArrayLen = myCSSArray.length; m < myCSSArrayLen; m++) {
    var myCSSResult = myCSSArray[m] + "{" + mySizeArray[m] + myFontFamilyArray[m] + myFontWeightArray[m] + myColorArray[m] + myLeadingArray[m] + myJustificationArray[m] + "margin: 0;" + "}"; //CSS生成
    myPropArray.push(myCSSResult); //配列に追加
}

var myHTMLArray = myHTMLArray.toString(); //HTMLタグ用配列を文字列に変換 ※変数上書き
var myHTMLArray = myHTMLArray.replace(/,/g, ""); //文字列化したCSVのカンマを削除
var myPropArray = myPropArray.toString(); //CSS用配列を文字列に変換 ※変数上書き
var myPropArray = myPropArray.replace(/,/g, ""); //文字列化したCSVのカンマを削除

var MyHTMLRessult = '<!DOCTYPE html><html lang="ja"><head><meta charset="UTF-8"><title>Document</title><style>' + myPropArray + '</style></head><body>' + myHTMLArray + '</body></html>'; //HTML生成

//▼ファイル保存
(function () { //無名関数を定義し実行
    var inputFileName = File.saveDialog("保存先とファイル名を指定して下さい");
    if (inputFileName == null) { //キャンセル処理
        alert("キャンセルしました。");
        return;
    }

    var inputFileName = inputFileName.toString(); //ファイル名に拡張子がないときの処理
    var myNewText = inputFileName.match(/.html/); //拡張子".txt"を付与
    if (myNewText) {
        var inputFileName = inputFileName; //入力したファイル名に拡張子が含まれる場合はそのまま
    } else {
        var inputFileName = inputFileName + ".html"; //入力したファイル名に拡張子が含まれない場合は付与
    }

    var fileObj = new File(inputFileName); //ファイル名を入力して保存
    var inputFileName = fileObj.open("w");
    if (inputFileName == true) {
        fileObj.encoding = "UTF-8"; //UTF-8を指定。これを入れないと異体字依存で書き出されない場合がある。
        fileObj.writeln(MyHTMLRessult); //書き出すテキストを連結
        fileObj.close();
        alert("処理が終わりました。");
    }
})();

image
▲フレームを選択し実行。

各段落の設定は以下。
1行目
青空文庫:銀河鉄道の夜 宮沢賢治
段落スタイル名:h1
サイズ:31px
フォント: A-OTF Futo Go B101 Pr6N Bold
スタイル:Bold
カラー: #009245 (R0 G146 B69)
行送り:54.25px (自動)
行揃え:中央揃え

2行目
銀河鉄道の夜
段落スタイル名:h2
サイズ:20px
フォント: A-OTF Midashi Go MB31 Pr6N MB31
スタイル:MB31
カラー:#006837 (R0 G104 B55)
行送り:35px (自動)
行揃え:左 / 上揃え

3行目
宮沢賢治
段落スタイル名:h3
サイズ:15px
フォント:A-OTF UD Shin Go Pr6N
スタイル:L
カラー: #662D91 (R102 G45 B145)
行送り:26.25px (自動)
行揃え:右 / 下揃え

4行目
一、午后の授業
段落スタイル名:h4
サイズ:13px
フォント: A-OTF Midashi Mi MA31 Pr6N MA31
スタイル: MA31
カラー: # 0000FF (R0 G0 B255)
行送り:22.75px (自動)
行揃え:左 / 上揃え

5行目以降
本文
段落スタイル名:p
サイズ:10px
フォント:A-OTF Gothic BBB Pr6N Medium
スタイル:Medium
カラー: # 42210B(R66 G33 B11)
行送り:17.5px (自動)
行揃え:均等配置(最終行左 / 上揃え)

実行後Bracketsで開きBeautifyでコードフォーマット

html、CSS
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        h1 {
            font-size: 31px;
            font-family: A-OTF 太ゴB101 Pr6N;
            font-weight: Bold;
            color: #009245;
            line-height: 54.25px;
            text-align: center;
            margin: 0;
        }

        h2 {
            font-size: 20px;
            font-family: A-OTF 見出ゴMB31 Pr6N;
            font-weight: MB31;
            color: #006837;
            line-height: 35px;
            text-align: left;
            margin: 0;
        }

        h3 {
            font-size: 15px;
            font-family: A-OTF UD新ゴ Pr6N;
            font-weight: L;
            color: #662D91;
            line-height: 26.25px;
            text-align: right;
            margin: 0;
        }

        h4 {
            font-size: 13px;
            font-family: A-OTF 見出ミンMA31 Pr6N;
            font-weight: MA31;
            color: #0000FF;
            line-height: 22.75px;
            text-align: left;
            margin: 0;
        }

        p {
            font-size: 10px;
            font-family: A-OTF 中ゴシックBBB Pr6N;
            font-weight: Med;
            color: #42210B;
            line-height: 17.5px;
            text-align: justify;
            margin: 0;
        }
    </style>
</head>

<body>
    <h1>青空文庫:銀河鉄道の夜 宮沢賢治</h1>
    <h2>銀河鉄道の夜</h2>
    <h3>宮沢賢治</h3>
    <h4>一、午后の授業</h4>
    <p>「ではみなさんは、そういうふうに川だと云われたり、乳の流れたあとだと云われたりしていたこのぼんやりと白いものがほんとうは何かご承知ですか。」先生は、黒板に吊つるした大きな黒い星座の図の、上から下へ白くけぶった銀河帯のようなところを指しながら、みんなに問をかけました。</p>
    <p>カムパネルラが手をあげました。それから四五人手をあげました。ジョバンニも手をあげようとして、急いでそのままやめました。たしかにあれがみんな星だと、いつか雑誌で読んだのでしたが、このごろはジョバンニはまるで毎日教室でもねむく、本を読むひまも読む本もないので、なんだかどんなこともよくわからないという気持ちがするのでした。</p>
</body>

</html>

image
▲Choromeで表示。モリサワパスポートがインストールしてあるのでモリサワTypekitフォントも表示されている。

image

image

image

image

image

▲Chromeの検証画面

注意点等
・行送り値は「自動」だと段落スタイルから取得できないので文字属性から取得しました。なのでフレーム内で使用されている順番に段落スタイルパネル内でソートされている必要がある。(いい方法あるかなぁ???)
・font-sizeやline-heightの単位はpxとしました。
・フォントはAdobe Typekit(モリサワフォント)を使用しましたがIllustratorの環境設定でフォントの英語表記をしてもpostscript名が取得できません。webフォント使用時に注意が必要。(いい方法あるかなぁ???)
・MB31やLなどfont-weightもこれでは無視されます。
・カラー値は16進数(HEX値)にしました。配列に格納したCSVのカンマを正規表現で削除しているので rgb (255,0,0); だとRGB値の区切りのカンマも削除されてしまう。(頑張ればできるかも。。。)
・user agent stylesheetで各タグ間にmarginが入り意図しない間隔が生じるため margin:0; を最後に付与してあります。
・クリップボードにコピーできればいいのですがJavaScriptではできないようなのでファイル保存するようにしました。

完全なコンバートではないけれども支援ツールとして使えそうだ。。。w
今度はInDesign版を作ってみよう!

※検証はWindows10 Google Chromeでしか行っておりません。

参考にしたサイトは以下。
Adobe Illustrator CC Scripting Reference: JavaScript
古籏一浩様のサイト Adobe CC バージョン JavaScript リファレンス

onebitious
Web業界に転職しました。 タグ書いたり、デザインしたり、JS書いたりしています。 HTML5プロフェッショナル認定資格レベル1、DTPエキスパート、クロスメディア・エキスパート 保有 たまに山登ったりしてます。 写真、Mac、iPhoneなども好き。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした