林檎の木の下で

iPhoneアプリやwebサービスの紹介など。いつもどうしたら毎日を効率良く過ごせるか考えてます。

【ノンプログラマーが作るTextwellアクション】その5 挿入

   

【ノンプログラマーが作るTextwellアクション】その5 挿入patience-games-232290_640

こんにちは、sakurako(@0518sakurako)です。

今回はデフォルトのアクション集では「Edit」のカテゴリーにある挿入というアクションを考えてみようと思います。

スポンサーリンク

まず、アクション集にある挿入というアクションは次のものがあります。

  • Bullets(*)
  • Bullets(-)
  • Bullets(・)
  • Bullets(1.)
  • Insert”(“and”)”
  • Insert”<>”and”</>”
  • Insert”Hello”
  • Indent(2 Space)
  • Indent(4 Space)
  • Indent(Tab)

行の初めにスペースやタブを挿入するという位置づけでIndentも挿入に含めました。

Bullet、Insert、Indentにわけて考えてみようと思います。

Textwell

360円
(2015.06.30時点)
posted with ポチレバ

Bullet

文章の初めに特定の文字を入れるアクションです。

基本的には次のような流れになっています。

挿入したいものを指定→改行ごとで文章を分ける→分けたものに挿入したいものをつける→T.(‘replaceRange’)で元のテキストと挿入したいものをつけたテキストを入れ替える

挿入したいものをつけるのは*、-、・はvar prefix = ‘挿入したいもの’ で示すことができます。つまりこの最初の一文を変えることで何でも挿入できるわけです。

さらに前回の記事のClearに複数タスクを登録する際にも使われたのと同じソースが入っています。

var text = T.text;
var selectionStart = T.range.loc;
var selectionEnd = selectionStart + T.range.len;
var hitLines = [];
var pointerStart = 0;
var pointerEnd = 0;
var lines = text.split( ‘\n’ );
var replacingRangeLoc = 0;
for ( var i = 0, l = lines.length; i < l; i++ ) {
var lineString = lines[ i ];
var pointerEnd = pointerStart + lineString.length;
if ( pointerStart > selectionEnd ) {
break;
};
if (
( pointerStart <= selectionStart && selectionStart <= pointerEnd ) ||
( pointerStart <= selectionEnd && selectionEnd <= pointerEnd ) ||
( selectionStart < pointerStart && pointerEnd < selectionEnd )
) {
if ( hitLines.length === 0 ) replacingRangeLoc = pointerStart;
hitLines.push( lineString );
};
pointerStart = pointerEnd + 1; // 1 means a line break.
};

選択範囲があった場合にも対応できるように選択範囲と行の文字数で色々分岐が行われており、最終的にすべての場合において空行を抜いてhitLinesが各行の文章を表すようになっています。

多分このソースは他でも応用できるように用意されているものなんだと思います。

Clearの方では3行目var selectionEnd = selectionStart + T.range.len;の後に次の文が入っています。

if ( T.range.len < 1 ) {
selectionStart = 0;
selectionEnd = text.length;
};

 

これは選択範囲がなかった場合にテキスト全体を選択することを示すソースで、Bulletの方には無いために選択範囲がないとT.textで指定されているにもかかわらずカーソル行の行にのみ指定文字が挿入されるというT.currentのような挙動をします。

Clearと同じ場所に上記のソースを入れてあげることとテキスト内のすべての行の頭に挿入文字が挿入されます。

あとは空行以外の行にprefixで指定した文字列を挿入して(数字の方はcounterで1ずつ数字が上がるようにして)T(‘replaceRange’)による置き換えが行われています。

Indent

Indentは段落の最初に空白を入れたり、タブを入れたりするアクションです。Bulletの応用版と考えてよいかと思います。

2 or 4スペースの挿入はBulletの最初のvar prefixにスペースそのものを、タブ挿入は正規表現でタブを示す\tが代入されています。

その後は基本同じなんですが2点違う点があります。

まずBulletの方は間に空行があるとエラーが出るようになっています。その記載が次のものです。

for ( var j = 0, m = hitLines.length; j < m; j++ ) {
var hitLine = hitLines[ j ];
if ( hitLine.match( /\S/ ) ) { // Ignore blank line
hitLines[ j ] = prefix + hitLine;
};
};
var insertingText = hitLines.join( ‘\n’ );

 

この空行を省いてprefixを追加する記述があるのに対してIndentは正規表現を用いて

var re = new RegExp( '(^.*$)', 'gm' ); 
var insertingText = 
replacingText.replace( re, prefix + '$1' ); // Add prefix.

 

となっています。またIndentはreplacingRangeでの選択範囲を置き換えた範囲全体としているため、Indentのアクション終了後に処理された文字列が選択されます。

その部分が下です。

Bullet

T( ‘replaceRange’, {
text: insertingText,
replacingRange: { loc: replacingRangeLoc, len: replacingRangeLen },
selectingRange: { loc: replacingRangeLoc + insertingText.length, len: 0 }
} );

 

Indent

T( ‘replaceRange’, {
text: insertingText,
replacingRange: { loc: replacingRangeLoc, len: replacingRangeLen },
selectingRange: { loc: replacingRangeLoc, len: insertingText.length }
} );

 

赤字の部分でBulletの方は選択範囲が0でカーソル位置を処理した文章の最後に指定しているのに対してIndentの方は処理した文章の最初から挿入したテキストの長さ分だけ選択するよう指定しているのがわかると思います。

Insert

カーソル位置に文字列を挿入するInsertです。

まず一番簡単なInsert”Hello”は

T( ‘insert’, {
text: ‘Hello’
} );

もちろんHelloのところを別の言葉にすることで違う文字列を挿入することが可能です。

次に選択範囲を()で囲ってしまうInsert”(“and”)”は

var prefix = ‘(‘;
var suffix = ‘)’;
T( ‘replaceRange’, {
replacingRange: T.range,
text: prefix + T.selectedText + suffix,
selectingRange: {
loc: T.range.loc + prefix.length,
len: T.range.len
}
} );

T(‘replaceRange’)による置き換えです。これは()をそれぞれprefixとsuffixという変数で置き換えて行っています。

次に置き換えないで直接挿入してしまう例としてInsert”<>”and”</>があります。

T( ‘replaceRange’, {
replacingRange: T.range,
text: ‘<>’ + T.selectedText + ‘</>’,
selectingRange: {
loc: T.range.loc + 2,
len: T.range.len
}
} );

基本は同じで変数に置き換えないで直接記入しています。

この<>と</>に文字を入れて選択した文字列をタグで囲むことができるんですが、気をつけないといけないのがselectingRangeのlocがT.range.loc+2になっていることです。

ちゃんと<>で囲んだ文字列の文字数に変えないと<から数えて2文字目から選択した文字列の文字数分だけアクション終了後に選択してしまいます。

まとめ

この辺りのアクションは単体でも少し改造してもとても便利なものなのですが、Clearの複数タスクの登録の際に似たようなソースが出てきたように他のアクションにつなげる元になるものなのだと思います。

とは言いつつ、アクションを解析してみることで今はいっぱいいっぱいなので新しいアクションを作るとかなかなかできてないのですが。

結構解析していると新しい発見があっておもしろいです。このアクション集自体、ユーザーが新しいアクションを作るための参考になるように作られているんだなあと今更ながらわかりました。

 - iPhoneアプリ ,

   

スポンサードリンク

スポンサードリンク

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事