tideとeglotの併用はするのか?

知りたいこと Emacsでtypescriptの開発をするうえでtideとは?ということの概要を学習したい。 そのうえで、tideとEglotによるlang serverを併用するのが良いのかを知りたい。 Geminiによる回答 Reasoning *Exploring Core Question 1 I’m currently focused on defining tide within the Emacs/TypeScript environment. The goal is to provide a concise overview for the user. I’m actively working to synthesize the relevant information and ensure clarity in my explanation. Refining the Explanation I’m now refining the explanation of tide. The focus is on the crucial role of tsserver as its engine. I’m exploring the best way to succinctly highlight tide’s key features, such as completion and error checking, without overwhelming the user. The goal is a truly concise overview. ...

August 22, 2025 · 2 min · moai

Recipistプライバシーポリシー

moai合同会社(以下「当社」は、ご自身の名称や屋号などに変更してください)は、本ウェブサイト上で提供するサービス(以下、「本サービス」といいます。)における、ユーザーの個人情報の取扱いについて、以下のとおりプライバシーポリシー(以下、「本ポリシー」といいます。)を定めます。 第1条(個人情報) 「個人情報」とは、個人情報保護法にいう「個人情報」を指すものとし、生存する個人に関する情報であって、当該情報に含まれる氏名、生年月日、住所、電話番号、連絡先その他の記述等により特定の個人を識別できる情報及び容貌、指紋、声紋にかかるデータ、及び健康保険証の保険者番号などの当該情報単体から特定の個人を識別できる情報(個人識別情報)を指します。 第2条(個人情報の収集方法) 当社は、ユーザーが利用登録をする際に氏名、生年月日、住所、電話番号、メールアドレス、銀行口座番号、クレジットカード番号、運転免許証番号などの個人情報をお尋ねすることがあります。また、ユーザーと提携先などとの間でなされたユーザーの個人情報を含む取引記録や決済に関する情報を、当社の提携先(情報提供元、広告主、広告配信先などを含みます。以下、「提携先」といいます。)などから収集することがあります。 第3条(個人情報を収集・利用する目的) 当社が個人情報を収集・利用する目的は、以下のとおりです。 当社サービスの提供・運営のため ユーザーからのお問い合わせに回答するため(本人確認を行うことを含む) ユーザーが利用中のサービスの新機能、更新情報、キャンペーン等及び当社が提供する他のサービスの案内のメールを送付するため メンテナンス、重要なお知らせなど必要に応じたご連絡のため 利用規約に違反したユーザーや、不正・不当な目的でサービスを利用しようとするユーザーの特定をし、ご利用をお断りするため ユーザーにご自身の登録情報の閲覧や変更、削除、ご利用状況の閲覧を行っていただくため 有料サービスにおいて、ユーザーに利用料金を請求するため 上記の利用目的に付随する目的 第4条(利用目的の変更) 当社は、利用目的が変更前と関連性を有すると合理的に認められる場合に限り、個人情報の利用目的を変更するものとします。 利用目的の変更を行った場合には、変更後の目的について、当社所定の方法により、ユーザーに通知し、または本ウェブサイト上に公表するものとします。 第5条(個人情報の第三者提供) 当社は、次に掲げる場合を除いて、あらかじめユーザーの同意を得ることなく、第三者に個人情報を提供することはありません。ただし、個人情報保護法その他の法令で認められる場合を除きます。 人の生命、身体または財産の保護のために必要がある場合であって、本人の同意を得ることが困難であるとき 公衆衛生の向上または児童の健全な育成の推進のために特に必要がある場合であって、本人の同意を得ることが困難であるとき 国の機関もしくは地方公共団体またはその委託を受けた者が法令の定める事務を遂行することに対して協力する必要がある場合であって、本人の同意を得ることにより当該事務の遂行に支障を及ぼすおそれがあるとき 予め次の事項を告知あるいは公表し、かつ当社が個人情報保護委員会に届出をしたとき 利用目的に第三者への提供を含むこと 第三者に提供されるデータの項目 第三者への提供の手段または方法 本人の求めに応じて個人情報の第三者への提供を停止すること 本人の求めを受け付ける方法 前項の定めにかかわらず、次に掲げる場合には、当該情報の提供先は第三者に該当しないものとします。 当社が利用目的の達成に必要な範囲内において個人情報の取扱いの全部または一部を委託する場合 合併その他の事由による事業の承継に伴って個人情報が提供される場合 個人情報を特定の者との間で共同して利用する場合であって、その旨並びに共同して利用される個人情報の項目、共同して利用する者の範囲、利用する者の利用目的および当該個人情報の管理について責任を有する者の氏名または名称について、あらかじめ本人に通知し、または本人が容易に知り得る状態に置いた場合 第6条(個人情報の開示) 当社は、本人から個人情報の開示を求められたときは、本人に対し、遅滞なくこれを開示します。ただし、開示することにより次のいずれかに該当する場合は、その全部または一部を開示しないこともあり、開示しない決定をした場合には、その旨を遅滞なく通知します。なお、個人情報の開示に際しては、1件あたり1、000円の手数料を申し受けます。 本人または第三者の生命、身体、財産その他の権利利益を害するおそれがある場合 当社の業務の適正な実施に著しい支障を及ぼすおそれがある場合 その他法令に違反することとなる場合 前項の定めにかかわらず、履歴情報および特性情報などの個人情報以外の情報については、原則として開示いたしません。 第7条(個人情報の訂正および削除) ユーザーは、当社の保有する自己の個人情報が誤った情報である場合には、当社が定める手続きにより、当社に対して個人情報の訂正、追加または削除(以下、「訂正等」といいます。)を請求することができます。 当社は、ユーザーから前項の請求を受けてその請求に応じる必要があると判断した場合には、遅滞なく、当該個人情報の訂正等を行うものとします。 当社は、前項の規定に基づき訂正等を行った場合、または訂正等を行わない旨の決定をしたときは遅滞なく、これをユーザーに通知します。 第8条(個人情報の利用停止等) 当社は、本人から、個人情報が、利用目的の範囲を超えて取り扱われているという理由、または不正の手段により取得されたものであるという理由により、その利用の停止または消去(以下、「利用停止等」といいます。)を求められた場合には、遅滞なく必要な調査を行います。 前項の調査結果に基づき、その請求に応じる必要があると判断した場合には、遅滞なく、当該個人情報の利用停止等を行います。 当社は、前項の規定に基づき利用停止等を行った場合、または利用停止等を行わない旨の決定をしたときは、遅滞なく、これをユーザーに通知します。 前2項にかかわらず、利用停止等に多額の費用を有する場合その他利用停止等を行うことが困難な場合であって、ユーザーの権利利益を保護するために必要なこれに代わるべき措置をとれる場合は、この代替策を講じるものとします。 第9条(プライバシーポリシーの変更) 本ポリシーの内容は、法令その他本ポリシーに別段の定めのある事項を除いて、ユーザーに通知することなく、変更することができるものとします。 当社が別途定める場合を除いて、変更後のプライバシーポリシーは、本ウェブサイトに掲載したときから効力を生じるものとします。 第10条(お問い合わせ窓口) 本ポリシーに関するお問い合わせは、下記の窓口までお願いいたします。 住所: 愛知県 社名: moai合同会社 担当部署: 問い合わせ担当 Eメールアドレス: 以上

