.NET6使用DOCFX自動生成開發文件

sogeisetsu發表於2021-12-11

本文內容來自我寫的開源電子書《WoW C#》,現在正在編寫中,可以去WOW-Csharp/學習路徑總結.md at master · sogeisetsu/WOW-Csharp (github.com)來檢視編寫進度。預計2021年年底會完成編寫,2022年2月之前會完成所有的校對和轉制電子書工作,爭取能夠在2022年將此書上架亞馬遜。編寫此書的目的是因為目前.NET市場相對低迷,很多優秀的書都是基於.NET framework框架編寫的,與現在的.NET 6相差太大,正規的.NET 5學習教程現在幾乎只有MSDN,可是MSDN雖然準確優美但是太過瑣碎,沒有過閱讀開發文件的同學容易一頭霧水,於是,我就編寫了基於.NET 5的《WoW C#》。本人水平有限,歡迎大家去本書的開源倉庫sogeisetsu/WOW-Csharp關注、批評、建議和指導。

注意,本文所講的API,為基於對程式碼註釋而自動生成的開發文件,API內容為程式碼中內類及成員的解釋,並非Web API或者REST API。

DOCFX

在團隊開發過程中,一個漂亮的開發文件是至關重要的,它有助於幫助人們快速地理解專案。DOCFX是一個搭建開發文件網站和根據註釋生成api文件的工具。DOCFX極其強大,自定義程度極高,缺點是自動化程度不高,使用起來略顯麻煩,比如已經2021年了,官方竟然還不支援自動生成目錄,好在其有很多與其相關的開源專案,可以一定程度上彌補它的缺憾。如果將DOCFX用好了,它就不僅僅是API文件生成器,還是一個簡單的部落格網站構建器,DOCFX由微軟旗下的dotnet開源,微軟的MSDN的構建就用到了DOCFX。遺憾的是DOCFX目前官方只支援.Net和JavaScript,但是它提供了Generate Metadata的步驟,理論上它可以支援任何語言(DocFX is designed to support any language),GitHub上基本上常見的語言都有針對DOCFX的開源專案。本文對DOCFX的講解不及其功能的十分之一,但是基本上可以應對日常的需要,如果想要進一步瞭解DOCFX,請前往DocFX - static documentation generator | DocFX website (dotnet.github.io)。本文所使用由DOCFX生成的API文件專案可以前往sogeisetsu/WOW-Csharp at docfx_example (github.com)檢視原始碼。

第一步 生成簡單的文件網站

前往Releases · dotnet/docfx (github.com)下載最新版的DOCFX。將其加入環境變數,這樣為了方便起見,docfx 命令可以直接從任何地方呼叫。(例如,對於 Windows,設定 PATH =%PATH%;d:docfx)。

  1. 執行docfx init-q。這個命令生成一個 docfx_project 資料夾,其下面有預設的 docfx.json 檔案。Json 是 docfx 用來生成文件的配置檔案。-q 選項意味著使用預設值悄悄地生成專案,您也可以嘗試 docfx init,並按照說明提供自己的設定。

  2. 執行命令 docfx docfx_project/docfx.json。請注意,在該資料夾下生成了一個新的子資料夾 _site。這是生成靜態網站的地方。

  3. 執行docfx serve docfx_project/_site就可以從http://localhost:8080檢視生成的網頁。如果未使用埠 8080,docfx 將在 http://localhost:8080 下託管 _site。如果8080正在使用,可以使用docfx serve _site -p <port>更改docfx使用的埠。

    walkthrough_simple_homepage.png (1026×640) (dotnet.github.io)

向網站新增文章

在進行初始化和建立網站之後,當前的docfx_project檔案結構應該是這樣的:

.
├── _site
├── api
├── apidoc
├── articles
├── docfx.json
├── images
├── index.md
├── obj
├── src
└── toc.yml

各個檔案和資料夾的作用如下:

/ - 這個網站的根目錄,包含:

  • docfx.json - docfx 依賴的配置檔案。所有的命令及其涉及到的檔案都會用docfx.json來配置。
  • index.md - 用來建立網站的首頁。
  • toc.yml – 呈現為導航選單欄,顯示在網站每個頁面的頂部。

/articles - 裡面放著一些markdown檔案。這些markdown檔案的圖片放在/images下。 這些 Markdown 檔案釋出在選單欄的Ariticles部分下。

/src - 包含可選的 .NET 語言專案檔案 (*.csproj),其中包含用於生成託管 API 文件的型別資訊。

/apidoc - 包含用於覆蓋根據註釋中自動生成的文字的 Markdown 檔案。

執行 DocFx 後,將建立其他資料夾:

/_site - 包含由 DocFx 生成的所有站點檔案,包括網站所需的生成的 HTML/JSON/JS/Images 檔案。

修改首頁

可以修改根目錄下的index.md來修改網站的首頁

將更多的文章放到網站

  1. 將更多.md檔案放入articles,例如快速開始.md演練.md進階.md。如果檔案引用了任何資源,請將這些資源放入images資料夾中。

  2. 為了組織這些文章,我們將這些檔案新增到/articles/toc.yml(也可以使用工具Release 用於自動生成docfx文件 · whuanle/CZGL.DocfxBuild.Yml (github.com)自動生成目錄)。內容toc.yml如下:

    - name: 快速開始
      href: intro.md
    - name: 演練
      href: 演練.md
    - name: 進階
      href: 進階.md
    

    現在articles資料夾的佈局是:

    .
    ├── intro.md
    ├── toc.yml
    ├── 演練.md
    └── 進階.md
    
  3. docfx_project資料夾下執行docfxdocfx serve _site,然後就可以看到已經有文章加入:

修改導航選單欄

導航選單欄預設有兩個選項,分別是ArticlesAPI Documentation,可以通過修改根目錄下的toc.yml來修改導航選單欄的名稱:

- name: 開始
  href: articles/
- name: Api 文件
  href: api/
  # homepage來定義api的首頁
  homepage: api/index.md

也可以嚮導航選單欄增加新的選項,比如說,在根目錄新建一個資料夾,命名為blog,該資料夾結構如下:

.
├── GIT 的merge、rebase和cherry-pick.md
├── Google Fonts注意事項.md
├── Linux筆記.md
├── issue trans Problem Description.md
├── python 包(package)和模組(module)的建立和引入(import).md
├── toc.yml
├── unix bsd linux shell bash GNU之間的聯絡,歪講Linux(一).md
├── vscode git 無需命令列.md
├── 一.md
├── 關於若干問題的解釋說明.md
├── 商品上架格式.md
├── 如何在印刷品中使用遵循SIL Open Font License協議的字型.md
├── 對微信支付文件的自我理解.md
├── 我的python加密方案.md
├── 找人.md
├── 日語 時間的量.md
├── 日語學習資源的分享.md
├── 說明.md
├── 貝多芬小傳.md
├── 還沒有學會告別,就已經後會無期。.md
├── 雷電介面.md
└── 青島科技大學新生報考參考.md

在該資料夾內新增toc.yml,內容如下:

### D:\blog
- name: GIT 的merge、rebase和cherry-pick
  href: GIT 的merge、rebase和cherry-pick.md
- name: Google Fonts注意事項
  href: Google Fonts注意事項.md
- name: issue trans Problem Description
  href: issue trans Problem Description.md
- name: Linux筆記
  href: Linux筆記.md
- name: python 包(package)和模組(module)的建立和引入(import)
  href: python 包(package)和模組(module)的建立和引入(import).md
- name: unix bsd linux shell bash GNU之間的聯絡,歪講Linux(一)
  href: unix bsd linux shell bash GNU之間的聯絡,歪講Linux(一).md
- name: vscode git 無需命令列
  href: vscode git 無需命令列.md
- name: 一
  href: 一.md
- name: 關於若干問題的解釋說明
  href: 關於若干問題的解釋說明.md
- name: 商品上架格式
  href: 商品上架格式.md
- name: 如何在印刷品中使用遵循SIL Open Font License協議的字型
  href: 如何在印刷品中使用遵循SIL Open Font License協議的字型.md
- name: 對微信支付文件的自我理解
  href: 對微信支付文件的自我理解.md
- name: 我的python加密方案
  href: 我的python加密方案.md
- name: 找人
  href: 找人.md
- name: 日語 時間的量
  href: 日語 時間的量.md
- name: 日語學習資源的分享
  href: 日語學習資源的分享.md
- name: 說明
  href: 說明.md
- name: 貝多芬小傳
  href: 貝多芬小傳.md
- name: 還沒有學會告別,就已經後會無期。
  href: 還沒有學會告別,就已經後會無期。.md
- name: 雷電介面
  href: 雷電介面.md
- name: 青島科技大學新生報考參考
  href: 青島科技大學新生報考參考.md

修改根目錄的toc.yml,將blog資料夾加進去:

- name: 開始
  href: articles/
- name: Api 文件
  href: api/
  homepage: api/index.md
- name: 部落格
  href: blog/
  homepage: blog/GIT 的merge、rebase和cherry-pick.md

然後修改根目錄下的docfx.json,這是依賴的配置檔案。關於它的用法後面再講,在docfx.json修改build的content下新增:

{
    "files": [
        "blog/**.md",
        "blog/**/toc.yml",
        "toc.yml",
        "*.md"
    ]
}

docfx_project資料夾下執行docfxdocfx serve _site,然後就可以看到已經有文章加入:

第二步 向網站新增 API 文件

向/src資料夾下新增一個c#專案,要包含csproj檔案。

├── src
   ├── ConsoleApp1.csproj
   ├── Program.cs
   ├── bin
   ├── newLei.cs
   └── obj

docfx_project資料夾下執行docfxdocfx serve _site,然後就可以看到已經有根據註釋自動生成的API文章加入:

在左側導航加入其他資料夾的內容

當前的根目錄下的toc.yml是這樣的:

- name: 開始
  href: articles/
- name: Api 文件
  href: api/
  homepage: api/index.md
- name: 部落格
  href: blog/
  homepage: blog/GIT 的merge、rebase和cherry-pick.md

這表示開始這一選單下只會包含articles資料夾下面的內容。

現在在根目錄新建一個資料夾,命名為anycombine,在該資料夾下面放置一個toc.yml,內容如下:

- name: Articles
  href: ../articles/toc.yml
- name: Blog
  href: ../blog/toc.yml

然後修改根目錄下的toc.yml:

- name: 開始
  href: anycombine/
- name: Api 文件
  href: api/
  homepage: api/index.md
- name: 部落格
  href: blog/
  homepage: blog/GIT 的merge、rebase和cherry-pick.md

