Textwellの2つのアクション、ReLineとReBlockを合体しました

木も見て森も見る。


Textwellがあれば段落単位でテキスト移動するのが簡単になる ReBlock
通勤中に iPod touch で文章を作り、wri.pe に保存。帰宅してから iPad で繋ぎ直して文章を編集する。毎日のルーティンが出来上がり、長文を量産できる環境になったのですが、問題は推敲の...
段落単位の推敲に使っているReBlock。行単位のReLineとほとんど同じだから棲み分けしづらい。微妙に違うからなあ。段落をざっくり消したり、並べ替えたりするときもあるし、行単位で細かく入れ替えるときもある。ああ、だったら一本にしちゃえばいいか。


Textwell 1.3.7
分類: 仕事効率化,ユーティリティ
価格: \300 (Sociomedia)

そんなわけで、行単位にも段落単位にもなるReBlockです。
Import Textwell ActionReBlock



カーソル行で分岐することにしました。空行で立ち上げれば段落単位。空行から空行までを一段落と見なすので、空行はどこかにあるでしょう。そこにカーソルを置きアクションを実行する。左端の緑帯をタップすれば段落が削られ、本文をタップすればそこに段落が移動する。それをスタック方式で「溜めて溜めて、吐いて吐いて」をするわけです。



カーソル行に文章があれば行単位の編集モード。帯が赤黒くなります。操作に関しては従来通り。タイトル欄がスタックと兼用になっています。また、二本指でスワイプすると、HTMLプレビューとコード表示をトグルします。タグのせいで表示が崩れる場合や勝手にリンクする場合、コード表示モードのほうで切り貼りしてください。



Jumperも兼ねています。スタックが空のとき、本文をタップするとTextwellの編集画面に戻る。カーソルも移動するので、見ていた場所にすぐ飛ぶことができます。再配置した後でも、スタックに何も残っていなければ勝手に内蔵ブラウザが閉じる。そのとき、再配置を破棄せず、本文に反映する仕様にしました。変だったらヒストリーで戻ればいいし。


エディタの画面はどうしても「狭く」なる宿命。全体像を見るには不向きです。それ故、プレビューが不可欠になる。でも、そのプレビューでも「編集」できれば便利じゃないですか。文字単位で推敲したり、行単位で推敲したり。「編集」に単位がある。このアクションはその部分を扱っているんだなあ、と作った後になってから気付いたりする。


【ソース】

<meta name=viewport content=initial-scale=1,user-scalable=no>
<style>
  body{
    margin:0;
    background:#eee;
    word-wrap:break-word;
  }
  hr{
    border:1px #fafafa solid;
  }
  table{
    width:100%;
    table-layout:fixed;
    font-size:small;
  }
  td.num{
    width:36px;
    color:white;
    vertical-align:top;
    text-align:center;
  }
</style>
<body id=wine></body>
<title>ReBlock</title>
<script>
  last=0;
  view=1;
  stack=new Array();
  list=new Array();
  separater=(T.current)? "\n":"\n\n";
  num=(T.current)? 1:2;
  bgcolor=(T.current)? "darkred":"#0c3";
  list=T.text.split(separater);
  Disp();
  len=T.text.length;
  wine.ontouchstart=switchView;
  T.closelets([{
    title:"Save ",
    fn:function(){saveText()}
  }])

  function Disp(){
    s="<hr>";
    for(i=0;i<list.length;i++){
      content=(view)?list[i]:list[i].replace(/</g,"&lt;");
      s+="<table><td class=num bgcolor="+bgcolor+" onClick=Minus("+i+")>"+("000"+(i+1)).slice(-4)+"</td><td onClick=Plus("+i+")>"+content.replace(/\n/g,"<br/>")+"</td></table><hr>\n";
    }
    wine.innerHTML=s;
    t=stack[stack.length-1] || "ReBlock";
    T.title(t);
  }

  function Plus(x){
    Count(x);
    if(stack.length){
      s=stack.pop();
      list.splice(x,0,s);
      Disp();
    }else{
      saveText();
    }
  }

  function Minus(x){
    s=list[x];
    if(s) stack.push(s);
    list.splice(x,1);
    Disp();
    Count(x);
  }

  function Count(x){
    last=0;
    for(i=0;i<x;i++)last+=list[i].length+num;
  }

  function switchView(e){
    if(e.touches.length>1){
      view=1-view;
      Disp();
    }
  }

  function saveText(){
    s=list.join(separater);
    T("replaceRange",{
      text:s,
      replacingRange:{len:len},
      selectingRange:{loc:last}
    });
  }

</script>