August 20, 2025 · 1 min · moai

Recipist利用規約

利用規約 この利用規約(以下、「本規約」といいます。)は、moai合同会社(以下、「当社」といいます。)がこのウェブサイト上で提供するサービス(以下、「本サービス」といいます。)の利用条件を定めるものです。登録ユーザーの皆さま(以下、「ユーザー」といいます。)には、本規約に従って、本サービスをご利用いただきます。 第1条(適用) 本規約は、ユーザーと当社との間の本サービスの利用に関わる一切の関係に適用されるものとします。 当社は本サービスに関し、本規約のほか、ご利用にあたってのルール等、各種の定め(以下、「個別規定」といいます。)をすることがあります。これら個別規定はその名称のいかんに関わらず、本規約の一部を構成するものとします。 本規約の規定が前条の個別規定の規定と矛盾する場合には、個別規定において特段の定めなき限り、個別規定の規定が優先されるものとします。 第2条(利用登録) 本サービスにおいては、登録希望者が本規約に同意の上、当社の定める方法によって利用登録を申請し、当社がこれを承認することによって、利用登録が完了するものとします。 当社は、利用登録の申請者に以下の事由があると判断した場合、利用登録の申請を承認しないことがあり、その理由については一切の開示義務を負わないものとします。 利用登録の申請に際して虚偽の事項を届け出た場合 本規約に違反したことがある者からの申請である場合 その他、当社が利用登録を相当でないと判断した場合 第3条(ユーザーIDおよびパスワードの管理) ユーザーは、自己の責任において、本サービスのユーザーIDおよびパスワードを適切に管理するものとします。 ユーザーは、いかなる場合にも、ユーザーIDおよびパスワードを第三者に譲渡または貸与し、もしくは第三者と共用することはできません。当社は、ユーザーIDとパスワードの組み合わせが登録情報と一致してログインされた場合には、そのユーザーIDを登録しているユーザー自身による利用とみなします。 ユーザーID及びパスワードが第三者によって使用されたことによって生じた損害は、当社に故意又は重大な過失がある場合を除き、当社は一切の責任を負わないものとします。 第4条(利用料金および支払方法) ユーザーは、本サービスの有料部分の対価として、当社が別途定め、本ウェブサイトに表示する利用料金を、当社が指定する方法により支払うものとします。 ユーザーが利用料金の支払を遅滞した場合には、ユーザーは年14.6%の割合による遅延損害金を支払うものとします。 第5条(禁止事項) ユーザーは、本サービスの利用にあたり、以下の行為をしてはなりません。 法令または公序良俗に違反する行為 犯罪行為に関連する行為 本サービスの内容等、本サービスに含まれる著作権、商標権ほか知的財産権を侵害する行為 当社、ほかのユーザー、またはその他第三者のサーバーまたはネットワークの機能を破壊したり、妨害したりする行為 本サービスによって得られた情報を商業的に利用する行為 当社のサービスの運営を妨害するおそれのある行為 不正アクセスをし、またはこれを試みる行為 他のユーザーに関する個人情報等を収集または蓄積する行為 不正な目的を持って本サービスを利用する行為 本サービスの他のユーザーまたはその他の第三者に不利益、損害、不快感を与える行為 他のユーザーに成りすます行為 当社が許諾しない本サービス上での宣伝、広告、勧誘、または営業行為 当社のサービスに関連して、反社会的勢力に対して直接または間接に利益を供与する行為 その他、当社が不適切と判断する行為 第6条(本サービスの提供の停止等) 当社は、以下のいずれかの事由があると判断した場合、ユーザーに事前に通知することなく本サービスの全部または一部の提供を停止または中断することができるものとします。 本サービスにかかるコンピュータシステムの保守点検または更新を行う場合 地震、落雷、火災、停電または天災などの不可抗力により、本サービスの提供が困難となった場合 コンピュータまたは通信回線等が事故により停止した場合 その他、当社が本サービスの提供が困難と判断した場合 当社は、本サービスの提供の停止または中断により、ユーザーまたは第三者が被ったいかなる不利益または損害についても、一切の責任を負わないものとします。 第7条(利用制限および登録抹消) 当社は、ユーザーが以下のいずれかに該当する場合には、事前の通知なく、ユーザーに対して、本サービスの全部もしくは一部の利用を制限し、またはユーザーとしての登録を抹消することができるものとします。 本規約のいずれかの条項に違反した場合 登録事項に虚偽の事実があることが判明した場合 料金等の支払債務の不履行があった場合 当社からの連絡に対し、一定期間返答がない場合 本サービスについて、最終の利用から一定期間利用がない場合 その他、当社が本サービスの利用を適当でないと判断した場合 当社は、本条に基づき当社が行った行為によりユーザーに生じた損害について、一切の責任を負いません。 第8条(退会) ユーザーは、当社の定める退会手続により、本サービスから退会できるものとします。 第9条(保証の否認および免責事項) 当社は、本サービスに事実上または法律上の瑕疵(安全性、信頼性、正確性、完全性、有効性、特定の目的への適合性、セキュリティなどに関する欠陥、エラーやバグ、権利侵害などを含みます。)がないことを明示的にも黙示的にも保証しておりません。 当社は、本サービスに起因してユーザーに生じたあらゆる損害について、当社の故意又は重過失による場合を除き、一切の責任を負いません。ただし、本サービスに関する当社とユーザーとの間の契約(本規約を含みます。)が消費者契約法に定める消費者契約となる場合、この免責規定は適用されません。 前項ただし書に定める場合であっても、当社は、当社の過失(重過失を除きます。)による債務不履行または不法行為によりユーザーに生じた損害のうち特別な事情から生じた損害(当社またはユーザーが損害発生につき予見し、または予見し得た場合を含みます。)について一切の責任を負いません。また、当社の過失(重過失を除きます。)による債務不履行または不法行為によりユーザーに生じた損害の賠償は、ユーザーから当該損害が発生した月に受領した利用料の額を上限とします。 当社は、本サービスに関して、ユーザーと他のユーザーまたは第三者との間において生じた取引、連絡または紛争等について一切責任を負いません。 第10条(サービス内容の変更等) 当社は、ユーザーへの事前の告知をもって、本サービスの内容を変更、追加または廃止することがあり、ユーザーはこれを承諾するものとします。 第11条(利用規約の変更) 当社は以下の場合には、ユーザーの個別の同意を要せず、本規約を変更することができるものとします。 本規約の変更がユーザーの一般の利益に適合するとき。 本規約の変更が本サービス利用契約の目的に反せず、かつ、変更の必要性、変更後の内容の相当性その他の変更に係る事情に照らして合理的なものであるとき。 当社はユーザーに対し、前項による本規約の変更にあたり、事前に、本規約を変更する旨及び変更後の本規約の内容並びにその効力発生時期を通知します。 第12条(個人情報の取扱い) 当社は、本サービスの利用によって取得する個人情報については、当社「プライバシーポリシー」に従い適切に取り扱うものとします。 第13条(通知または連絡) ユーザーと当社との間の通知または連絡は、当社の定める方法によって行うものとします。当社は,ユーザーから,当社が別途定める方式に従った変更届け出がない限り,現在登録されている連絡先が有効なものとみなして当該連絡先へ通知または連絡を行い,これらは,発信時にユーザーへ到達したものとみなします。 第14条(権利義務の譲渡の禁止) ユーザーは、当社の書面による事前の承諾なく、利用契約上の地位または本規約に基づく権利もしくは義務を第三者に譲渡し、または担保に供することはできません。 ...

