Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
KoharaKazuya committed Jul 23, 2017
2 parents d9b8ca3 + e2fc417 commit d23b200
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ matrix:
- os: linux
rust: stable
env: TARGET=x86_64-unknown-linux-gnu
- os: linux
rust: stable
env: TARGET=x86_64-unknown-linux-musl

script:
- cargo test --verbose
Expand Down
110 changes: 110 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,111 @@
# forest

[![Build Status](https://travis-ci.org/KoharaKazuya/forest.svg?branch=master)](https://travis-ci.org/KoharaKazuya/forest)

forest は行指向で構造化された木構造を表すテキストを整形して出力するコマンド。


##

(sample1.txt)

```
pattern1_root
pattern1_root/pattern2_last_leaf
root_node
root_node/pattern3_non-last_leaf
root_node/pattern3_non-last_leaf/sample
root_node/pattern3_non-last_leaf/pattern4_non-last_node's_child
root_node/leaf_node
```

```console
$ cat sample1.txt | forest
├ ─ pattern1_root
│   └ ─ /pattern2_last_leaf
└ ─ root_node
    ├ ─ /pattern3_non-last_leaf
    │   ├ ─ /sample
    │   └ ─ /pattern4_non-last_node's_child
    └ ─ /leaf_node
```

(sample2.txt)

```
サン
サンプル
forest
forest doesn't specify any characters
forest doesn't specify any characters as separater.
```

```console
$ cat sample2.txt | forest
├ ─ サ
│   └ ─ ン
│       └ ─ プル
└ ─ forest
    └ ─  doesn't specify any characters
        └ ─  as separator.
```


## ダウンロード

<https://github.com/KoharaKazuya/forest/releases>


## forest がなぜ必要か

考えられる用途としては tree コマンドや ps --forest オプションで十分だが、単機能として分離しておくと柔軟に組み合わせられるため。

find コマンドの柔軟な検索結果を forest で整形表示するなど。


## アルゴリズム

アルゴリズムを擬似コードで示す。

```
入力: テキスト input
出力: テキスト output
entries ← 空キュー
// 木構造構築フェーズ
ancestors ← 空スタック
prev ← null
while line ← input の先頭行
while ancestor ← ancestors.pop()
if line が ancestor.value から始まる
ancestors.push(ancestor)
break
if prev != null
prev.shape ← CLOSE
prev ← ancestor
entry ← (depth: ancestors の長さ + 1, shape: Pending, value: line)
if prev != null
prev.shape ← OPEN
ancestors.push(entry)
entries.enqueue(entry)
while ancestor ← ancestors.pop()
ancestor.shape ← CLOSE
// 木構造出力フェーズ
ancestor_shapes ← 空リスト
while entry ← entries.dequeue()
ancestor_shapes ← ancestor_shapes の先頭 (entry.depth - 1) 要素
shape for each ancestor_shapes
if shape = OPEN
ANCESTOR_GUIDE_OPEN を output 出力
else if shape = CLOSE
ANCESTOR_GUIDE_CLOSE を output 出力
if entry.shape = OPEN
NAME_GUIDE_OPEN を output に出力
else if entry.shape = CLOSE
NAME_GUIDE_CLOSE を output に出力
entry.value を output 出力
ancestor_shapes の末尾に entry.shape を追加
```

0 comments on commit d23b200

Please sign in to comment.