🐑

プロジェクトと一体でコンテンツを提供するCLIツールを作った2

2022/02/26に公開

前回から機能拡張しました。

新規機能

  • 新規記事作成
  • 多言語サポート
  • Playground URL 追加(Rust のみ)
  • コードブロック演算

使い方

$ cargo build

target/debug/cai.exezenn-content直下に配置します。

$ cai init [option] <title> <topics>

[option]-pを指定すると、projects直下にファイル名と同じ名前のフォルダが作成されます。

$ cai init -p これはタイトル トピック1 トピック2

例えば上記のコマンドを実行すると、articles/<uuid>.txtprojects/<uuid>が作成されます。

├─images
├─books
├─articles
│  └─<uuid>.txt
└─projects
   └─<uuid>
<uuid>.txt
---
title: これはタイトル
emoji: 🐒
type: tech
topics: [トピック1, トピック2]
published: false
---

オプション(-p)を無くすと、articles/<uuid>.txtだけ作成されます。
.txtファイルである理由は記事として認識されないようにするためです。

プロジェクトがある場合もない場合も以下のコマンドを実行すると<uuid>.mdファイルが作成されます。ファイル名のコピーが面倒ですが...

$ cai <path>
├─images
├─books
├─articles
│  ├─<uuid>.txt
│  └─<uuid>.md
└─projects
   └─<uuid>
<uuid>.md
---
title: これはタイトル
emoji: 🐒
type: tech
topics: [トピック1, トピック2]
published: false
---

記事を新規に作成するコマンドはinitだけ、titleだけで実行することも可能です。

$ cai init これはタイトル

対応言語

  • Python
  • Julia
  • Rust
  • C
  • C++(cpp)
  • C#(cs)
  • Java
  • Javascript
  • TypeScript
  • Go
  • Swift
  • PHP
  • Scala
  • Haskell
  • Lua

()の中はスニペットの言語指定で、全部小文字で指定します。

```cpp:main.cpp
#include <iostream>

using namespace std;

int main(){
  cout << "Hello world." << endl;
  return 0;
}
```

「Rust で Hello, world!」という記事を書く場合をベースにしてみます。

$ cai init -p "RustでHello, world!" Rust

上記のコマンドを実行したときのフォルダ構成は以下のようになっています。

├─images
├─books
├─articles
│  └─<uuid>.txt
└─projects
   └─<uuid>

projects/<uuid>に移動して以下を実行します。

$ cd projects/<uuid>
$ cargo init --name project

ここまでのフォルダ構成 ↓

├─images
├─books
├─articles
│  └─<uuid>.txt
└─projects
   └─<uuid>
      ├─src
      │  └─main.rs
      └─Cargo.toml

main.rsにコメントを追記します。

src/main.rs
// 1
fn main() {
    println!("Hello, world!");
}
// -1

articles/<uuid>.txtmain.rsで表示させたいコードの範囲の番号を書いたコードスニペットを追記します。

articles/<uuid>.txt
---
title: RustでHello, world!
emoji: 🐒
type: tech
topics: [Rust]
published: false
---

```rust:src/main.rs
1
```

以下のコマンドを実行します。

$ cai <uuid>

そうするとarticles/<uuid>.mdが作成され、以下のような内容になっています。

<uuid>.md
---
title: RustでHello, world!
emoji: 🐒
type: tech
topics: [Rust]
published: false
---

```rust:src/main.rs
fn main() {
    println!("Hello, world!");
}
```

これでpublished: trueにすれば Github に Push して記事をデプロイできます。

Playground URL を追記する

Rust 限定ですが、Playground の URL を追記できます。

<uuid>.txt
```rust:src/main.rs:サンプルコード
1
```

上記のように<言語>:<パス>:<リンク用文字列>とすることで、そのコードブロック内のプログラムの Playground URL を追記できます。

<uuid>.md
[サンプルコード](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn%20main%28%29%20%7B%0A%20%20%20%20println%21%28%22Hello%2C%20world%21%22%29%3B%0A%7D)

```rust:src/main.rs:サンプルコード
fn main() {
    println!("Hello, world!");
}
```

コードブロック同士を足す

ファイルの特定のコメントアウトの範囲同士を結合することができます。

src/main.rs

src/main.rs
// 1
fn main() {
   hello();
}
// -1

src/hello.rs

// 1
fn hello() {
   println!("Hello, world!");
}
// -1

上記 2 つのファイルのコメントアウトの範囲を結合する場合は以下のように記述します。

*.txt

```rust```src/main.rs:1 + src/hello.rs:1

コード同士は、記述された順番に上から結合されていきます。

*.md

```rust
fn main() {
   hello();
}
fn hello() {
   println!("Hello, world!");
}
```

https://github.com/ogty/article-continuous-integration

Discussion