August 20, 2025 · 1 min · moai

Mastraの機能と有用性とは?

Mastraの機能と開発者における導入メリット この記事の概要: Mastraの開発者のメリットをまとめ直してみる MastraのようなLLMオーケストレーションツールが開発者になぜ必要なのかを整理します。 Mastraの機能の概観 Mastraは複雑なタスクをLLMに実行させるための開発フレームワークです。 https://mastra.ai/ Mastraは複数のステップや外部ツール連携機能に伴うを提供します。 具体的には以下のような機能です。 状態管理: 目的、過去の対話履歴や生成結果を記憶し ツール連携: 外部APIや独自の関数(ツール)をLLMが呼び出せるようにする機能。 例)Google ドキュメントの作成やメール送信といった、 タスクの連鎖(Chain/Workflow): タスクの自動実行やフローを定義できます。 例)「献立生成→買い物リスト生成→ドキュメント化」のような一連の処理を定義し、自動実行する機能。 トリガー設定: 定期実行をトリガーできる機能 例)定期実行(毎週木曜)や外部からの入力(ユーザーからの修正依頼)をきっかけにタスクを開始させる機能。 素朴な疑問: Mastraによって何が便利になるのか? 機能性は様々ありますが、なぜこのような機能性が必要になるのでしょうか? シンプルにLLMのAPIをCallして、ステップをコーディングすれば良さそうに思います。 そのため、まずはシンプルにLLMのAPIをCallして、ステップを直接コーディングする際の課題を考えてみたいと思います。 このとき、改めてMastraの有用性をまとめ直してみようと思います。 課題:素朴なLLM APIで複雑なタスクを実行する際に困ること 単純なLLM APIの呼び出し、ステップを直接コーディングするときに困ることを考えてみましょう。 状態を記憶できない: 必要な実装1)LLMは過去の生成内容を覚えていないため、その都度プロンプトでLLMに状態を教えてやる必要があります。 課題1):このときLLMに毎回コンテキストを渡す処理を書く必要があります。 外部ツールを操作できない: 必要な処理2)タスクによってはGoogle ドキュメントやカレンダー操作が必要になります。 課題2)LLMにツールの利用のためにMCPの接続を設定する必要があります。 処理の連鎖が難しい: 必要な実装3)「献立生成」と「買い物リスト生成」の連鎖タスクを作った場合、それらをコーディングする必要があります。 課題3)手順そのものの実装の手間、それぞれの結果を次の処理に確実に引き渡す仕組みを自作する必要があります。 入力形式が多様: 必要な実装4)ユーザーからのURL、画像、自然言語による修正依頼など、多様な入力を受け付けて処理を分岐させるロジックが必要です。 課題4)これらの分岐を実現する必要があります。 Mastraはどのように解決するのか? Mastraは、上記の課題を解決するための仕組みを提供します。 状態管理: 献立履歴やユーザーからのリクエストをMastraのメモリ機能で管理し、献立生成時にプロンプトへ自動的に含めることができます。 ツール連携: 「Googleドキュメント作成ツール」を定義しておけば、LLMは献立生成後にそのツールを呼び出すだけでドキュメント作成と共有を実行できます。 タスクの連鎖: 「献立生成→買い物リスト生成→ドキュメント化・共有」という一連の処理を一つのワークフローとして定義し、毎週木曜に自動実行させることが容易になります。 エージェント化: ユーザーからの多様な入力(URL、画像、修正依頼)を解釈し、適切なツール(URL読込、画像解析、献立修正)を自律的に選択・実行する「エージェント」を構築できます。 Mastraの有用性とは? LLMを利用した長期タスクを実現するAgentを開発する場合、Mastraを使うことで開発者は「何をしたいか」という本質的なロジックの定義に集中できます。 これはおそらく単発での処理や、LLMのAPI Call一発で済むようなタスクの場合には不要な処理でしょう。 複雑だったり、実行に長い時間が必要だったりする場合に複雑な処理の流れをシンプルに記述できるようになるのです。 これは個別のAPIコール、データ(献立履歴)の管理、Googleドキュメント連携といった「接着剤」の役割を果たすコードを自前で実装する手間が省けるからです。

