Publishでプラグインをインストールする方法(Swift)

「PublishでWebサイトを構築する」は6部構成です。
記事を順番に読み進めると、PublishでWebサイトが構築できるようになります。

第1部: [セットアップ&使い方](https://qiita.com/uhooi/items/57e040df2f4aa7f62d89)
第2部: [カスタムテーマの作成](https://qiita.com/uhooi/items/111d4439273775586149)
第3部: プラグインのインストール　__←イマココ__
第4部: プラグインの作成（未投稿）
第5部: [ツイートボタンの表示](https://qiita.com/uhooi/items/9aa046f0a42e5afbd7c3)
第6部: [はてなブックマークボタンの表示](https://qiita.com/uhooi/items/40cb71ac3aca57853544)

## はじめに

Publishでプラグインをインストールする方法を紹介します。

本記事では例として [SplashPublishPlugin](https://github.com/JohnSundell/SplashPublishPlugin) をインストールします。
こちらはSwiftのコードをシンタックスハイライトするプラグインです。

## 環境

- OS：macOS Monterey 12.2.1
- Xcode：13.3 (13E113)
- Swift：5.6
- Publish：0.8.0
- SplashPublishPlugin：0.1.0

## パッケージの追加

まず `Package.swift` の依存関係にプラグインのパッケージを追加します。

```diff_swift:Package.swift
// swift-tools-version:5.6

import PackageDescription

let package = Package(
    name: "WebsiteSample",
    products: [
        .executable(
            name: "WebsiteSample",
            targets: ["WebsiteSample"]
        ),
    ],
    dependencies: [
        .package(url: "https://github.com/johnsundell/publish.git", from: "0.8.0"),
+       .package(url: "https://github.com/johnsundell/splashpublishplugin", from: "0.1.0"),
    ],
    targets: [
        .executableTarget(
            name: "WebsiteSample",
            dependencies: [
                .product(name: "Publish", package: "publish"),
+               .product(name: "SplashPublishPlugin", package: "splashpublishplugin"),
            ]
        ),
    ]
)
```

`Package.swift` を保存し、エラーが発生しなかったら追加に成功しています。

## プラグインのインストール

プラグインのインストールは `.installPlugin(_:)` で行います。

先ほど追加したパッケージをインポートし、 `.installPlugin()` の引数に指定します。

```diff_swift:main.swift
+ import SplashPublishPlugin

try WebsiteSample().publish(using: [
+   .installPlugin(.splash(withClassPrefix: "")),
    .addMarkdownFiles(),
    .copyResources(),
    .generateHTML(withTheme: .uhooi),
    .generateRSSFeed(including: [.posts]),
    .generateSiteMap(),
    .deploy(using: .gitHub("uhooi/website-sample-output", useSSH: false))
])
```

`SplashPublishPlugin` はMarkdownファイルが処理される前にインストールする必要があるので、 `.addMarkdownFiles()` より前に記述します。

## テーマの更新

プラグインによってはテーマを更新する必要があります。

`SplashPublishPlugin` はCSSを更新しないとシンタックスハイライトされません。
[サンプル](https://github.com/JohnSundell/Splash/blob/7f4df436eb78fe64fe2c32c58006e9949fa28ad8/Examples/sundellsColors.css) があるので、本記事ではそのまま使います。

まずサンプルのCSSを `Resources` フォルダ以下に格納します。
私は `Resources` に `SplashPublishPlugin` フォルダを作成し、サンプルの名前（ `sundellsColors.css` ）のまま格納しました。

次に追加したCSSを適用するため、テーマのSwiftファイルを更新します。
シンタックスハイライトは記事のみで使うので、 `makeItemHTML(for:context:)` が返すHTMLにCSSを適用します。

```diff_swift:Theme+Uhooi.swift
extension Theme {
    static var uhooi: Self {
        Theme(
            htmlFactory: UhooiHTMLFactory(),
            resourcePaths: [
                "Resources/UhooiTheme/styles.css",
+               "Resources/SplashPublishPlugin/sundellsColors.css",
            ]
        )
    }
}

private struct UhooiHTMLFactory<Site: Website>: HTMLFactory {
    // ...
    func makeItemHTML(for item: Item<Site>,
                      context: PublishingContext<Site>) throws -> HTML {
        HTML(
            .lang(context.site.language),
-           .head(for: item, on: context.site),
+           .head(for: item, on: context.site, stylesheetPaths: [
+               "/styles.css",
+               "/sundellsColors.css",
+           ]),
        // ...
    }
    // ...
}
```

`publish-cli run` を実行してWebサイトを確認します。

|Before|After|
|:--:|:--:|
|![スクリーンショット 2022-03-29 10.59.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/91d9fc0b-f128-f02d-d0e4-2fb04df0b38f.png)|![スクリーンショット 2022-03-31 17.57.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/f64b9b8a-4a47-3044-ab28-47d3c75c0e74.png)|

Swiftのコードがシンタックスハイライトされました。
CSSを適用したのでDiffのコードもスタイルが変わっていますが、シンタックスハイライトはされません。

## おわりに

これでPublishのプラグインをインストールできました！

トピックに `publish-plugin` が付いているとPublishのプラグインが見つけやすいとのことです。
以下のリンクからプラグインを探せるので、必要に応じてインストールしましょう :relaxed:
https://github.com/topics/publish-plugin?l=swift

## 参考リンク

- [Publish/using-splash.md](https://github.com/JohnSundell/Publish/blob/9e1b20a23c73ba078966a4fcce23146088d0de63/Documentation/HowTo/SyntaxHighlighting/using-splash.md)
- https://twitter.com/the_uhooi/status/1508699232668364807?s=20&t=gpIVMUdrxPED1br-rmVMvA
- [publish触ってく](https://zenn.dev/nnabeyang/scraps/ffa9047f75b1db#comment-cedd54b2de74f1)
- [JohnSundell/Publish: A static site generator for Swift developers](https://github.com/JohnSundell/Publish#building-plugins)
- [Swiftでブログが作れるPublishの機能を拡張するプラグインを作ってリリースする | DevelopersIO](https://dev.classmethod.jp/articles/publish-swift-plugin_intro/)