「そういうもの」のうちのひとつについて

長いこと、それこそ何年も何十年もずっと好きなことって、誰しもそんなに多くはないと思います。
時期ごとに熱中したものはあれど、どこかで飽きるというか、熱が冷めるもんです。
でも、中には、何年も何十年もずーっと好きでいられることがあったりします。
ずっと好きなことに出会うと、それは生活にしみわたり、それにふれるために時間をつくったり、日々の活力になったり。
それなしの人生は、ちょっとイメージしがたいくらいになります。
そういうものに出会うことができるのは、幸せなんちゃうかなぁ。
そんな風に思います。
ぼくにとって数学や本を読むことが「そういうもの」にあたります。
今回は数学について、ちょっと書きたいと思います。


いつから数学が好きなのか、と考えてみると、小学校のころにさかのぼります。

先生:じゃあ、算数ドリルの27ページを開いて、そのページの問題を解きましょう。
解けた人は先生に持ってきてねー。
いつものように、はやく全問正解した5人には、先生の代わりに「マルつけ先生」をやってもらいますからね。

ぼく:(よしゃ!今日もはやく問題解いて、マルつけ先生しよう!)

ぼくは一生懸命に問題を解き、「マルつけ先生」の役をゲットし、はりきって友だちのドリルのマルつけをしていました。
そろばんを習っていたこともあってか、みんなよりも計算をすばやくおこなうことができていました。
計算問題がササッと「できる」ことがうれしく、「マルつけ先生」になれるのが楽しかった小学校のころ。
算数が、少し好きでした。
小学校でのこの経験は、ぼくの中の大切な思い出の一つとなっています。
そして、そこからちょくちょく、数学はぼくに、強烈に印象に残る出来事を与えてくれます。

中学生のころ。
週に3日ほど塾に通っていたおかげもあってか、数学、理科、英語がまずまず得意でした。
ある日の塾での出来事を、すごく鮮明に覚えています。

先生:ノートに5cmの長さの線分をかきましょう。
みんなかけた?
じゃあここで問題です。
その線分から、2cmの距離にある点がえがく図形をかいてみましょう。

ぼく:まず線分の両側に同じ長さの線分を平行にかいて。。。
・・・
先生:おぉ、すごいな。これ、正解です。みんな、ちょっとこれ見てみて。
先生、これまで塾で教えてきたけど、正確に作図できてたのはキミがはじめてやわ。すごいすごい。

今考えれば、先生の「キミがはじめて」という言葉は、ほんとうかどうか実際のところはわかりません。
でも、ぼくは、自分で考えて、定規とコンパスを使って図をかき、それが正解であったことがむちゃくちゃうれしかった。
しかも先生に「キミがはじめて」と言われたことも、すごく誇らしかった。
考え、自分の答えを出し、それを強烈にほめてもらえた経験は、おそらくずーっと忘れないことと思います。

高校に進学し、数学がとたんに難しく感じるようになりました。
定期テストの前だけ必至こいて勉強し、なんとか赤点をまぬがれるように乗り切る。
そんな風にして、いつしか高校3年生。
大学進学のため、これまでの人生で最も勉強に励む時期に入ります。
理系クラスに進学したものの、中学まで好きだった数学は、難しくてなかなか身につかず、好きという風に感じなくなっていました。
そのころ好きだったのは、化学と物理だったでしょうか。
中学までは、数学を、問題の解き方を暗記することで対応していました。
それでなんとかなっていたんです。
けれども、高校では学ぶ内容がすごく多くなり、解き方の暗記では、自分の中に吸収しきれなくなってしまいました。
これが、数学から気持ちがはなれた原因だと思います。
でも、いくつかの出来事によって、またぼくは数学にグググッと惹きつけられていきます。
その中でも特に印象的なのは、高校3年になってからの、予備校での授業でした。

ぼくが教わった先生は、

  • 解き方の暗記ではなく、「なぜ?」を考えること。

について、熱く伝えてくれました。

  • なぜそう考えるのか?なぜそう進むのか?なぜそう扱っていくのか?
  • 数学は、その「なぜ?」に必ず答えてくれる。
  • やみくもに問題を解くのではない。
  • やみくもに式変形するのではない。
  • 条件と求めるものを明確にし、一歩一歩求めるものに向かって進んでいく。

解き方を暗記する数学から、考えて進む数学へ、180°転換した瞬間でした。
そして、その先生が教えてくれたことは、今のぼくの中に、深く深く根付いています。

