概要

これはObsidianとの互換性を備えたSSG(Static Site Generator)。これを使うだけでObsidianのVaultを見栄えのいいWebページに変換できる。他にも独自プラグインの作成や表示内容の簡単なカスタマイズなどができる。

環境

名前バージョンなど
Quartz4.0
Obsidianv1.5.11

とりあえず動かす

git clone https://github.com/jackyzha0/quartz.git
cd quartz
npm i
npx quartz create

初期設定後は同ディレクトリのcontentフォルダにVaultを入れ、 npx quartz build を実行するとpublicフォルダにサイトのコンテンツが保存される。 --serve をつけてbuildを実行すると保存後にサーバーを立ててくれる。これは後述するquartzの設定などを監視しており変更を加えると即座に変更が反映されるっぽい。 なお、サーバーにアクセスしたときのトップページはindex.mdの内容が使われる。もちろんこれを単体で作ってもいいしaliasesでindexを指定しても良い。

設定

Obsidian側の設定

プロパティ名説明
titleTextページに表示されるタイトル。ないなら文書名
descriptionTextリンクプレビュー時に表示される説明
aliasesListページの別名
tagsTagsタグ。Obsidianでの使い方でいい。
draftCheckboxチェックが入ってたら非公開
dateDateDate & Timeでも受け付けてるけどYYYY-MM-DD形式で表示されたのでそれ以上を求めるならカスタマイズする必要がある。

Quartz側の設定

設定に関わるファイルはQuartzの動作を変更するquartz.config.tsとWebページのレイアウトを変更するquartz.layout.tsの2つがあり、公式ドキュメントに詳細な説明がある

quartz.config.ts

Quartzの動作に関する設定を変更できる。 公式ドキュメントのGeneral Configurationが詳細に書いてあってわかりやすいので変更点だけ書く。

変更したプロパティ名
pageTitlescriptreplay minimarimo3.log
enableSPAfalse
analyticsnull
localeja-JP
baseUrllog.minimarimo3.jp
ignorePatterns”t_テンプレート”, “s_資料等”を追加
defaultDateTypemodified

また、Pluginsというパースの最中に内容を変更できるようになる仕組みの設定もできる。これはtransformersfilters, emittersの3タイミングで内容に変更を加えることができるもの。こっちも同じ理由から変更点だけ書く。

変更したプラグイン名プロパティ
CrawlLinksprettyLinksfalse
CrewlLinksopenLinksInNewTabtrue

quartz.layout.ts

Webページのレイアウトを変更できる。ページは公式サイトに載っている通り、ページのレイアウトのようになっており、それぞれの部位にQuartzComponentというもの(もしくはリスト)を追加することでWebページが構築される。 ここに表示されていない(=見えない or 標準で有効になっていない)レイアウトとして、headとheaderがある。headはhtmlのheadタグを設定でき、headerは有効化することでヘッダーバーを配置できるようになる。

こっちも同じくドキュメントが十分シンプルかつ分かりやすいので変更点だけ書く。 sharedPageComponents: (画面下に出てくる全ページ共通のコンポーネント)からGitHubのリンクとDiscordコミュニティへのリンクを削除。

export const defaultContentPageLayout: PageLayout = {  
  beforeBody: [  
    Component.Breadcrumbs(),  
    Component.ArticleTitle(),  
    Component.ContentMeta(),  
    Component.TagList(),  
    Component.MobileOnly(Component.TableOfContents()),  
  ],  
  left: [  
    Component.PageTitle(),  
    Component.MobileOnly(Component.Spacer()),  
    Component.Search(),  
    Component.Darkmode(),  
    Component.DesktopOnly(Component.Explorer()),  
  ],  
  right: [  
    Component.DesktopOnly(Component.TableOfContents()),  
    Component.Backlinks(),
	Component.RecentNotes()
    Component.MobileOnly(Component.Explorer()),  
  ],  
}

日誌と文献以外の場合、RSSがあることを通知する

// plugins/emitters/contentIndex.ts のgenerateRSSFeedを変更する
// 日誌とZoteroからのインポート用のRSSを作成しない
 
.map(([slug, content]) => {
if (!content.title.startsWith("@") && ! /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/.test(content.title)) {
return createURLEntry(simplifySlug(slug), content)
}
})
// components/Head.tsx のHeadを変更する
// 日誌か、Zotroからのインポートしたファイルを開いているときにRSSがあることをブラウザに通知しない
 
// return の上に追加
const isValidDateFormat = (str: string) => {
	const regex = /^\d{4}-\d{2}-\d{2}$/;
	return regex.test(str);
};
 
let rssLink;
if (!isValidDateFormat(title) && !title.startsWith('@')){
	rssLink = <link rel="alternate" type="application/rss+xml" title="scriptreplay minimarimo3.log" href="/index.xml" />;
}
 
// 省略
 
<meta name="generator" content="Quartz" />
{rssLink}  // 追加
{css.map((href) => (
<link key={href} href={href} rel="stylesheet" type="text/css" spa-preserve />
))}

適切な概要を生成する

// plugins/transformers/description.ts
// 45行目(if文の直前)から
// 概要〜環境があるならその中身を概要として処理
// 正規表現を使って '## 概要' から始まり、その後に空行が来る部分までをマッチさせる
const match = toString(tree).match(/概要\n([\s\S]*?)環境\n/);
if (match){
console.log(match[1])
file.data.description = match[1];
file.data.text = text;
return
}

サーバーの設定

ホストの方法についても公式ドキュメントが用意されている。 自分のサーバーでどうしているかは ObsidianのVaultを自分のサーバーで公開する に書いている。

参考文献

公式ドキュメント GitHub