最後在docfx.json裡面新增anycombine資料夾,讓其在建立網頁時能夠包含這個資料夾:

  "build": {
    "content": [
      {
        "files": "anycombine/**"
      },

然後建立網站,網站上導航選單欄中的開始選項包含articlesblog兩個資料夾的內容:

匯出為PDF文件

之前已經講解了如何生成網站,現在講解如何將網站上面的內容轉為PDF,先下載一個開源工具 wkhtmltopdf,可以前往wkhtmltopdf根據自己電腦的規格來選擇版本。安裝或解壓之後,將其放置在環境變數,方便以後呼叫,可以在power shell使用setx PATH "%PATH%;D:\wkhtmltopdf\bin"來將其放入環境變數。

然後在之前docfx生成的資料夾的根目錄下建立一個資料夾,名為pdf,在裡面建立一個toc.yml來包含需要生成PDF的目錄:

- name: Articles
  href: ../articles/toc.yml
- name: Blog
  href: ../blog/toc.yml
- name: API 文件
  href: ../api/toc.yml

接下來,需要將pdf部分新增到docfx.json,只有這樣,才能在執行docfx的時候來將其轉換為pdf,增加一個pdf屬性,docfx.json排除了 TOC 檔案,因為每個 TOC 檔案都會生成一個 PDF 檔案,內容如下:

"pdf": {
    "content": [
        {
            "files": [
                "api/**.yml"
            ],
            "exclude": [
                "**/toc.yml",
                "**/toc.md"
            ]
        },
        {
            "files": [
                "articles/**.md",
                "articles/**/toc.yml",
                "toc.yml",
                "*.md"
            ],
            "exclude": [
                "**/toc.yml",
                "**/toc.md"
            ]
        },
        {
            "files": [
                "blog/**.md",
                "blog/**/toc.yml",
                "toc.yml",
                "*.md",
                "pdf/*"
            ],
            "exclude": [
                "**/toc.yml",
                "**/toc.md"
            ]
        },
        {
            "files": "pdf/toc.yml"
        }
    ],
    "resource": [
        {
            "files": [
                "images/**"
            ]
        }
    ],
    "overwrite": [
        {
            "files": [
                "apidoc/**.md"
            ],
            "exclude": [
                "obj/**",
                "_site/**"
            ]
        }
    ],
    "wkhtmltopdf": {
        "additionalArguments": "--enable-local-file-access"
    },
    "dest": "_site_pdf"
}

然後在docfx專案的根目錄執行docfx,就可以在_site_pdf資料夾看到pdf檔案了。提示:這一過程可能會花費比較長的時間,建議喝杯咖啡等待。

其實,說實話,html的表現效果一定要比PDF檔案強,這個是毋庸置疑的。

DOCFX 常用命令

現在根據docfx.json中的設定,有下面幾個命令(之所以放到這裡說是因為易懂性方面的考慮):

  • docfx metadata 根據src目錄下的專案來修改api資料夾的內容,即生成API文件。
  • docfx build 生成網站原始碼,檔案放在_site資料夾下。
  • docfx serve <_site資料夾位置> 建立本地伺服器,可以本地訪問API網站內容
  • docfx pdf 匯出PDF。
  • docfx 執行docfx metadatadocfx builddocfx pdf

應該可以看到,DOCFX的命令的內容甚至是作用都和docfx.json中的配置是息息相關的,這個配置檔案其實很好理解,主要記住content屬性會規定命令會波及到哪些檔案和會放過那些檔案其實就可以了。遇到別的需求可以查閱docfx.exe User Manual | DocFX website (dotnet.github.io),裡面詳細地記載了docfx.json中每個屬性的作用。

自定義

template

執行命令docfx template list,可看到內建的模板列表:

Existing embedded templates are:
        common
        default(zh-cn)
        default
        pdf.default
        statictoc

可以在docfx.json中的build屬性的template屬性中設定模板:

"template": [
    "default(zh-cn)"
],

也可以在命令列中進行類似-t statictoc的操作,比如使用docfx build -t statictoc之後的網站是一個靜態網站,可以通過本地檔案系統預覽而非伺服器環境。

.NET6使用DOCFX自動生成開發文件

匯出template

使用docfx template export default可已匯出預設的HTML模板,將有名為 _exported_templates 的資料夾新增到根目錄下,其中包含名為default的資料夾,即default模板的HTML。

建立template

建立一個資料夾,比如templates,然後將匯出的_exported_templates 中的default資料夾複製到templates中。

  • templates中的default現在就是建立的一個新的模板資料夾,可以修改其中的內容來自定義。

    • 修改partials/footer.tmpl.partial來修改頁尾版權,建議只修改<span>Generated by <strong>DocFX</strong></span>部分來宣告自己的版權,不要修改微軟對DOCFX的版權。

      {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
      
      <footer>
        <div class="grad-bottom"></div>
        <div class="footer">
          <div class="container">
            <span class="pull-right">
              <a href="#top">{{__global.backToTop}}</a>
            </span>
            {{{_appFooter}}}
            {{^_appFooter}}<span>Copyright (c) 2021 蘇月晟,版權所有。<br>通過<strong>DocFX</strong>生成</span>{{/_appFooter}}
          </div>
        </div>
      </footer>
      
      
    • 有一個預設模板叫做default(zh-cn),可以將文件改為中文,在docfx.json將其放到裡面來實現中文,並將自定義模板放到default(zh-cn)後面,因為在docfx.jsonbuildtemplate中是後面的覆蓋前面的,這樣就不用再一個個修改自己自定義的模板了。如果想自定義中文可以修改模板檔案中的partials/title.tmpl.partialtoken.json兩個檔案來自定義中文名稱。

      "template": [
          "templates/default",
          "default(zh-cn)"
      ],
      
    • 對於修改圖示和logo有兩個方式,一個是參考docfx.exe User Manual | DocFX website (dotnet.github.io)docfx.json中的"globalMetadata"進行修改,另一個是直接替換模板檔案中的logo.svg和favicon.ico。可以修改partials\logo.tmpl.partial來取消class=“svg”從而取消logo的動畫,並可以調整大小,這裡附上我自己對partials\logo.tmpl.partial的修改,僅供參考。

      <a class="navbar-brand" href="{{_rel}}index.html">
        <img id="logo" src="{{_rel}}{{{_appLogoPath}}}{{^_appLogoPath}}logo.svg{{/_appLogoPath}}" height="46" width="46" alt="{{_appName}}" >
      </a>
      
    • 可以在docfx.json中的"globalMetadata"_enableSearch設定為true來增加搜尋框,但是根據實驗,docfx對中文搜尋的支援很差。可以修改_appTitle來修改網站的標題。可以增加_gitContribute來設定Improve this Doc按鈕。

    • 可以修改模板中的styles\docfx.vendor.css來自由發揮對css的修改,筆者的方式為先在瀏覽器中確定css選擇器,然後再進行對應的修改。

  • 最終為了使我們建立的模板工作,應當在在docfx.jsonbuildtemplate中的來新增模板資料夾相對位置,為了顯示中文,筆者還會使用一個預設模板叫做default(zh-cn)

    • "template": [
          "templates/default",
          "default(zh-cn)"
      ],
      

最終的效果如下:

可以訪問這是首頁 | 演示文件製作 (sogeisetsu.github.io)來檢視在這篇文章中筆者所建立的文件網站,可以在sogeisetsu/WOW-Csharp at docfx_example (github.com)檢視文件網站的原始碼和docfx配置檔案。

LICENSE

已將所有引用其他文章之內容清楚明白地標註,其他部分皆為作者勞動成果。對作者勞動成果做以下宣告:

copyright © 2021 蘇月晟,版權所有。

知識共享許可協議
作品蘇月晟採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。

相關文章