予備校の先生の教えのもと、無事大学に合格できたわけですが、大学に入ってすぐに打ちのめされます。
代数学、線形代数、微分・積分学、幾何学。。。
どれもが難しく、いまひとつわからない。
それでもなんとか単位をとりつつ、3回生からはゼミがはじまりました。
あえて、ぼくのいる学部で一番厳しい先生のゼミに入り、必至こいて勉強し始めました。
ゼミの形式は、教科書を理解し、ゼミにて90分間先生に対して、何も見ずに理解した内容を解説する、というもの。
内容を理解し、頭に叩き込んでゼミにのぞまなければいけません。
少しでも理解が不十分であれば、解説の際にすぐに先生に見抜かれてしまいます。
苦労しながらも、同じゼミの友だちと協力し合いながら、なんとか教科書を読み進めていました。
ある日、勉強していて、どうしてもわからない部分にぶつかりました。
いくら考えてもわからない。
しかも、たった3行の記述について、どうしても理解することができないんです。
考えても考えてもしっくりこない。意味がとれない。後の内容につながっていかない。
その部分について、ずーっと考えました。
先生に質問することもできたのですが、そうしませんでした。
ある程度自分で考えると、躍起になって、どうにかこの部分を自分の力で理解したい、という気持ちになります。
だから、すっと考えました。
文字通り三日三晩考えました。
そしてその瞬間が訪れました。
「なるほど!そういうことか!」
この瞬間。すべてがつながる瞬間。理解できた!と確信する瞬間です。

そんなこんなで、今もまだ数学をちまちまと学んでいます。
大学生の時のこの体験、三日三晩考え、自分で理解できた体験がなかったら、もしかしたら今はもう数学を学び続けていなかったかもしれません。
それほどに強烈な体験でした。


長いこと、それこそ何年も何十年もずっと好きなことって、誰しもそんなに多くはないと思います。
でも、中には、何年も何十年もずーっと好きでいられることがあったりします。
それなしの人生は、ちょっとイメージしがたいくらいの。
そういうものに出会うことができるのは、幸せなことだと思います。
ぼくにとって数学は、「そういうもの」です。
だから、今もまだ数学を学び続けていますし、そんな数学の魅力を伝えたいと思っています。
ぼくが数学について語り、伝えていくことで、ちょっとでも数学が好きになったり、興味を持ってもらえるように。
究極は、ほかの誰かにとっても数学が「そういうもの」になってくれるように。
ずーっとそこを目指して、生きていきたいものです。

では、お読みいただきありがとうございました。

ObsidianPublishとブログの明確な境界線

これまでいろいろと書いたり試したりしてきました。
ブログから始めて、動画を載せる別ブログを立ち上げたり、Scrapboxに書いたり。
今は、やろうと思えばYouTubeで動画の公開ができたり、ポッドキャストで音声の配信ができたり、Substackでニュースレターを書けたり。
選択肢は色々とありますが、そんなに試してはおらず、ぼくの場合は2つの媒体に絞っています。

どちらも「文章を書いてそれを公開する」場なのですが、この2つには明確な違いがありまして。
「これについてはどっちに書こうかなぁ」と迷うことはありませんし、書き方・記述の仕方も違います。

Obsidianは、1ページ1テーマをつらぬく

Obsidianでは、1ページ1テーマをつらぬく気持ちで書きます。とにかく、1つのことについて書く。
未来の自分は他人という気持ちできちんとした文章で書きつつも、必要以上に説明しすぎることをせず、そこはリンクで別ページとのつながりを作りながら。
いわゆる豆論文を書く気持ちで。
ObsidianのPublishの一つひとつのページは、1ページ1テーマであるが故に、ブログなど他の文章を書く際に、言及・引用がしやすい状態である、と言えます。それらを組み合わせさえすれば文章が書ける、とまでは行かないまでも、1つのテーマについて書かれたものは、取り回しが良く、使いやすいのは間違いありません。
『知的生産の技術 (岩波新書)』(梅棹忠夫)を読んで何年も経ちますが、ようやく1枚1テーマで書く、ということに対する理解が追いついた気持ちです。
また、Obsidianのリンクする機能を使うことで、ページ同士がつながってくれており、それもまた言及・引用のしやすさに一役を買っています。Obsidian上のページをひらけば、それに関連するページが必ず表示されるので、思い起こすことができるから。

ブログは、1つの完成したものを

一方でブログは、はじめから読んでいけば内容を理解でき、それだけで完結することを意識して書いています。
そのためには、文中に出てくる語句の解説を入れる必要があったり、前提となる条件を書いたり、最後にまとめ的なことを書いたりすることが必要になります。
となると、1つの記事にはいくつものテーマが混在することになり、それでようやくはじめから読んでいけば内容を理解できる、読めるものが出来上がる、と思います。
ブログの記事は、それ一つで完結したものになるように心がける、ということです。

以下は、同じ「明日をInboxにする」ということについて書いた、Obsidianとブログの記事。かなり違いが表れていると思います。

おわりに

ブログに投稿するもの、Obsidianでpublishするもの、ブログに投稿してObsidianでもpublishするもの〜その1〜ブログに投稿するもの、Obsidianでpublishするもの、ブログに投稿してObsidianでもpublishするもの〜その2〜にて、その当時のObsidianPublishとブログの分け方を書いていました。
その時にも今回と同じような結論が出ていたのですが(書いたこと完全に忘れてた)、特に今後意識していきたいのは、「Obsidianは、1ページ1テーマをつらぬく」こと。で、ページ同士をリンクさせておくこと。
その気になれば、ブログには基本的には何を書いてもいいと考えているので、完成したものをと思いつつも、そこにはあまり縛られず、気軽に書いていきたい。
なので、ある意味Obsidianにてpublishする方が、そっちにちゃんと書いていく方が、結構難しかったりするかもしれません。
ただ、あまり書く前からハードルをあげすぎるのもよくないので、とりあえず書いて、後からどんどん手入れしていくという方針で、1ページ1テーマをつらぬいていこうと考えています。

