開発者は、ツリー構造のファイル(XML、JSON、YAML、MarkdownやOrg-modeなどのあらゆる種類のマークアップ言語)を処理する必要があります。 全般的に私たちの生活を促進するこのようなファイルは、制御不能な成長の傾向があり、ある時点でソリューションから問題に変わります。
この問題の標準的な解決策は、小さなファイルに分割することです。 これはもちろん機能しますが、必ずしも便利ではありません。
しかし、それについての代替案があります-以下。
org-modeとそのマークアップ。
おそらく最初に私の問題の概要を説明する価値があります。 私はEmaxを使用し、Emaxの多くのユーザーと同様に、 org-modeマークアップ言語を使用して、ほぼすべてのドキュメント、メモ、作業日記、およびタスクリストを記述します。 このマークアップのドキュメントは次のようになります。
... ... > cat tests/simple.org document section * headline 1 headline section 1 ** inner headline 1 some inner section 1 some inner section 1-2 ** inner headline 2 inner section 2 ** inner headline 3 *** inner inner headline 1 * headline 2 section text 2
私のドキュメントの1つは、さまざまな入れ子の深さの数百の小見出しに成長しました。さまざまな情報を探して、これらすべての見出しのスクリプトを定期的に見て回っています。 ドキュメントをいくつかのファイルに解析したくなかったのは、 マシン間または任意のスクリプト間の同期は、単一のファイルを処理する方が簡単です。 しかし、そのように生きることは決定的に不可能でした。
そして、たとえば、標準のUnix cd headline1
またはcd ..
、 ls -l
およびcat section
を使用して、ディレクトリとしてファイルを通過するのがいいと思いました。
つまり、ヘッダーとテキストセクションのツリーを、ディレクトリとファイルの通常のツリーとして表示できるようにしたかったのです。 同じUnixに関しては、この欲求は次のように聞こえます。ある種の特殊なファイルシステムをマウントします。
もちろん、Linux向けの本格的なファイルシステムを作成することは長く、感謝のない作業であり、そのようなまれなケースでは確かに価値がありません。
ヒューズ
ただし、最近では誰もこれを行っていません。つまり、約10年前にLinux がFUSEモジュールを導入したため、ファイルシステムを通常のユーザープロセスとして作成でき、マウントされたファイルシステムに接続されているすべてのファイルがカーネル/システムコール。
FUSEの助けを借りて、たとえばWikipediaの記事をマウントするおもちゃのFSから、同じGnomeのような現代のLinuxの非常に深刻な部分まで、さまざまなファイルシステムが作成されました。 したがって、FUSEは人気のあるディストリビューションの不可欠な要素になりました。
FUSEでの作業をさらに楽しいものにしているのは、最近ではPython、Ruby、Java、その他多くの高レベル言語で絶対に些細なラッパーが利用できるという事実です。 わずか2〜3時間で独自のファイルシステムを作成できます。
フュージー
具体的には、Pythonにはlibfuse
(FUSEクライアント側)の周りにいくつかのラッパーもありますが、何よりも私はfusepyプロジェクトが好きでした:Githubの例とソースコードを除いて、プロジェクトコードは非常にシンプルで理解しやすいため、何も必要ありませんでした。
fusepy
ベースのファイルシステムは、 fuse.Operations
クラスのメソッドのオーバーライドにfuse.Operations
、各メソッドはシステムコールに対応しています。
未定義のシステムコールの場合、妥当なデフォルトの動作または標準エラーがあります。
Orgfuse
実際、ディレクトリとファイルのツリーとして表示したい特定のファイル形式はそれほど重要ではありません。 org-mode
マークアップの場合、Pythonで使用可能なパーサーはどれも好きではなく、自分でを作成しました 。 パーサーは指定されたファイルを通過し、ドキュメントの構造を反映するツリーを作成します。
マークアップファイルの解析ツリーは、ファイルシステムのユーザーに表示されるファイルとディレクトリを反映して、さらに別のツリーに変換されます。
最後のツリーで作業するには、4つのシステムコール( open
、 read
、 readdir
、 getattr
)を実装するだけで十分でした。各システムコールは、Python で文字通り数行のコードを取りました。
class FuseOperations(Operations): def __init__(self, tree): self.tree = tree self.fd = 0 def open(self, path, flags): self.fd += 1 return self.fd def read(self, path, size, offset, fh): node = self.tree.find_path(path) if node is None: raise FuseOSError(EIO) return node.content[offset:offset + size] def readdir(self, path, fh): node = self.tree.find_path(path) if node is None: raise FuseOSError(EROFS) return ['.', '..'] + [child for child in node.children] def getattr(self, path, fh=None): node = self.tree.find_path(path) if node is None: raise FuseOSError(ENOENT) return node.get_attrs()
結果のスクリプトは次のように機能します。
... ... > mkdir mount > python orgfuse.py tests/simple.org mount/ ... ... > tree mount mount/ ├── headline 1 │ ├── inner headline 1 │ │ └── section │ ├── inner headline 2 │ │ └── section │ ├── inner headline 3 │ │ └── inner inner headline 1 │ └── section ├── headline 2 │ └── section └── section 6 directories, 5 files
このすべての奇跡には、約200行、つまり私の怠zyな夜の仕事の3〜4時間かかります。それは私の小さな仕事で素晴らしい仕事をします。
通常のインストール手順とコードは、 Githubにあります。
プロトタイプを消化しやすいものに変換することに興味があり、ファイルを編集し、より多くのフォーマットをサポートできる場合は、喜んでお話しします。