August 20, 2025 · 1 min · moai

LINE botの作成方法

アプリケーションのUIとしてLINE botを作成する手順を示します。 LINE Developersの準備 LINE Developersにログインし、新規プロバイダーと「Messaging API」チャネルを作成します。 作成したチャネルから「チャネルアクセストークン」と「チャネルシークレット」を控えます。 サーバーサイドアプリケーションの構築 Python (Flask) や Node.js (Express) などで、LINEからのWebhookリクエストを受け取るサーバーを準備します。 ユーザーからのメッセージ(テキスト、画像など)を受信し、応答するロジックを実装します。 ロジックの実装 受信したメッセージを解析します。例えば、「肉じゃがを追加して」のようなテキストや、共有されたレシピ画像・URLを処理する部分です。 解析結果に応じて、このドキュメントで定義されている献立生成や修正の機能を呼び出します。 デプロイと設定 作成したアプリケーションをHerokuやAWSなどのサーバーにデプロイします。 デプロイしたアプリケーションのURLを、LINE Developersコンソールの「Webhook URL」に設定します。 これで、LINEを通じて献立のリクエストや修正ができるようになります。

August 20, 2025 · 1 min · moai

org-roamで異なるファイルへの見出しへのリンク取得方法

org_roamで異なるファイルへの見出しへのリンク取得方法が知りたい。 見出しをorg-roamのnodeにする =org-id-get-create=コマンドを実行する。 すると以下のようなIDが振られる。 適当な見出し :ID: cc9f43cb-6891-4322-90d5-82571fde8668 見出しに対するリンクを貼る org-roam-node-insert コマンド使って絞り込みます。 C-c n i (org-roam-node-insert) を実行します。 目的の見出しを選択して RET を押します。