では、お読みいただきありがとうございました。

考える場所が、すぐそこに用意されているということ

デイリーページを毎日作成し、そこにタスクをかき並べて実行していくことでタスクを管理・実行しています。
主にObsidianを使っており、このObsidianには「バックリンク」なる機能が存在します。何かというと、今開いているページに言及しているページを一覧で表示してくれるもの。

これがあれば、プロジェクトに関するログの一覧が、わざわざプロジェクト用のページに書き込まなくても確認できるようになります。
ちなみにここでいう「プロジェクト」とは、完了までに何日かかかるやることのことを指していると思ってください。

ログに関しては、とりあえずそのプロジェクトのリンクを記述し(Obsidianでは「[[]]」で囲んだ部分がリンクとなります)、そこに何をしたか、などのメモを書いておけば後からログを振り返ることができます。
となると、プロジェクトのために作成したページにはログを書かないことになるので、プロジェクトページの中身はすっからかんなまま。
それがなんだかいやで、わざわざログをプロジェクトページに転記したりしていたのですが(もちろんそのように使うのもいいのですが)、こうやって書くスペースが確保されていることが尊いのだと感じます。

プロジェクトを進めていて、ある程度作業を進めているときに、「どうしよう?」と悩むことがありました。どうデータを整理していくべきかわからず、「このままなんとなくで作業を進めると後々一からやり直しになりそう」という時が。
一方で、「どうしよう?」と悩み始めてからとった動きはとてもスムーズで。
そのプロジェクトページを開き、例によって中身はすっからかんなその場所に、データから何を抽出したいのか、そのためにはいくつかのデータをどう整理して組み合わせれば目的に叶うものになりそうかを書き出していきました。
一通り書き、見通しが立った後、あぁ、このためにプロジェクトページは存在するのか、と腑に落ちました。
プロジェクトページがあれば、常に「考える場所」がそこにあるのか、と。
「どうしよう?」と悩んでからページをひらけば考える場所があり、今悩んでいることを整理し始めることができる。この環境が尊いものだ、と感じたんです。

そしてこれは、たすくまではなく、1Writerを使うようになったこととも関係しています。

Taskuma —TaskChute for iPhone
カテゴリ: 仕事効率化, ライフスタイル

1Writer – Markdown Text Editor
カテゴリ: 仕事効率化, ユーティリティ

メモを書く場合、またそれを確認する場合は、たすくまでメモするよりもテキストエディタに書いていった方が自分の好みにあっているという理由もありますが、何よりもエディタなら「考えながら書く」ことができるってのが何物にも変え難い。
たすくま上では「考えながら書く」ということがなんだかできなくて。
また、たすくまでメモしたものは、書き込んだタスクをタップしてタスクの詳細画面にいかないと目に入りません。ログをエクスポートすればEvernote上で確認できるようになりますが、たすくま上では常にメモしたものは隠れたまま。
一方で、エディタ上に1日のタスクをたすくま並みに詳細に書き連ね、そこにメモも直接書き込んでいく1Writerであれば、1Writerをひらけばメモも一緒に目に入ります。書いたメモが勝手に目に入ってくれる。
着想メモは、放り込むだけより、書き込むときに過去のものが目に入ったほうがいいと考えているので、それにはたすくまではなく1Writerだなぁ、と。
それには、たすくまの便利さをかなりの部分手放す必要があったわけですが、今のところなんとかなっています。


考える場所が、すぐそこに用意されていること。
そういう環境が今実現されているので、今までになくいい感じにプロジェクトについて考え、タスクを進め、メモを書き残せている気がします。

では、お読みいただきありがとうございました。

ファイルからリストを作成して、リピートタスクを呼び出す〜1Writerカスタマイズ④〜

「1Writerカスタマイズ」の①〜③にて書いたアクションを作成した段階で、たすくまを使うのをやめ、1Writer(Obsidian)に完全移行しました。

1Writer – Markdown Text Editor
カテゴリ: 仕事効率化, ユーティリティ

Taskuma —TaskChute for iPhone
カテゴリ: 仕事効率化, ライフスタイル

デイリーのテンプレートと、行ごとの削除と移動があれば、一つ一つの行動を記録しながら過ごすことは、けっこう簡単になります。
あとは、予定になかった、つまり、デイリーページ上に書き込まれていないリピートタスクを呼び出すことができれば、終了予定の算出だけがないタスクシュートと呼べるようになるでしょう。
ということで、「リピートタスクの呼び出しできるようにならないか」と考えました。

1Writerのjavascriptアクションの数々には例が載っています。試しに「ui.list()」の例を実行してみると、項目がリスト表示され、そのリストから好きなものをタップすると、そのリストの内容が文中に挿入されるものでした。
これは、使えそうです。
そのコードを書き換え、

  • リピートタスクの一覧が記述されたファイルを開く
  • それをリスト形式に表示する
  • 選択された項目をクリップボードにコピーする

というものにしました。

リピートタスクの呼び出し

//アクションを実行したあと、元のファイルに戻るため、今編集中ファイルのフォルダとファイル名を取得
var folder = editor.getFolderPath();
var editingfile = editor.getFileName();

