vimscript 覺へ書き

visualモードで選択した文字列を 函數の引數として渡す方法

操画で使ふシナリオ といふか テキストを書く際に ルビ振りを 「:」のキャラクターを使って指定してゐる
例へば 「操画」にルビをふる場合
操:さう:画:が:
のやうに書いて ルビの処理をしてゐる
このルビ振りを vimプラグインで 簡單にできるやうにした
autoload に入れる rubi.vim は 次のやうになった

scriptencoding utf-8
" AUTHOR: yokoP <teruyokoP@gmail.com>
" MAINTAINER: yokoP
" License: This file is placed in the public domain.

function! s:AppendRubi(moji)
  let l = strchars(a:moji)
  let rb = input(a:moji . ':')
  if rb==' '
    let rb=''
  endif
  let rblist = split(rb,' ')
  let lr = len(rblist)
  let str = ''
  let i = 0
  while l > 0
    if lr > i
      let irb = ':' . rblist[i] . ':'
    else
      let irb = ''
    endif
    let str = str . strcharpart(a:moji,i,1) . irb 
    let i = i + 1
    let l = l - 1
  endwhile
  let @" = str
  call feedkeys('P') 
endfunction 

function! rubi#RubiStart()
  echo 'rubi start'
  command! -nargs=1 Rubia call s:AppendRubi(<args>)
  nnoremap <buffer> q :Rubiq
  vnoremap <buffer> r d<Esc>:Rubia '<C-R>"'<CR> 
  augroup Rubi 
    autocmd!
  augroup END
endfunction

function! rubi#RubiEnd()
  echo 'rubi end'
  augroup Rubi 
    autocmd!
  augroup END
endfunction

ここで

function! rubi#RubiStart()
  echo 'rubi start'
  command! -nargs=1 Rubia call s:AppendRubi(<args>)
  nnoremap <buffer> q :Rubiq
  vnoremap <buffer> r d<Esc>:Rubia '<C-R>"'<CR> 
  augroup Rubi 
    autocmd!
  augroup END
endfunction

の部分は とても面白いと思ふ

vnoremap <buffer> r d<Esc>:Rubia '<C-R>"'<CR> 

は r キーを ビジュアルモードのときにマッピングしてゐるのだが
まづ 選択した部分を消去する (d)
このとき 消去されら文字列は 無名レジスタに格納される
ノーマルモードに戻り (<Esc>)
コマンドをタイプする (:Rubia)
この Rubia コマンド は 引數をひとつ持つやうに設定してをり
その引數にあたる部分が ' <C-R>" ' である
これは 無名レジスタの値をクオートでくくって 文字列として Rubia に渡す役割をしてゐる
最後に <CR> で Enter入力され コマンドが實行される
これによて ビジュアルモードで選択した文字列が 函數の引數として渡せてゐるのだ
これは 様々な場面に應用可能で 有用な手順だと思ふ

Rubia コマンドの定義部分は 次のやうになってゐる

command! -nargs=1 Rubia call s:AppendRubi(<args>)

-nargs で 引數の數(この場合は1)を指定してゐる
これにより Rubia コマンドは 引數をひとつとって s:AppendRubi函數に その引數を渡すことが實現してゐる

vim で 縦書き

これの基礎部分を實現したのは 今年の2月13日だった
それから バグを直していき
最近また バグが見つかったので 手直しをした
Githubに そのプラグインを載せてゐる

github.com

これに至る道程 といふか 経緯のやうなものを 電子書籍化しやうと思ってゐる
この tatevim も さらに機能を追加して
シナリオエディタのやうに使へ
編集しながら ノベルゲームのやうなことができたりすれば 面白いと思ふ

Haskell と SDL #2

完全に忘れてゐたが 二年前に

syouzanponkikki.hatenablog.com

の記事のコメントで SDLのインストールに成功したことを書いてゐた

ただ 今回は實際に サンプルコードを参考にして
画面の表示だけでなく 點や線の描画 画像の貼り付け さらには フォントの表示を實現できた

フォントに關しては 殘念ながら Windowsでは成功してゐない
しかし Debianにおいては sdl2-ttf が正常に機能し フォント表示ができた

いつも Haskellで樂しませられるのは
ふたつの 矛盾したやうな事象が 常に同時平行してゐるやうに見えることだ

その ひとつの事象の例を擧げると

  • Haste といふコンパイラ (Haskell コード から javascript を生成するもの) が存在するが 對應してゐる Haskell のバージョンは古く 現在全くメンテナンスやアップグレードは爲されてゐない

  • FreeGame といふ Haskellのパッケージが 木下さん といふ方によって創られたが 5年前を最後に更新は止まったままである

  • 今回の記事で触れた SDL や GHCJS といった グラフィック關係 Web關聯の Haskellパッケージが存在するが 初心者は インストールもままならない