August 20, 2025 · 1 min · moai

解決編:pandocでdocxをorgファイルに変換する際に何故かquoteで囲われてしまう。

Pandocは文書形式の相互変換が便利ななツールです。 私も普段から利用していますが、先日、Word(.docx)ファイルからorg-mode(.org)ファイルへ変換する際に面倒な問題に遭遇しました。 この記事では、その試行錯誤の道のりと解決策をまとめます。 課題 : 箇条書きが、意図せず#+begin_quote…#+end_quoteブロックで囲まれてしまう docx形式で作成した箇条書きリストを、Pandocを使ってorgファイルに変換したところ、2つの大きな問題が発生しました。 ネストした箇条書きが、意図せず#+begin_quote…#+end_quoteブロックで囲まれてしまう。 各リスト項目の間に、不要な空行が入ってしまい、間延びした表示になる。 問題の出力例: コード スニペット #+begin_quote 親項目1 #+begin_quote 子項目A #+end_quote #+begin_quote 子項目B #+end_quote #+end_quote このような出力は、見た目が崩れるだけでなく、構造的にも意図しない「引用」となってしまい、org-modeでの再利用性を著しく損ないます。 最終結論 この問題は、PandocのLuaフィルタを使い、変換プロセス中にリストのネストを引用としないことで解決しました。 原因は、以下の2点でした。 Word文書のインデント構造が、PandocによってリストのネストではなくBlockQuote(引用ブロック)として解釈されていた。 リストの各項目がPara(段落)要素で構成されており、これがorg-mode出力時に項目間の空行を生んでいた。 最終的に完成したLuaフィルタと実行コマンドは記事の最後にまとめてあります。 試行錯誤1:単純なBlockQuoteの解除 最初に考えたのは、「問題となっているBlockQuoteを単純に解除すればよいのでは?」というアプローチでした。 しかし、単純な条件のフィルタではうまくいかず、原因を特定する必要に迫られました。 まず、 pandoc -t native コマンドで文書の内部構造をダンプしてみると、問題の箇所は以下のような構造になっていることがわかりました。 , BulletList [ [ BlockQuote [ Para [ Str “\12456\12450\12525\12496\12452\12463\12434\36092\20837\12377\12427” ] ] , BulletList [ [ BlockQuote [ Para [ Str “\12489\12524\12483\12469\12540\12434\25448\12390\12427” ] ] ] , [ BlockQuote [ Para [ Str “\12362\12418\12385\12419\12384\12394\12434\37096\23627\12398\30495\12435\20013\12395\25345\12387\12390\12367\12427” ] ] ] , [ BlockQuote [ Para [ Str ...

