Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
lempiji committed May 4, 2021
0 parents commit 2cc75ef
Show file tree
Hide file tree
Showing 6 changed files with 602 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.dub
docs.json
__dummy.html
docs/
/md
md.so
md.dylib
md.dll
md.a
md.lib
md-test-*
*.exe
*.o
*.obj
*.lst
178 changes: 178 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# md

Markdownのコードブロックを実行するツールです。

READMEに書かれたサンプルが動作するかどうかをCIなどで確かめることができます。

## 実行方法

`dub run md -- README.md` といった形式で実行できます。

この `README.md` も実行可能です。


## 機能概要

言語が `d` と指定されているコードブロックが実行されます。

以下のように複数のブロックがある場合、それらが結合されて実行されます。

__1ブロック目__

```d
import std;
auto message = "Hello, " ~ "Markdown!";
```

__2ブロック目__

```d
writeln(message); // Hello, Markdown!
```

### 除外設定

以下のように `disabled` と指定したコードブロックは実行されません。

~~~
```d disabled
```
~~~

__実行されないブロック__

```d disabled
throw new Exception("disabled");
```

### 名前指定

コードブロックに対して、以下のような名前を指定することで独立したスコープを与えることができます。
離れた位置に書かれていても、同じ名前を与えると1つのブロックとして結合されます。

~~~
```d name=test
```
~~~

```d name=test
import std;
auto buf = iota(10).array();
writeln(buf);
```

`name` 指定がない場合は `main` という名前として扱われます。

### 独立実行

1つのコードブロックを他のブロックと結合せず、独立して実行させるためには `single` という属性を付与します。

~~~
```d single
```
~~~

__他のブロックと結合しない例__

```d single
import std;
auto message = "single code block";
writeln(message);
```

### 既定のパッケージ参照

ライブラリのREADMEなどをサポートするため、実行時のカレントディレクトリがdubパッケージであった場合、自動的に `dub` プロジェクトとしての依存関係が追加されます。

たとえば、 `dub.sdl` と同じディレクトリにある本READMEの場合、内部で使っている `commands.main``import` することができます。

```d name=package_ref
import commands.main;
import std.stdio;
writeln("current package: ", loadCurrentProjectName());
```

### グローバル宣言

通常のコードブロックはサンプル用の記述を想定し、 `void main() {}` の中に書かれたものとして実行されます。(前後に `void main() {``}` が補われたソースが生成されます)

コードブロックを1つのソースファイルとして解釈させる場合、コードブロックに `global` という設定を追加します。これは `single` を指定した場合と同様、他のコードブロックとは結合されません。

~~~
```d global
```
~~~

__1つのソースとして実行される例__

```d global
import std;
void main()
{
writeln("Hello, Markdown!");
}
```


## その他

### 実行時の仕組み

tempディレクトリに `.md` ディレクトリを作り、dubのシングルファイル形式のソースを生成、 `dub run --single md_xxx.md` といったコマンドで実行します。

### 制限

#### UFCS

通常のコードブロックでは、 `void main() {}` で囲んだソースを生成します。
関数定義がグローバル関数ではないため、UFCSは動作しません

__UFCSが解決されず動かない例__

```d name=ufcs_error
auto sum(R)(R range)
{
import std.range : ElementType;
alias E = ElementType!R;
auto result = E(0);
foreach (x; range)
{
result += x;
}
return result;
}
auto arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
auto result = arr.sum();
```

global設定を行い、main関数を適切に書くことで動作します。

__UFCSのためglobal指定を追加した例__

```d global
auto sum(R)(R range)
{
import std.range : ElementType;
alias E = ElementType!R;
auto result = E(0);
foreach (x; range)
{
result += x;
}
return result;
}
void main()
{
auto arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
auto result = arr.sum();
}
```
6 changes: 6 additions & 0 deletions dub.sdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name "md"
description "A tool for executing sources in Markdown."
authors "lempiji"
license "MIT"
dependency "jcli" version="~>0.12.0"
dependency "commonmark-d" version="~>1.0.8"
9 changes: 9 additions & 0 deletions dub.selections.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"fileVersion": 1,
"versions": {
"commonmark-d": "1.0.8",
"jcli": "0.12.0",
"jioc": "0.2.0",
"silly": "1.0.2"
}
}
10 changes: 10 additions & 0 deletions source/app.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module app;

import commands.main;
import jcli;

int main(string[] args)
{
auto executor = new CommandLineInterface!(commands.main);
return executor.parseAndExecute(args);
}
Loading

0 comments on commit 2cc75ef

Please sign in to comment.