そして まうひとつの事象の例は

  • 新しい暗号通貨としてつくられた Ada のブロックチェーンである Cardano は 基本的に Haskell で書かれてゐる
  • 有名なFacebook (現在はメタ?)のコードは Haskellを土台にしてゐるといふ
  • Steamにも名を連ねてゐるゲームが Haskellで書かれてゐる
  • その他多くの金融系企業で Haskellが積極的に使はれてゐるといふ
  • Haskell自體の更新は 精力的に現在でも爲されてゐる

つまり 私が言ひたいことは
Haskellにおいて その需要が一定數 確實にあるにもかかはらず
その環境構築や チュートリアルといった 初心者を取り込み ユーザーを増やすべき部分が
絶望的に難解かつ 情報に欠ける といふことだ
Haskell Platform や Stack などのツールは そりゃまう 簡單にダウンロードして インストールできる
しかし いざ ゲームをつくらう!
ウェブサイトをつくらう!
などといったとき 突然 ユーザーには 大きな壁が立ちはだかる
全く おもしろすぎて 笑ってしまふ 意味不明さなのだ

しかし 確實に この事は 私にとって Haskellの魅力のひとつである といへる
python みたいに How To本も あふれる程にあって
ほら! こんな簡單に ゲームできちゃうよ!
ほら! こんな簡單に Webアプリができちゃうよ!
とかいふより どれだけ謎めいていて 深みがあって 魅力のある言語だらうか!!

Haskell で SDL

tar -zxvf SDL2-*
  • 解凍してできたフォルダに移動
  • 次のコマンドを實行する
./configure && make -j4 && sudo make install
stack new myproject

などとする(ここで myproject は仮の名前であるーー實際は 好きな名前にする)

cd myproject
  • package.yaml といふファイルがある筈だ
    これを編集する
  • dependencies: といふところに - sdl2 を加える
dependencies:
- base >= 4.7 && < 5
- sdl2
  • イメージの讀み込みを實驗するため mkdir images などとして
    イメージファイル用のディレクトリを作る
  • その中に何らかのビットマップファイル(拡張子が .bmpのもの)を入れる
    私の場合は kagunomi.bmp といふものを入れた
  • app といふディレクトリがある筈だ
    そこにある Main.hs を編集する
vi app/Main.hs

上の例は エディタとしてvimを使った場合だが
編集できれば何でもよい