August 17, 2025 · 2 min · moai

私について

山崎 遼介 (Yosuke Yamazaki) プロダクトと組織の両面を理解し、実装から事業インパクトまで貢献することを得意としています。 バックエンド・フロントエンドの実装経験や、インフラ・非同期処理に関する知識を活かし、エンジニア、EM、スクラムマスターとしての経験を基に、認証・認可領域のプロダクト戦略を実行しています。 また、組織横断での標準化やプロセス改善も推進しています。 スキル AWS Go Java React Ruby on Rails UXデザイン エンジニア採用 プロジェクトマネジメント 経歴 freee株式会社 (現職) プロダクトマネージャー SIer (前職) Webアプリケーションの開発、運用、インフラ構築、トラブルシューティングに従事。 学歴 慶應義塾大学大学院 理工学研究科 (2009-2011)

August 17, 2025 · 1 min · moai

elispにおける『,』の意義

`,` には、どのような意味があるのでしょうか? 例えば以下のようなコードを考えてみます。 (setq org-roam-capture-templates `(("d" "default" plain "%?" :target (file+head "sketches/nodes/%<%Y%m%d%H%M%S>-${slug}.org" ,(my-org-roam-hugo-header "${title}" "sketches/nodes"))) ("p" "post" plain "%?" :target (file+head "posts/%<%Y%m%d%H%M%S>-${slug}.org" ,(my-org-roam-hugo-header "${title}" "posts"))))) (setq org-roam-dailies-capture-templates `(("d" "default" entry "* %?" :target (file+head "%<%Y-%m-%d>.org" ,(my-org-roam-hugo-header "%<%Y-%m-%d>" "sketches/dailies"))))) 前提:バッククオート (`) の機能 まず、カンマを理解するには、その外側を囲んでいるバッククオート (`` ` ``) の役割を知る必要があります。 バッククオートは、内部の式を「評価させない」ための記号です。つまり、`(setq …)` のような関数呼び出しとは異なり、バッククオートで囲まれたリストはコードとして実行されず、そのままデータ(リスト構造)として扱われます。 この例では、`org-roam-capture-templates` という変数に、テンプレート定義のリストを「データとして」設定しようとしています。 本題:カンマ (,) による部分的な評価 ここで登場するのがカンマ (`,`) です。カンマは、バッククオートの「評価しない」という原則に対する唯一の例外を指定します。 カンマは、直後にある式を「この部分だけは評価(実行)せよ」とEmacs Lispに指示するマーカーです。提示されたコードを見てみましょう。 ... ,(my-org-roam-hugo-header "${title}" "sketches/nodes") ... この部分では、カンマの働きにより `my-org-roam-hugo-header` 関数が呼び出され、その *返り値*(この場合は生成されたヘッダー文字列)がリストのその位置に挿入されます。 もしカンマがなければ、`(my-org-roam-hugo-header …)` という式自体がリストの一要素として扱われてしまい、関数が実行されることはありません。これでは意図したテンプレートは完成しません。 結論:静的なデータ構造に関数の実行結果を埋め込む記法 結論として、バッククオート (`) とカンマ (,) はセットで使われ、「基本的には評価しないデータ構造を定義しつつ、特定の部分だけ動的に生成した値で置き換えたい」という場面で活躍します。 したがって、このカンマは バッククオート構文の中で関数を呼び出し、その結果を埋め込むために不可欠な記号 と言えます。

August 17, 2025 · 1 min · moai

google docを個人のorg-roamのnodeとして取り込む自動化

はじめに 本記事では、Google Drive上のGoogleドキュメントを自動で取得し、個人のorg-roamナレッジベースにノートとして取り込むための自動化スクリプト fetch_drive_data.sh について解説します。 外出先のモバイルで調査した内容をうまくナレッジにするには? 解きたかった課題は「外出先で調査・思索した内容を、いかに効率よく個人のナレッジベース(org-roam)に集約するか」という点です。 現在スマートフォンでの情報収集やアイデアメモが大きな比重を占めています。 例えばスマートフォンのGeminiアプリは、調査や文章生成に非常に強力なツールです。 しかし、その内容をorg-roamのナレッジにするのは煩雑な手順が必要です。 google docsにエクスポートして orgフォーマットに直し org-roamのnodeとして追加する このような手順を行う必要があります。手動で5ステップほどでしょうか。 少し多いですね。 一方で、GeminiアプリはGeminiの応答をGoogleドキュメントとして手軽にエクスポートできます。 Googleドキュメントとして保存する操作は、どのデバイスからでも非常に簡単です。 そのため、手軽なナレッジ追加自体は簡単に思えます。 これをうまく結合させようと思ったのが開発の発端でした。 ここからアイディアを発展させて特定のGoogle DriveをGeminiなどで調査した外部情報の「一時受け入れボックス(インボックス)」として機能させることを思いつきました。 orgzly の利用は却下した 当初は orgzly のようなモバイルアプリも検討しました。 これはorgファイルを直接モバイルでも扱えるようにするものです。 しかし、このアイディアは却下しました。 スマートフォン上で直接orgファイルのフォーマットを整えながら編集するのは、操作が煩雑に感じられたためです。 しかもGeminiアプリからの転記作業も必要です。 また、 orgzly データの同期は syncthing を用いるものが一般的なようでしたが、このアプリケーションがセキュアかどうか判断しかねたのです。 そのため、 orgzly を利用するのはやめました。 rcloneを利用してナレッジの取り込む方針とした 上記のアイディアを検討した結果、 rclone で取り込むことにしました。 そうすると必要なのはorg-roamにnodeとして取り込みを自動化する処理です。 ここまでくればあとは開発するのみです。 諸々ゴニョゴニョする必要はありますが、力技です。 具体的には以下の処理です。 rclone を使って、指定したGoogle Driveフォルダからドキュメントを一括でダウンロードする。 ダウンロードしたファイルを pandoc でorg-mode形式に変換する。 変換したファイルにorg-roam用のプロパティ(IDなど)を付与し、ノートとして所定のディレクトリに配置する。 この流れをシェルスクリプトに落とし込みます。 モバイルでGoogle Driveに保存、PCで取り込みという体験の完成 このshell scriptによってこのようなフローが実現できます。 モバイルで行うこと 調査したことをGoogle Driveに保存 PCで行うこと shellの実行 これによりモバイルで生まれた着想や調査結果を、コマンド一つでシームレスにナレッジに統合する仕組みの完成です。 参考)スクリプトの全体像 以下が、今回開発した fetch_drive_data.sh の全容です。参考に貼っておきます。 #!/bin/bash # fetch_drive_data.sh: 指定したGoogle Driveフォルダ内のすべてのGoogleドキュメントを # 一括ダウンロードし、org-roamノートに変換してDBを同期するスクリプト # --- 設定 --- # Google DriveのフォルダIDを指定 FOLDER_ID="${your_folder_id}" # org-roamのノートが保存されているディレクトリパスを指定 ORG_ROAM_DIR="org_sources/sketches/nodes/" # 作成されるorgノートに設定するHugoのセクション HUGO_NODES_SECTION="sketches/nodes" # --- 初期化 --- set -e # エラーが発生したらスクリプトを終了 TEMP_DIR=$(mktemp -d) TMP_RCLONE_CONF="/tmp/rclone.conf.$$" # スクリプト終了時に一時ファイルを必ず削除する trap 'rm -f "$TMP_RCLONE_CONF"; rm -rf "$TEMP_DIR"' EXIT # --- rclone設定 --- echo "1. rcloneの設定を読み込み中..." pass show rclone/config > "$TMP_RCLONE_CONF" export RCLONE_CONFIG="$TMP_RCLONE_CONF" echo "設定読み込み完了。" # --- 一括ダウンロード --- echo "2. Google Driveからドキュメントを一括ダウンロード中 (Folder ID: ${FOLDER_ID})..." # --include "*.gdoc" でGoogleドキュメントのみを対象にする rclone copy "gdrive:" --drive-root-folder-id "${FOLDER_ID}" "${TEMP_DIR}" -P -v # ダウンロードされたファイルがあるか確認 if [ -z "$(find "$TEMP_DIR" -name "*.docx")" ]; then echo "ダウンロードされたdocxファイルが見つかりません。処理を終了します。" exit 0 fi echo "一括ダウンロード完了。" # --- ローカルでのループ処理 --- echo "3. ダウンロードした各ファイルの処理を開始..." for DOCX_FILE in "$TEMP_DIR"/*.docx; do echo "--------------------------------------------------" echo "処理中: $(basename "$DOCX_FILE")" # 3a. pandocでorgに変換 BASENAME=$(basename "$DOCX_FILE" .docx) echo " - pandocでorgに変換中..." PANDOC_ORG_FILE="${TEMP_DIR}/${BASENAME}.org" pandoc -f docx -t org "$DOCX_FILE" -o "$PANDOC_ORG_FILE" --wrap=none # 3b. org-roam用ファイルを作成 echo " - org-roamノートを作成中..." ROAM_ID=$(uuidgen) ROAM_BASENAME=$(echo "${BASENAME}" | tr ' ' '_') ROAM_FILE_PATH="${ORG_ROAM_DIR}$(date +%Y%m%d%H%M%S)-${ROAM_BASENAME}.org" { echo ":PROPERTIES:" echo ":ID: ${ROAM_ID}" echo ":END:" echo "#+title: ${BASENAME}" echo "#+HUGO_SECTION: ${HUGO_NODES_SECTION}" echo "#+AUTHOR: moai" echo "#+HUGO_AUTO_SET_LASTMOD: t" echo "#+hugo_paired_shortcodes: reasoning" echo "" cat "$PANDOC_ORG_FILE" } > "$ROAM_FILE_PATH" echo " - ノート作成完了: ${ROAM_FILE_PATH}" done echo "--------------------------------------------------" echo "全てのファイルの処理が完了しました。" # --- DB同期とHugoエクスポート --- echo "4. org-roamデータベースを更新し、Hugoコンテンツをエクスポート中..." emacs --batch -l ~/.emacs.d/init.el --eval '(progn (org-roam-db-sync) (my-hugo-export-all-org-sources))' echo "DB同期とHugoエクスポートが完了しました。" # --- Google Driveのクリーンアップ --- echo "5. 処理済みのドキュメントをGoogle Driveから削除中..." rclone delete "gdrive:" --drive-root-folder-id "${FOLDER_ID}" --include "*.gdoc" -P -v echo "Google Driveのクリーンアップが完了しました。" echo "全ての処理が正常に完了しました。" 実際にはこのshellをmakeコマンドにして実行できるようにしています。 ...

August 17, 2025 · 2 min · moai