サポンテ 勉強ノート

サポンテの勉強ノート・読書メモなどを晒します。

AppleScript の do shell script で実行されるシェル環境を調べる

 昨日のスクリプトを作っているときに気になったので。

 スクリプトエディタ.app で以下の AppleScript を実行します。

-- 使われているシェルとそのバージョン取得
set shName to do shell script "echo $SHELL"
log (do shell script shName & " --version")

-- 環境変数の取得
log (do shell script "set")

-- AppleScript のバージョン取得
log ("AppleScript version: " & version of AppleScript)

-- macOS のバージョン取得
log (do shell script "sw_vers")

Spotlight を利用して素早く新規ファイル作成【macOS】【AppleScript】

はじめに

 「Finder で『この場所に新しいテキストファイル』を作成したい」際に、クリックひとつでテキストファイルが作成できるよう、かつて AppleScript で作成したアプリケーションを、Finder ウィンドウのツールバーに登録していました。メモファイルをたくさん作るためです。

 しかし最近は、同じように .md ファイル(Markdown ファイル)を素早く作りたいケースが増えてきました。でもツールバーのボタンを、むやみに増やしたくありません。

 ツールバーのアプリケーションアイコンをクリックした際に、新規作成したファイルの候補を選択するような UI を最初に考えたのですが、それよりは Spotlight で「new_text」とか「new_md」とか、いやいっそ「nt」とか「nm」とかタイプするだけでテキストファイルや .md ファイルが作成できるようにしたい。

続きを読む

Mac の日本語 IME のユーザ辞書内容を Google 日本語入力の辞書へ移行するスクリプト

はじめに

 Mac(Catalina)の日本語 IME があんまりにもひどいので1Google 日本語入力を試してみることにしました。

 しかしインストールしてもユーザ辞書を自動的にインポートしてくれたりはしませんでした。ChromeSafari のブックマークをインポートするかどうか選べるのに。


  1. 学習しない。正確に言うと、学習内容がしばらくするとなぜか消される。ことえりより明らかに悪化しています。
続きを読む

CotEditor をストップウォッチとして使う_文字数も数える

はじめに

執筆の時間計測に使いたいので、早速導入しました。テキストを開いたときの文字数取得とストップウォッチを止めたときの文字数取得し、増えた文字数をカウントするにはどうしたらいいでしょうか……? id:rainlittle

まず...

 CotEditor の「環境設定」を開き、「ウィンドウ」の設定で「ステータスバー表示」のところから「文字数」にチェックを入れます。

 それで、ステータスバーに現在の書類の文字数が表示されますので、それを自分でメモするのではダメでしょうかね。

スクリプトでのやり方

 CotEditor スクリプトは、編集中のテキスト全部をもらうディティクティブがあり、PHP には md_strlen() があるので、それが使えるでしょうね。

使い方

  1. CotEditor でドキュメントを開きます。
  2. はじめに、ストップウォッチをスタートさせるスクリプトを実行します。
  3. 次に、ラップタイムを記録するスクリプトを実行します。

実行結果

  1. スタートのスクリプトを実行すると、CotEditor で編集中のドキュメントの文字数を保存しておきます。見た目には何も起きません。
  2. ラップタイムのスクリプトを実行すると、スタートからのラップタイムと、増えた文字数を新規ドキュメントに出力します。

注意点

  • 増えた文字数は「スタート」からの文字数になります。ラップ取得時ではありません。
  • 前回と同じく、「書類」フォルダの下に、テキストファイルを一つ作成します。「com.hatenablog.saponte.StopWatchWithCharCount.txt」です。

ショートカット

 前回の記事を参照ください。

スクリプト

 以下の PHP スクリプトを、上記のように好みのファイル名で保存していただき、実行権を与えて、CotEditor のスクリプトフォルダに格納してください。

 UTF-8 で保存してください。

 実行権を忘れないでくださいね。

StopWatchWithCharCount_Start.php

#!/usr/bin/php -q
<?php
// %%%{CotEditorXInput=AllText}%%%

$doc = file_get_contents('php://stdin');

file_put_contents(
    $_SERVER['HOME'] . '/Documents/com.hatenablog.saponote.StopWatchWithCharCount.txt'
    , microtime(true) . "\t" . mb_strlen($doc)
    );

StopWatchWithCharCount_Lap.php

#!/usr/bin/php -q
<?php
// %%%{CotEditorXInput=AllText}%%%
// %%%{CotEditorXOutput=NewDocument}%%%

$doc = file_get_contents('php://stdin');
$start_info = file_get_contents($_SERVER['HOME'] . '/Documents/com.hatenablog.saponote.StopWatchWithCharCount.txt', false);
$tmp = explode("\t", $start_info);
$start_time = $tmp[0];
$start_strlen = $tmp[1];
$lap_time = microtime(true) - $start_time;
$inc = mb_strlen($doc) - $start_strlen;

list($sec, $millisec) = explode('.', $lap_time . '');
$m = floor($sec / 60);
$s = $sec % 60;

echo str_pad($m, 2, 0, STR_PAD_LEFT) . ':' .
     str_pad($s, 2, 0, STR_PAD_LEFT) . '.' .
     substr($millisec, 0, 3) . "\n" .
     $inc . " 文字増えました。\n";

おわりに

 動作を確認したサポンテの Mac では PHP のバージョンは 7.3.11、CotEditor のバージョンは 4.0.8(471) でした。

CotEditor で開いている書類の diff を取得する【CotEditor】