{-# LANGUAGE OverloadedStrings #-}
module Main where

--import Lib
import SDL
import Control.Monad (unless)

main :: IO ()
main = do
  initializeAll
  let myWindow = defaultWindow {windowInitialSize =  V2 480 600}
  window <- createWindow "FuncPong" myWindow
  image <- loadBMP "./images/kagunomi.bmp"
  renderer <- createRenderer window (-1) defaultRenderer
  texture <- createTextureFromSurface renderer image
  appLoop renderer texture 
  destroyWindow window

appLoop :: Renderer -> Texture -> IO ()
appLoop renderer texture = do
  events <- pollEvents
  let eventIsQPress event =
        case eventPayload event of
          KeyboardEvent keyboardEvent ->
            keyboardEventKeyMotion keyboardEvent == Pressed &&
            keysymKeycode (keyboardEventKeysym keyboardEvent) == KeycodeQ
          _ -> False
      qPressed = any eventIsQPress events
  rendererDrawColor renderer $= V4 182 100 255 255
  clear renderer
  rendererDrawColor renderer $= V4 0 0 0 255
  drawPoint renderer (P (V2 100 100))
  drawLine renderer (P (V2 50 50)) (P (V2 80 80))
  rendererDrawColor renderer $= V4 100 100 100 255
  fillRect renderer (Just (Rectangle (P (V2 200 200)) (V2 100 100)))
  copy renderer texture Nothing (Just (Rectangle (P (V2 30 300)) (V2 100 100))) 
  present renderer
  unless qPressed (appLoop renderer texture)
  • 自分が myproject ディレクトリ(好きな名前のディレクトリ)のすぐ下に居ることを確認する
  • そこで stack build を實行する
  • めでたく エラーが出なければ
stack exec myproject-exe

などとして實行する(myproject の部分は 最初に stack new の後に入力した名前だ)

といふ感じで 取り急ぎ 私が實行した手順をまとめてみた
色々言ひたいこともあるが それは順次 書き足していかうと思ふ

やっと再歸

今日やっと 「は」で再歸函數の動作が實現した
具体的には
0 sai = 5
a sai = 3 (a -1) sai
などとして評価し
4 sai
で評価すると
結果 17 を得る
三日前からの課題(問題)は 2點あった

ひとつは 評価する際に 函數名の文字が 置換されてしまふこと
sai が s4i などとなってしまった

もうひとつは
a sai = (a -1) sai 3
とすると動作するが
a sai = 3 (a -1) sai
とすると 動作が固まってしまふこと

昨日までには ひとつめの問題は解決してゐたが
二番目の問題は 難題だった

ただ 結果的に コード中のダッシュをひとつ取るだけで解決した

「は」の中心部分 計算の実装部分が 肥大化し過ぎて
複雑で 手におへなくなってきた

新たに 計算部分だけを最初から設計し直す作業も平行して行ってゐる
とにかく やり續け 吟味し續けること

最近は Haskellに触れない日はなくなってゐる
きっと成果が出てくるだらう

何よりも 樂しい
だから續けられてゐるのだと思ふ

javascript で サーバー上のテキストファイルを讀みこむ

この あたり前のやうに使ひ 簡單さうなことが
なかなか すんなりと出來ず
説明してある サイトも少ない

結局今まで 次のやうなコードで對應してきた

var readFromFile = function(fileURL){
  var text = null;
  var raw = new XMLHttpRequest();
  raw.open("GET",filename,false);
  raw.onreadystatechange = function(){
    if(raw.readyState === 4){
      if(raw.status === 200 || raw.status == 0){
        text = raw.responseText;
      }
    }
  }
  raw.send(null);
  return text;
}

しかし なんと これが次のやうにしても動くことが確認できた

var readFromFile = function(fileURL){
  var raw = new XMLHttpRequest();
  raw.open("GET",filename,false);
  raw.send(null);
  return raw.responseText;
}

今の私は 次のやうに書いてゐる

const readFromFile = (fileURL) => {
  const raw = new XMLHttpRequest();
  raw.open("GET",filename,false);
  raw.send(null);
  return raw.responseText;
}

ただし ブラウザがバージョンアップされてからは
クロスオリジンがどうのこうのとかで ローカルな環境上ではファイルをうまく讀みこめない
それも出來れば解決したいが
最近では monaca上ですぐエミュレートしてしまふので
htmlファイルをローカルでそのまま試すことをしなくても
何とかなってしまってゐる

「は」制作 覺へ書き2

今回の更新は つまづきの連續だつた
式の評価方法を 根本から見直し パターンマッチと再歸を實現するのが目標だつた
正直なところ 自分の書いたコードの細部まで 自信をもつて 挙動を予想できるやうに なつてゐない
とりあへず 何とか 動いた といふのが 實感である
もちろん そこは これからコードを吟味しつつ
バグを直し 簡潔にできるところは まとめ
より汎用性の高いものを目指すつもりだ
少なくとも 次のやうな パターンマッチ ・ 再歸を實現することができた
Haskell風に書くと

something 0 = 0
something x = (something (x-1)) + 3

この函數somethingに引數4を適用して評価すると
something 4 は 12 となる
「は」の表記法で ひらがなを使ひ 同じことを書くと 次のやうになる

これは ろ か ろ に あ か あきひ み た

函數「これ」に引數「よ」を適用し評価すると
「は よ これ た」は 「ひふ」となる

www.nicovideo.jp

やったことを 簡潔に箇条書きにすると

  • 今までは 入力された文字列を 二度整形し (函數の部分を書き換へるなどして) 三度目に整形された文字列リストを評価してゐた
  • 今回 文字列の評価は 一度とし 必ず 前から後ろへ 一要素ずつ 評価しながら 整形するやうにした
  • 状態として登録される函數は 引數の組と それを用ひた式をペアにして それを複數もてるやうにし パターンマッチに對應した

おそらく Data.List モジュールを使へばすぐ實現できるやうなことも 自前で函數をつくり 實現した

理由は ただ さうしたかつたからである

特に 予想外に苦勞したのは 次の函數である

sepWith :: String -> String -> String
sepWith wd str 
  | length str >= length wd =if (take (length wd) str)==wd
                                then " x "++(sepWith wd (drop (length wd) str)) 
                                else [(head str)]++(sepWith wd (tail str))
  | otherwise = str

これは 文字列を 文字列で分割し 分割する文字列を" x "で置きかへる函數である
例へば
sepWith "あか" "しろあかあお"
とすると
"しろ x あお"
が返される
これができると あとから 「x」の部分を別のものに置きかへることができ
函數の引數を 連続した文字列の中で変換させることができるやうになる
實例でいふと 先程の「は」式中の 「あきひ」の部分でこれが適用されてゐる
具體的には「あきひ」の「あ」は函數の引數なので それを除いた 「きひ」の部分が
"ratio"の型をもつと判断された場合 「あ」の部分が 與へられた數(例の場合は「よ」)に置き換へられ
結果として「よきひ」の形になつて 「み」を得る といふやうに 使はれてゐる

github.com