Goldbug Software

Second Notes Script for Mac

Second Notes Script for Mac

Trial

Second Notes Scriptがダウンロードできます。

macOS 10.13 and later, and Apple silicon only

Second Notes Script for Mac

Second Notes ScriptはSecond NotesにPython Scriptの実行機能を追加したものです。App Storeの制限によりPythonを利用するアプリが販売できないため、フリーアプリとして配布します。なお、App Store版で利用可能なiCloudを利用したSecond Notes for iOSとのNotesの共有は利用することができません。

Second Notes ScriptのPython Script機能

Second Notes ScriptはMacにインストールされたPython3.8を利用して、Python Scriptを実行し、Noteを編集することができます。その他の機能はSecond Notes for Macと同じです。

Pythonを利用してNoteに定型文字を入力したり、計算処理を行った結果をNoteに追加することができるだけでなく、Pythonの外部モジュールを利用してWebサイトをスクレイピングし、その結果をNoteに書き出すなど、可能性は無限大です。


Python Scriptの使い方

MacにPython3がインストールしてあることが必要です。Python3は/opt/homebrew/bin/python3に、Python.frameworkが/opt/homebrew/frameworksにインストールされていている必要があります。起動時に確認し、FormatメニューのScriptメニューが有効になります。また、ツールバーに"Script"メニューを追加することができます。

Scriptメニューから、Python Scriptを選択して実行することができ、開いているNoteに対して実行されます。


Python Scriptは Second NotesのScriptフォルダーに作成します。

Scriptの登録は、ScriptフォルダーにPythonファイルをドラックすることでも登録することができますし、ScriptフォルダーをControlクリックすると表示されるコンテキストメニューから新規作成できます。

ただし、そのPython ScriptはSecond Notes用のコマンドを追加する必要があります。例えば、次のPython Scriptを実行すると、表示しているNoteのカーソルの位置に結果が挿入されます。Note上で文字列を選択している場合には、その文字列が置き換えられます。


def insert_date():
    import datetime
    now = datetime.datetime.now()
    return now.strftime('%Y/%m/%d(%a)')
        

Python3.xのインストール

Second NotesはMacにインストールされたPyhton3.Xを利用してPython Scriptを実行します。3.8以降で動作確認しています。

具体的には、次の場所にあるframeworkをダイナミックリンクしています。

/opt/homebrew/frameworks/Python.framework
そして、Second Notesの起動時に、この場所にPython.frameworkがあることを確認するとSecond NotesのScriptメニューが利用可能になります。


Python 3.xをインストールするには Homebrewを利用します。

Internetで検索すれば、Python3.xをインストールする方法がいくつか見つかります。例えば、"Python環境構築ガイド > macOS環境のPython"に詳しい説明があります。


Homebrewを利用してインストールする方法を簡単に手順を説明すると、

  1. XCodeまたはApple DeveloperサイトからXCodeコマンドラインツールをインストールする。
  2. Homebrewをインストールする。
  3. Homebrewを使ってPython3.8をインストールする。
ということになります。


また、Python.orgからpkgファイルをダウンロードしてPython3をインストールすることもできます。その場合、python.frameworkは

/Library/Frameworks/Python.framework
にインストールされます。この場所にPython 3.12がインストールされている場合に、Second Notes Scripが動作することを確認しています。

Pythonをインストール後、Pythonに付属するpipを使ってPandasやNumpyなどの外部モジュールもインストールすれば、Second Notes Scripからも利用することができます。


Python ScriptとSecond Notesとのインターフェイス

Second Notes ScriptはPython Script用のsnembモジュールを利用してScriptを実行します。作成したScriptでは、snembモジュールをimportする必要があります。Scriptは、snembのインターフェイスを利用して、対象のNoteの内容を取り出したり、一部または全体を置き換えることができます。


サンプルスクリプト

snembモジュールを利用して、日付を挿入する

上にある日付を挿入するPython Scriptをsnembモジュールを利用するように書き直すと次のようになります。


import snemb
import datetime
def insert_date():
    range = snemb.selected_range()
    now = datetime.datetime.now()
    newdate = now.strftime('%Y/%m/%d(%a)')
    snemb.replace_string_in_range(range[0], range[1], newdate)
    return ''
        


日付のフォーマットを変換する例

snembモジュールを使った別の例は、Noteの中でドット表記の日付 "2020.11.1" を "2020/11/1" のように変換します。


import re
import datetime
import snemb
def DateFormatter():
regex = re.compile(r'(\d{4})\.(\d+)\.(\d+)')
text = snemb.document()  # Note全体を取り出す。
lines = text.splitlines(keepends=True)
dst = '';
for line in lines:
    mm = regex.search(line)
    rval = ''
    if mm and (len(mm.groups()) ≤ 2):
        dt = datetime.datetime.strptime(mm.group(0), '%Y.%m.%d')
        new_dt = dt.strftime('%Y/%m/%d')
        rval = regex.sub(new_dt, line)
        dst += rval
    else:
        dst += line
snemb.set_document(dst)  # Noteを置き換える。
return ''
    

Debug用snembモジュール

以下のようなScriptをsnemb.pyという名前で作成し、importすることで、作成したPython ScriptをPython IDEL を使ってテストすることができます。


src_text = ''

def document():
  return src_text

def set_document(text):
  global src_text
  src_text = text

def document_length():
  return(len(src_text))

def document_lines():
  lines = src_text.splitlines(keepends=True)
  return(len(lines))

def string_at_line(number):
  lines = src_text.splitlines(keepends=True)
  return lines[number]

def string_in_range(location, length):
  return src_text[location:location+length]

def set_selected_range(location, length):
  global src_selected_range
  src_selected_range = (location, length)

def selected_range():
  global src_selected_range
  return src_selected_range

def replace_string_in_range(location, length, string):
  global src_text
  dst = src_text[:location] + string + src_text[location + length:]
  src_text = dst;

def replace_string_at_line(number, string):
  global src_text
  lines = src_text.splitlines(keepends=True)
  lines[number] = string
  src_text = ''.join(lines)
  
def input_dialog(message, info):
  result = input(message + ', ' + info + ':')
  return result

def text_dialog(string):
  print("--- Begin Text Dialog ---")
  print(string)
  print("--- End Text Dialog ---")
    

実際にテストする場合には__main__の部分を利用して次のように実行します。なお、テストするPython Scriptとsnemb.pyとテスト用のテキスト sample.txt はすべて同じフォルダーにある必要があります。


#! /usr/bin/env python3
# coding: utf-8
import snemb
import datetime
def insert_date():
    range = snemb.selected_range()
    now = datetime.datetime.now()
    newdate = now.strftime('%Y/%m/%d(%a)')
    snemb.replace_string_in_range(range[0], range[1], newdate)
    return ''

if __name__ == "__main__":
    filename="sample.txt"
    with open(filename) as f:
        src = f.read()
    snemb.set_document(src)
    snemb.set_selected_range(13,9)
    print("--- Call insert_date()")
    rval = insert_date()
    print ("--- Return value = ", rval)
    print ("--- document =")
    print (snemb.document())
    

ご質問や提案があれば、goldbugsoft_support@icloud.com にメールでおしらください。