はじめに

 二つのテキストの差分を調べる diff コマンドですが、いちいちファイルに保存せず手軽に比較したいことがしばしばあります。

 CotEditor で開いている Window から、二つを選択して比較するスクリプトを作ってみました。書類は保存する必要はありません。

 出来上がったものは、正直なところあまり実用的ではないと感じるのですが、まあ役に立つこともあるかもしれないので置いておきます。

続きを読む

tccutil コマンドで「オートメーション」を指定するには

はじめに

 macOS のシステム環境設定「セキュリティとプライバシー」には、自分が起動したアプリケーションなどの設定が日々追加されていきます。問題は別にないのですが、リセットしたいケースがしばしばあります。

 調べてみると tccutil というコマンドを使うようで、Qiita に詳細な記事がありました。

セキュリティとプライバシーの設定値をリセットする(macOS 10.15 Catalina) - Qiita

 コマンドにはリセットしたい対象のアプリケーションとサービス名を指定します。

tccutil reset <サービス名> <アプリケーションのバンドルID>

 上記 Qiita 記事にサービス名の一覧があります。英語名になっていますが、それをみると、おおよそ想像がつきます。つくのですが「オートメーション」だけは名前が全く違ったので、見当をつけて「えいやっ」と実行しました。

「オートメーション」は「AppleEvents」

 AppleEvents でした。無事にリセットできました。これって往年からの mac 開発者じゃないとわからないのでは?まあ消去法で辿り着けるかもしれませんが。

tccutil reset AppleEvents com.coteditor.CotEditor

f:id:saponte:20210910194304p:plain

Excel や Numbers からコピーした表を Markdown としてペーストする - その2【CotEditor】

はじめに

 先日 PHP で作成した CotEditor スクリプトを、pbpaste文字コード違いも気になったため JavaScript(JXA)で作り直しました。

使い方

 先日のスクリプト同様、表計算ソフトからセル範囲を選択して「コピー」を行います。

 CotEditor に戻って「⌘ + Shift + V」します。

 以下のようになります。

Id    |Name            |Price       
------|----------------|------------
1     |Apple           |200         
2     |Banana          |150         
3     |Citrus          |300         
九九九|ドラゴンフルーツ|価格未設定。

スクリプトソースコード

 ファイル名を「TSVを表としてペースト.@$v.js」などと設定し、CotEditor のスクリプトフォルダに入れれば、「⌘ + Shift + V」で実行できます。

#!/usr/bin/osascript -l JavaScript

(() => {
    'use strict';
    
    ObjC.import('stdlib')
    
    let CotEditor = Application('CotEditor');
    CotEditor.includeStandardAdditions = true;
    let doc = CotEditor.documents[0];
    const selection = doc.selection;
    
    const notification = (msg, title) => {
        let app = Application.currentApplication();
        app.includeStandardAdditions = true;
        app.displayNotification(msg, {
            withTitle: "CotEditor - スクリプト",
            subtitle: title,
            soundName: "Frog",
        });
    };
    
    const clipboardText = () => {
        let app = Application.currentApplication();
        app.includeStandardAdditions = true;
        return app.doShellScript("pbpaste");
    };
    
    const strlen = (str) => {
        // https://mebee.info/2020/12/21/post-26346/#outline__3
        let len = 0;
        for (let i = 0; i < str.length; i++) {
            (str[i].match(/[ -~]/)) ? len += 1 : len += 2;
        }
        return len;
    };
    
    const padright = (text, width, padString) => {
        let len = width - strlen(text);
        return text + padString.repeat(len);
    };
    
    let str = clipboardText();
    
    // 入力チェック
    if ((!str.includes("\r") || !str.includes("\n")) && !str.includes("\t")) {
        let msg = "改行/タブのいずれも含まれていないようです。";
        let title = "クリップボードの内容は TSV ではありません";
        notification(msg, title);
        $.exit(0);
    }

    // 行分割
    let linesSrc = str.split(/(\n|\r)+/);
    
    // 列分割
    let lines = [];
    linesSrc.forEach(line => {
        if (line.trim() === '') {return;}
        lines.push(line.trim().split("\t"));
    });
    
    // 列幅取得
    let colWidth = new Array(lines[0].length).fill(0);
    for (let i = 0; i < lines[0].length; i++) {
        lines.forEach(line => {
            let c = line[i];
            let w = strlen(c);
            colWidth[i] = Math.max(w, colWidth[i]);
        });
    }
    
    var ret = "";
    
    // 見出し出力
    let titles = [];
    lines[0].forEach((title, idx) => {
        titles.push(padright(title, colWidth[idx], ' '));
    });
    ret += titles.join("|") + "\n";
    
    // 水平線出力
    let hr = [];
    colWidth.forEach((w) => {
        hr.push("-".repeat(w));
    });
    ret += hr.join("|") + "\n";
    
    // データ部出力
    for (let row = 1; row < lines.length; row++) {
        let cols = [];
        lines[row].forEach((col, idx) => {
            cols.push(padright(col, colWidth[idx], ' '));
        });
        ret += cols.join("|") + "\n";
    }
    
    selection.contents = ret;
    CotEditor.activate();

})();

参考

 文字数のカウントに、以下のスクリプトを使わせていただきました。

javascript 全角文字は2文字で半角文字は1文字としてカウントする | mebee

環境

 以下の環境で開発・動作確認しました。

ProductName:   Mac OS X
ProductVersion: 10.15.7
BuildVersion:   19H1323
AppleScript version: 2.7
CotEditor version: 2.7.4
Numbers.app version: 10.3.9

 また、Google Spreadsheet でも確認しました。