bar_1

contents_map

ラベル 変換 の投稿を表示しています。 すべての投稿を表示
ラベル 変換 の投稿を表示しています。 すべての投稿を表示

2014年3月14日金曜日

PukiWiki からのデータ移行のシンプルな方法

PukiWiki から Markdown への変換


昨年 (2013年)、XP で運用していたマシンが壊れまして。それ以降、XP上のローカルサーバで長年運用してきた PukiWiki から、他のシステムにリプレイスすることを考えてました。

Wiki 以外の方法もなにかないかと、他の方法の模索をしてきたのだけど、やっぱり、Wiki はいいなと思います。

また一方で、ここ最近は Markdown も便利だと感じてました。Markdown そのものは、Wiki (CMS) ではなく、単なるドキュメントの書式でしかないのだけれども、最近は、JavaScript で書かれた Markdown レンダラーがある。こいつを使えば、Markdown でローカル Wiki みたいなことはできるんじゃないか・・ということを考えた。

で、とりあえず PukiWiki のデータを、なんとか他のシステムに移しやすい形にしたいなと。見てみたところ、


  • PukiWiki のデータはテキストファイル (xxxx.txt) で、ひとつのディレクトリにフラットに格納される (pukiwiki/wiki/)

  • ファイル名は、EUC コード (16進数) をそのまま文字列にしたもの。スラッシュなんかの記号を含んだものになる。

  • ファイルの中身は、EUC-JP で、PukiWiki形式で記述されている。(これは、設定にもよるのかも)

ということがわかった。

PukiWiki のデータを OSX 上の HFS+ に展開する


変換するに手っ取り早い方法は、テキストファイルで表現されているデータ構造とデータを、ファイルシステム上に展開してしまう、というものです。

今使っているのは Mac なので、以下のことを考えました:


  • 元のファイル名は見にくいので、デコードして、UTF-8形式で通常の文字列として表す

    • HFS+で使用できない特殊な記号が使用されていた場合は、必要に応じてなんらかのエスケープ処理をする

    • ただし、半角スラッシュの場合は、ディレクトリを掘る (HFS+ の仕様と上記仕様からくる制限)

  • ファイルの内容は、EUC-JP から UTF-8 に、漢字コードを変換する

  • PukiWiki 記法から、Markdown か MediaWiki の形式にする

  • 検索システムは、grep か mdfind を使えばいい

ということを、考えました。

ディレクトリを掘るのは、やっぱフラットに数千ファイルあると、みるのが辛いからです。。。

スクリプト


既存のスクリプトがないか、けっこう探してみたのですが、どうも見当たらない……ぜったい誰か作ってるはずなのに……。まぁ、PukiWiki 自体がもう10年近くリリース止まってますしね。

仕方ない。ということで、Ruby で以下のようなものを作りました:


  • pw2hfs.rb (変換スクリプト本体)

  • nf-pw2md.rb (PukiWiki形式→Markdown形式変換フィルタ)

はじめは MediaWiki 形式にしようかと思いましたが、めんどくさいのでやめました。PukiWiki->Markdown変換は、適当です (一行一行の正規表現マッチングと置換)。あと、スクリプト内で、OSX に入っている iconv コマンドを使ってます。

使い方は、2つのスクリプトを、pukiwiki のデータの格納してあるディレクトリの一つ上において、結果出力用のディレクトリ dst/ を作ってから、pw2hfs.rb を実行します。しばらく待つと、dst/ 以下に、変換したものができます。

この結果と、Invisible.js かなにかを、組み合わせようと思ってます。Wiki の記法 (特に、Markdown 中での、ページ名のリンク ―スクウェア・ブラケットで2重に囲むアレ) 対応は、JavaScript 側でやったほうがいいかな……。

それでは。



2011年3月22日火曜日

[Ruby]配列とハッシュ

インデックス、値、変換配列の値(要素)から、そのインデックスを得る方法を探していたのだが、当初、見つからなかった。
このため、配列を、一旦、ハッシュに変換してから、処理しようと試みた。しかし、Rubyでは、配列でもハッシュでも、要素から(インデックス|キー)を引くのは、同じ方法(indexメソッド)であることが分かったorz

以下は、配列の場合である。

irb(main):001:0> ["foo", "bar", "car", "cdr"].index("car")
=> 2
irb(main):002:0> ["foo", "bar", "car", "cdr"][2]
=> "car"

以下は、ハッシュの場合である。
irb(main):006:0> {1=>"foo", 2=>"bar", 3=>"car", 4=>"cdr"}.index("bar")
=> 2
irb(main):008:0> {1=>"foo", 2=>"bar", 3=>"car", 4=>"cdr"}[2]
=> "bar"

配列からハッシュを生成する(1)ここで、仮に配列からハッシュに変換しようとした場合、どのようにしたらよいだろうか?ここで、変換の際、配列のインデックスは、ハッシュにしたときにキーとなるものとする。
上記を考えたとき、以下のようなトピックを利用すれば、変換することができる:
  • Array http://www.ruby-lang.org/ja/man/html/Array.html
    配列クラス
    • Array#transpose
      配列の配列を行列とみなし、行と列の転置をおこなうインスタンス・メソッド
    • Array#flatten
      階層化された配列から階層を取り払い、一次(インデックスが1種類)の配列にするインスタンス・メソッド
  • Hash
    ハッシュ・クラス
    • Hash.[]
      与えられたオブジェクトで新しいハッシュを生成するクラス・メソッド
  • *[] (多重代入)
    複数の値を、それらに対応する複数の変数に、代入する仕組み

配列からハッシュを生成する(2)
(1) 変換前の配列を元に、二つの配列を用意する; ひとつは、変換前の配列のインデックスを要素とする配列 a、もうひとつは、変換前の配列のを要素とする配列 b である。すなわち:
a = [0, 1, 2, ..., n-1]
b = [e_0, e_1, e_2, ..., e_(n-1)]
n: aのサイズ=bのサイズ
e_i: 変換前の配列の各要素
(2) 配列aの要素a_iとbの要素b_iが、交互に並ぶような配列abを作成する; つまり、
ab = [a_0, b_0, a_1, b_1, ..., a_(n-1), b_(n-1)]
n: aのサイズ=bのサイズ
である。
この処理を行うためには、Array#transpose と Array#flatten を、利用する。
(3) ハッシュを生成する。このとき多重代入によって、配列abをハッシュ生成メソッドに与える。

ソース・コードは以下となる。戯れに、gist.github.comにも格納してみた
(https://gist.github.com/876272 )。
#file: to_h.rb
#conversion method from Array to Hash.
#
#
class Array
def idxarr( x )
Array.new(x) {|i| i}
end
def to_h
Hash[ *[idxarr(self.size), self].transpose.flatten ]
end
end
####endof file: to_h.rb

実行例は以下である:
irb(main):002:0> require 'to_h.rb'
=> true
irb(main):003:0> ['foo', 'bar', 'car', 'cdr'].to_h
=> {0=>"foo", 1=>"bar", 2=>"car", 3=>"cdr"}

Conclusion
- 配列でも、indexメソッドで、値からインデックスを求めることが出来る
- 配列からハッシュへの変換メソッドを実装した
Future Works
- 自分の環境で、gisty で投稿できないので、原因を解明すること
References
- Dave Thomas, et. al.; “プログラミングRuby”, 第2版, 言語編; オーム社
- Dave Thomas, et. al.; “プログラミングRuby”, 第2版, ライブラリ編; オーム社
- buzword, “配列からハッシュを作成する”, http://www.rubylife.jp/ini/hash_class/index7.html