//リピートタスクを記述しているファイルのファイル名
var openfilename = 'ここに一覧を取得したいファイル名を記述.md'

//リピートタスクの一覧が記述されているファイルを開く。フォルダは、そのファイルが保存されているものを指定してください。
editor.openFile('Dropbox/'+openfilename,'edit',call);

function call(){
    //開いたファイルに記述されているテキストを取得
    var text = editor.getText();
    //改行ごとに配列に格納
    const listData = text.split('\n');
    ui.hudDismiss();
    //配列をリストに
    ui.list('Repeat', listData, false, selectedValues => {
        if (!selectedValues) {
            return;
        }
        const text = selectedValues.join('\n');
        if (editor.isClosed()) {
            editor.newFile(text);
        }else {
            //選択した項目をクリップボードにコピー
            app.setClipboard('\n' + text);
            //はじめに編集中だったファイルを開く
            editor.openFile(folder + '/' + editingfile);
        }
    });
}

アクションを起動した時の動き

アクションを起動するとリストが表示され、そのうち一つを選択すると選択した項目のがクリップボードにコピーされ、元のファイルに戻ってくるので、好きな場所に貼り付けることができます。
リストは、複数選択を可能にもできるので、その場合は
ui.list('Repeat', listData, false, selectedValues
のfalseの部分をtrueに書き換えてください。

まずは、リスト表示したいファイルを作成して、そのファイル名をコード内の「ここに一覧を取得したいファイル名を記述」の部分に書くことでアクションが使えるようになします。
改行を目じるしに、1行1項目でリストに表示するので、リスト表示したいファイルは、そのことを念頭に置いた上で作成していただければと思います。


これまで4回にわたり1Writerの自作アクションについて書いてきました。これにて、「やったことの記録がすこぶる取りやすいリストアプリ」のように、テキストを扱えるようになり、日々、デイリーリストを作成し、1WriterとObsidianで同一のファイルを扱いながら、やったことの記録をとりつつ過ごしています。
まずまず気に入っているので、しばらくはこのまま使い続けようかな、と思います。

では、お読みいただきありがとうございました。

別ファイルに記述されたデイリーテンプレートを呼び出す〜1Writerカスタマイズ③〜

テキストを1行ごとに削除したり移動したりできるようにすることで、「1行ごとのリスト」として扱えるようにしたのが前回までの話。

1Writer – Markdown Text Editor
カテゴリ: 仕事効率化, ユーティリティ

これでかなり便利になり、1行単位での操作ができるようになったので、箇条書きやチェックリストがすごく扱いやすくなりました。
こうなると本格的に「テキストエディタでタスク管理」がしたくなってきます。
しかもぼくは普段から「たすくま」を利用しているので、テキストエディタである1Writerでも、たすくまのように「すべての行動を記録してはいけないものか」、と考えました。

Taskuma —TaskChute for iPhone
カテゴリ: 仕事効率化, ライフスタイル

となると不可欠になってくるのが、リピートタスクを呼び出すこと。
毎日やっていることに関しては、リピートタスクとして登録しておき、日々それを呼び出してタスクリストを作ることで、たすくまのような「やったことの記録がすこぶる取りやすい」テキストエディタが実現します。

1Writerには、「指定したファイルを開く」アクションがあり、それを使うことでテンプレートを呼び出すアクションを作ることができます。
アクションを起動すると、

  • あらかじめ作成したテンプレートファイルを開く
  • 内容をコピーする
  • 元のファイルに戻ってくる

ところまでやってくれるので、あとは任意の場所にペーストするだけ。
準備は、テンプレート用のファイルを作成しておくことと、以下のコードの「ここにテンプレートファイル名を記述」の場所を自分で書き換えること。

テンプレートファイルを開き、コピーし、戻るアクション

d=new Date();
today=d.getFullYear()+zero(d.getMonth()+1)+zero(d.getDate());
yesterday = d.getFullYear()+zero(d.getMonth()+1)+zero(d.getDate()-1);
tomorrow = d.getFullYear()+zero(d.getMonth()+1)+zero(d.getDate()+1);
oneyearsago = (d.getFullYear()-1)+zero(d.getMonth()+1)+zero(d.getDate());
twoyearsago = (d.getFullYear()-2)+zero(d.getMonth()+1)+zero(d.getDate());
threeyearsago = (d.getFullYear()-3)+zero(d.getMonth()+1)+zero(d.getDate());
var dayOfWeek = d.getDay(); // 曜日(数値)
var weekday = [ "(Sun)", "(Mon)", "(Tue)", "(Wed)", "(Thu)", "(Fri)", "(Sat)" ][dayOfWeek]; // 曜日(日本語表記)

var folder = editor.getFolderPath();
var editingfile = editor.getFileName();

var openfilename = "ここにテンプレートファイル名を記述.md";

editor.openFile('Dropbox/Days/'+openfilename,'edit',call); //ファイル名の前には、フォルダを指定。ここでは、「Dropbox」フォルダ内の、「Days」フォルダを指定している。

function call(){
    var text = editor.getText();
    var text = text.replace(/{{today}}/g,today).replace(/{{tomorrow}}/g,tomorrow).replace(/{{yesterday}}/g,yesterday).replace(/{{oneyearsago}}/g,oneyearsago).replace(/{{twoyearsago}}/g,twoyearsago).replace(/{{threeyearsago}}/g,threeyearsago).replace(/{{weekday}}/g,weekday);
    app.setClipboard(text);
    editor.openFile(folder + '/' + editingfile);
}

function zero(s){return ("0"+s).substr(-2)}

コード内に、{{today}}や{{yesterday}}という記述があることにお気づきでしょうか。
これは、テンプレートのテキスト内の{{today}}と書かれている部分を、今日の日付に変換するための記述です。

このように書かれている場合、アクションを起動してテンプレートの内容を取得し、ペーストすると

こうなります(スクショは4月15日に撮影)。

{{oneyearsago}}や{{twoyearsago}}は、1年前、2年前の同じ月日。Obsidianにて連用手帳を実践していて、その際1年前や2年前のページを見返したいので、テンプレートに組み込んでいます。

テンプレートは1つのmdファイルなので、編集が簡単。
ただ、たすくまのような複雑なリピート設定はできないので、そこは今後工夫する必要がありそうです。


これで、日々のリピートは簡単に呼び出し可能になり、かなり詳細な記録を取ることができるようになりました。
こうなってくると、1日の計画を立てるときには書いていなかったタスクも、リピートに登録されているのであれば、リピート一覧から選択し、挿入できるようにしたくなってきます。
1Writerには、配列のデータから「リスト」を作成するアクションもありまして。次はそのあたりについて書いていきます。

カット・ペーストを可能にして、ダイナミックな移動を可能に〜1Writerカスタマイズ②〜

Obsidianが日々の相棒となってくれており、iPhoneでは「1Writer」というアプリを使ってObsidianで扱っているファイルと同じファイルを編集できるようにしています。

1Writer – Markdown Text Editor
カテゴリ: 仕事効率化, ユーティリティ

そして、リストアプリのようにテキストを扱えるようにするにはなにが必要かを考え、

  • 行ごとの削除
  • 行ごとの移動

の2つが欠かせないということで、

にて、削除と上下の移動は可能にすることができました。が、もっとダイナミックに移動させたいという願望が出てきました。


リストアプリでは、長押しや「編集」ボタンを押すことで、項目のドラッグ&ドロップが可能になるものが多いと思います。で、これが結構大事でして。
タスクを、実行しようと思っている順に並べているのですが、実際はそれ通りにいくことはあんまりありません。時にはリストの項目を大きく移動させたい時が出てきます。そんな時に重宝するのがドラッグ&ドロップの機能なわけです。
でもこれをテキストエディタに求めるのは、つまり1行ごとにドラッグ&ドロップによる移動ができるようにするのは、なかなかに難しい。
でもやっぱり、大きく移動させる機能は欲しい。

ということで、「カット」と「ペースト」を気軽にできるようにすることで、ドラッグ&ドロップのような動きを可能にしよう、と考えました。

  • カーソル(選択)行をカット
  • クリップボードの内容をペースト

という2つの機能があれば、リストの項目を大きく動かしたい時は、動かしたい項目をカットして動かしてきたかった場所でペーストすることができるので、ドラッグ&ドロップ機能の代わりができるだろう、と。
実際に動きを見てみましょう。

移動させたい行にカーソルを持っていく。あるいは、複数行に渡る場合は範囲選択をしておき、カット。するとその行がカットされる。移動したい先にカーソルを持っていって、ペーストボタンを押せばそこに移動完了です。
この機能で、さらにテキストエディタの内容を1行ごとに操作することが、以前よりやりやすくなりました。

カーソル(選択)行をカット

var text = editor.getText();
var linetexts = text.split('\n');
const range = editor.getSelectedRange();
var s = range[0];
var e = range[1];
var selects;
var selecte;
var linecount = 0;
var selectrange;
for (let i = 0; i < linetexts.length; i++){
    if ( s <
        linecount + linetexts[i].length +1){
        selects = i;
        selectrange = linecount - 1;
        break;
    }else{
        linecount += linetexts[i].length + 1;
    }
}
linecount = 0;
for (let i = 0; i < linetexts.length; i++){
if ( e <
    linecount + linetexts[i].length +1){
        selecte = i;
        break;
    }else{
        linecount += linetexts[i].length + 1;
    }
}

var before = -1;
for(let i=0; i < selects;i++){
    before = before + linetexts[i].length + 1;
}
var after = before;
if(before < 0){
    before = 0;
}
for(let i=selects; i < selecte+1;i++){
    after = after + linetexts[i].length + 1;
}
editor.replaceTextInRange(before, after, "")
var cutlines = [];
for(let i = 0; i < selecte-selects+1; i++){
    cutlines.push(linetexts[selects + i])
}
var cuttext = cutlines.join('\n');
app.setClipboard('\n' + cuttext);

クリップボードの内容をペースト

“`
var text = editor.getText();
var linetexts = text.split('\n');
const range = editor.getSelectedRange();
var s = range[0];
var e = range[1];

var cuttext = app.getClipboard();

editor.replaceTextInRange(s,e,cuttext);
“`

テキストエディタ上のテキストを1行ごとに扱うことができるようになることが、iPhone上ではこんなに快適になるものなんだな、と驚いています。
ついでに、カーソル行をコピーするアクションも作りました。

カーソル(選択)行をコピー

var text = editor.getText();
var linetexts = text.split('\n');
const range = editor.getSelectedRange();
var s = range[0];
var e = range[1];
var selects;
var selecte;
var linecount = 0;
var selectrange;
for (let i = 0; i < linetexts.length; i++){
if ( s <
linecount + linetexts[i].length +1){
selects = i;
selectrange = linecount - 1;
break;
}else{
linecount += linetexts[i].length + 1;
}
}
linecount = 0;
for (let i = 0; i < linetexts.length; i++){
if ( e <
linecount + linetexts[i].length +1){
selecte = i;
break;
}else{
linecount += linetexts[i].length + 1;
}
}
var cutlines = [];
for(let i = 0; i < selecte-selects+1; i++){
cutlines.push(linetexts[selects + i])
}
var cuttext = cutlines.join('\n');
app.setClipboard('\n' + cuttext);

  • カーソル(選択)行を削除
  • カーソル(選択)行を上へ移動
  • カーソル(選択)行を下へ移動
  • カーソル(選択)行をカット
  • カーソル(選択)行をコピー
  • クリップボードの内容をペースト

以上のアクションをカスタムキーボードに設定し、毎日使っています。

とても快適になったわけですが、1Writerで、たすくまのように「全ての行動を記録する」となると、行ごとの操作に加え、リピートタスクを設定し、それを簡単に呼び出せる仕組みが必要になってきます。全ての行動を記録する際、毎日やっていることに関しては、。毎日入力するよりもテンプレートで引っ張って来る方が明らかに手間が省けます。ましてや、たすくまのタスク数は大体40程度。それらを毎日入力するのは現実的ではありません。

そこで、1Writerにも、テンプレートを引っ張ってきてエディタ部分に入力し、たくさんのタスク名をいちいち入力しなくて住むようになりました。が、これはまた別の機会に。

テキストを「1行ごとのリスト」ととらえ、削除と移動を可能に〜1Writerカスタマイズ①〜

タスク管理アプリの多くは、長年使っている「たすくま」もそうですが「リスト」の形式をとっています。

1タスク1リスト(1タスク1行)の表示で、タスクがダァーッと並んでいる形式。
確かにこの形式は、タスク管理をする上で扱いやすいなぁと感じます。
リスト形式であれば、

  • 行の削除ができる
  • 行の順番の入れ替えができる

という機能を備えており、それがタスクを扱いやすくしてくれている要因ではないか、ということで、「やったことの記録がすこぶる取りやすいリストアプリ」のように、テキストを扱えるようにしたいな、という思いがわいたわけでした。
「アウトライナー」をタスク管理に利用している方も多くいられると思うのですが、それは、アウトライナーは行の削除と順番の入れ替えが容易であるというのも大いに関係していると感じます。

ぼくは、タスク管理に今はObsidianを使っているのですが、iPhoneでは、「1Writer」というアプリを使っています。

1Writer – Markdown Text Editor
カテゴリ: 仕事効率化, ユーティリティ

1Writerはjavascriptを扱えますので、テキストを加工することができます。そこで、1Writerのjavascript機能を使って、

  • 行の削除ができる
  • 行の順番の入れ替えができる

という機能を実装しようと考えました。
そうして作成したのが、以下の3つのアクション。

  • カーソル(選択)行を削除
  • カーソル(選択)行を上へ移動
  • カーソル(選択)行を下へ移動

カーソル(選択)行を削除

var text = editor.getText();
var linetexts = text.split('\n');
const range = editor.getSelectedRange();
var s = range[0];
var e = range[1];
var selects;
var selecte;
var linecount = 0;
var selectrange;
for (let i = 0; i < linetexts.length; i++){
    if ( s <
        linecount + linetexts[i].length +1){
        selects = i;
        selectrange = linecount - 1;
        break;
    }else{
        linecount += linetexts[i].length + 1;
    }
}
linecount = 0;
for (let i = 0; i < linetexts.length; i++){
    if ( e <
        linecount + linetexts[i].length +1){
        selecte = i;
        break;
    }else{
        linecount += linetexts[i].length + 1;
    }
}

var before = -1;
for(let i=0; i < selects;i++){
    before = before + linetexts[i].length + 1;
}
var after = before;
if(before < 0){
    before = 0;
}
for(let i=selects; i < selecte+1;i++){
    after = after + linetexts[i].length + 1;
}
editor.replaceTextInRange(before, after, "")

カーソル(選択)行を上へ移動

var text = editor.getText();
var linetexts = text.split('\n');
const range = editor.getSelectedRange();
var s = range[0];
var e = range[1];
var selects;
var selecte;
var linecount = 0;
var selectrange;
for (let i = 0; i < linetexts.length; i++){
    if ( s <
        linecount + linetexts[i].length +1){
        selects = i;
        selectrange = linecount - 1;
    break;
    }else{
        linecount += linetexts[i].length + 1;
    }
}
linecount = 0;
for (let i = 0; i < linetexts.length; i++){
    if ( e <
        linecount + linetexts[i].length +1){
        selecte = i;
        break;
    }else{
        linecount += linetexts[i].length + 1;
    }
}

var before = 0;
for(let i=0; i < selects;i++){
    before = before + linetexts[i].length + 1;
}
var after = before;
if(before < 0){
    before = 0;
}
for(let i=selects; i < selecte+1;i++){
    after = after + linetexts[i].length + 1;
}
editor.replaceTextInRange(before, after, "")
var cutlines = [];
for(let i = 0; i < selecte-selects+1; i++){
    cutlines.push(linetexts[selects + i])
}
var cuttext = cutlines.join('\n');

if ( selects == 0 ){
    editor.replaceTextInRange(0, 0, cuttext + '\n');
    editor.setSelectedRange(cuttext.length,cuttext.length);
}else if( selects == 1 ){
    editor.replaceTextInRange(0, 0, cuttext + '\n');
    editor.setSelectedRange(s - linetexts[0].length-1,e-linetexts[0].length-1);
}else{
    var before = 0;
    for(let i=0; i < selects-1;i++){
        before = before + linetexts[i].length + 1;
    }
    editor.replaceTextInRange(before-1, before-1, '\n'+cuttext)
    editor.setSelectedRange(s - linetexts[selects-1].length-1,e-linetexts[selects-1].length-1);
}

カーソル(選択)行を下へ移動

var text = editor.getText();
var linetexts = text.split('\n');
const range = editor.getSelectedRange();
var s = range[0];
var e = range[1];
var selects;
var selecte;
var linecount = 0;
var selectrange;
for (let i = 0; i < linetexts.length; i++){
    if ( s <
        linecount + linetexts[i].length +1){
        selects = i;
        selectrange = linecount - 1;
        break;
    }else{
        linecount += linetexts[i].length + 1;
    }
}
linecount = 0;
for (let i = 0; i < linetexts.length; i++){
    if ( e <
        linecount + linetexts[i].length +1){
        selecte = i;
        break;
    }else{
        linecount += linetexts[i].length + 1;
    }
}

var before = 0;
for(let i=0; i < selects;i++){
    before = before + linetexts[i].length + 1;
}

if ( selecte == linetexts.length-1 ){

}else{

    var after = before;
    if(before < 0){
        before = 0;
    }
    for(let i=selects; i < selecte+1;i++){
        after = after + linetexts[i].length + 1;
    }
    editor.replaceTextInRange(before, after, "")
    var cutlines = [];
    for(let i = 0; i < selecte-selects+1; i++){
        cutlines.push(linetexts[selects + i])
    }
    var cuttext = cutlines.join('\n');
    var before = 0;
    for(let i=0; i < selecte+1;i++){
        before = before + linetexts[i].length + 1;
    }
    editor.replaceTextInRange(before-1+linetexts[selecte+1].length-cuttext.length, before-1+linetexts[selecte+1].length-cuttext.length, '\n'+cuttext);
    editor.setSelectedRange(s + linetexts[selecte+1].length+1,e+linetexts[selecte+1].length+1);
}

おそらくあんまりキレイなコードではないと思うのですが、、、便利なのでよかったら使ってみてください。

で、これらによって、テキストを行ごとに削除したり移動したりが簡単になったわけです。でも、だいぶと便利になったのに、さらに欲が出てきまして。
もっとダイナミックに移動させたいようになってきました。

つづく

自分で書いた記事・R-styleの記事ではっきり覚えているもの WRM「今週のQ」

倉下忠憲のWRM 「読む・書く・考えるの探求」第546号、ラディカルなRashitaのスタイルの変容の「今週のQ」での問いかけです。


ふと考えてみて、すぐに思いつくのは。「数学からぼくが学んだこと」と題しての連載です。

この4つのエントリで、自分が思う数学の良さや数学との向き合い方をけっこう伝えることができたのではないかと感じるくらいに、かなり力を入れた、じっくりと書き上げた記事となりました。

他には、

もとても思い入れの強い記事です。

は、かなり前に書いたものを、他の人が6年越しにツイートしてくれて、ふと目に飛び込んできて読み返して少しだけ修正を加えて新たにポストしたもの。

自分で書いた記事ではっきり覚えているものはこれらの記事かな、と思います。
どれも、数学に関して書いたもの。
数学についてどんどんブログで書きたい、と思っているものの、なかなかにそれができておらず、でもなんとかしっかりまとめ切れたという感覚があるからこそ、これらの記事はかなりはっきりと覚えているのだろうな、と思います。


R-styleの記事ではっきり覚えているのは、個人の書くブログの楽しさを教えてくれた

から始まる、一連の連載。
R-styleで展開される、Evernoteというツール越しに見る知的生産についての話が、すごく面白く、興味深く、ブログというのは面白いんだなーと思うようになったきっかけの記事となります。
で、そこから自分もブログを書きたい、となって実際に更新を始めるまでさほど時間はかかりませんでした。で、今もまた更新している、とうわけです。

他には、今ふと思い出したのが、

という、4月1日に書かれた記事。もう11年前になるんですね。
なぜこの記事が記憶に残っているかというと、

という本が、後に発売されることとなるからです。
書評 クラウド時代の知的生産の技術(倉下忠憲)が書かれたのは、倉下さんが物書きになる前、『Evernote「超」仕事術』の発売される前だったと思います。まだ本を1冊も世に出していない状況で、自分が本を出した体で記事がかかれているのがこの記事。
やがてコンビニの店長から物書きにジョブチェンジされて、『Evernote「超」仕事術』が発売され、『Evernote「超」知的生産術』がその後に続きます。
そして、『Evernoteとアナログノートによる ハイブリッド発想術』が発売され、その告知エントリが書かれて。
「ついに!!」と感動・興奮した記憶があるので、とても記憶に残っているのだと思います。

他にも、

は、よく覚えている記事の一つ。R-styleにて倉下さんの書く記事に触発されて自分も記事を書いたりしますが、やはりそういう触発を生んでくれた記事は覚えているものが多いように感じます。


自分のブログとR-styleの記事の中から覚えているものをあげてみました。
記憶力に自信がないく、基本的に忘れっぽい自分でも覚えている記事たちは、自分の中に色濃く残っているものたち、ということになると思います。
そういう記事をもっと書いていけたらなぁと思わなくもありませんが、ぼちぼちと日々書き続けるのを楽しくやってるので、まずは楽しむことを第一に今後も書き続けたいと思います。

では、お読みいただきありがとうございました。

抽象化の先に待っているものが感じられるTED動画

小学校で学ぶ算数と、中学校以降に学ぶ数学。このふたつには大きな違いがあります。
よく「算数は普段使うから必要やけど、数学を普段使うことはない。やから必要ない」って意見を聞いたりしますが、「必要ない」という部分以外はまさにそのとおりだと思います。「算数は普段使うから必要やけど、数学を普段使うことはない」。だって、扱う対象が違うんですもの。

算数で扱うのは、”具体的”です。具体的な数を扱い、数に関する知識を学びながら、四則演算を習熟していきます。に対して数学で扱う対象は”抽象的”なもの。数学では「文字式」を筆頭に、普段の生活ではなかなか出てこない、抽象化された世界へと踏み込んで行きます。
だから「算数は普段使うから必要やけど、数学を普段使うことはない」んです。ただ、必要ないことは決してないですが。

抽象化してなんなのさ

じゃあ、抽象化していったいなんだというのでしょうか。

中学校に入り、いきなり度肝を抜かれるのが、文字式だと思います。
それまでは500とか1.2とか具体的な数字を用いていたのに、なんだかxとかyとかが登場してきて、それで式を表現したりします。抽象化された世界への第一歩を踏み出すわけです。

算数の有名な問題で「鶴亀算」というのがあります。鶴と亀の数とその足の総数からそれぞれ何匹いるのかを求める問題です。

算数の世界ではあくまでも具体的な数を扱うので、まずは「すべて鶴であるとする」という仮定から始めての、総数を求めて行きます。それはそれで大切な考え方を学ぶことができるのですが、文字式を獲得したあとであれば、”方程式”という強力な武器が使えるようになります。こっちの方は鶴亀算のみならず、いろんな問題に応用可能です。

具体的な世界を離れる、ということは、応用範囲を広めることにつながります。

「ロバートラングが全く新しい時代の折り紙を折る」

抽象化することの恩恵がすごく感じられる動画が、TEDにあります。それが「ロバートラングが全く新しい時代の折り紙を折る」。

とにもかくにも動画を見て欲しいなと思います。「折り紙もすごいとこまできたもんだ」と感心すること請け合いです。

ロバート・ラングが全く新しい時代の折り紙を折る | Video on TED.com

今回注目して欲しいのは、折り方をコンピュータに計算してもらうことができるようになるまでの話の部分です。
そこでは、いろんな折り方のすべてに共通する要素を抜き出してしまうと、たった4つの法則にたどり着くことができる、ということが述べられています。
折り紙には古くから培われてきた、本当に様々な折り方ってのが存在します。これまでは一つ一つ折り方を編み出してきたわけですが、すべての折り方に共通する法則を抜き出すことで、折り紙の世界はとたんに広がります。
簡単な骨組みを考えることで折り方をコンピュータにはじき出してもらうことができるようになったんですから。
具体物の一つ一つをから構成されていた折り紙の世界を、すべての折り方に共通している要素、”4つの法則”を抜き出すことで抽象化し、単純な要素のみで表現することで、しまいにはコンピュータに計算してもらえるようにしちゃったわけです。
コンピュータの技術がどんどん高まっている現在、こんな事例はこれからも出てくるのではないかなと思います。

おわりに

というわけで、TED動画「ロバートラングが全く新しい時代の折り紙を折る」を見ることで、抽象化の恩恵を感じ取れるのではないかなと思います。
抽象化するってのはとてもすごいことなんですけれども、抽象化されたら具体を離れるということで、目に見える対象ではなくなっちゃうんですよね。やっぱり普段の生活で扱うものは具体的なものばかりなんで、対象が抽象的なものである「数学」という学問は「別になくても困らないし、必要ないでしょ」って結論に至っちゃう人がとても多いんでしょう。
でも、だからこそおもしろい面もあるわけで。そんなのをこれからも紹介できればなと思います。

では、お読みいただきありがとうございました。

20130703202511