config.json


config.json 檔案描述賽道的設定。它包含賽道的練習與概念等重要資訊。

中繼資料

以下頂層屬性包含一般的賽道中繼資料:

  • language:賽道的語言(例如 "C#")。長度必須 <= 255。(必填)
  • slug:以 kebab-case 小寫字串表示的賽道語言(例如 "csharp")。長度必須 <= 255。(必填)
  • active:一個 boolean 值,指出賽道是否為啟用狀態(也就是學生可以在網站上加入該賽道)(必填)
  • blurb:語言的簡短描述。長度必須 <= 400。(必填)
  • version:config.json 檔案的版本(目前固定為 3)(必填)
  • online_editor:描述線上編輯器所用設定的物件:(必填)
    • indent_style:"space" 或 "tab"(必填)
    • indent_size:以整數表示的縮排大小(例如 4)(必填)
    • highlightjs_language:Highlight.js 的語言識別碼(請參閱完整的識別碼清單)(選填)
  • status:描述應啟用哪些 v3 功能的物件:(必填)
    • concept_exercises:一個 boolean 值,指出是否已建置概念練習(必填)。當值為 true 時,Exercism 網站的介面會隨之改變,表示該賽道已有可用的概念練習。
    • test_runner:一個 boolean 值,指出是否已實作測試執行器(必填)。當值為 true 時,我們會讓提交的解答通過我們的測試基礎架構,並在網站上顯示結果。網站也允許學生直接在線上編輯器裡發起測試執行。
    • representer:一個 boolean 值,指出是否已實作呈現器(必填)
    • analyzer:一個 boolean 值,指出是否已實作分析器(必填)
  • files:練習中所用檔案位置的樣式,相對於該練習的目錄。(選填)
    • solution:起始實作檔案樣式(選填)
    • test:測試檔案樣式(選填)
    • example:範例實作檔案樣式(選填)
    • exemplar:典範實作檔案樣式(選填)
    • editor:額外的唯讀編輯器檔案樣式(選填)
  • test_runner:描述賽道測試執行器的物件(若有):(若 status.test_runner 為 true 則必填)
    • average_run_time:一個整數 number 值,代表測試執行器平均執行所需的秒數(例如 4)(若 status.test_runner 為 true 則必填)
  • approaches:帶有賽道解題方法相關中繼資料的物件:(若賽道有任何解題方法則必填)
    • snippet_extension:用於程式碼片段副檔名的字串值(例如 rb)(若賽道有任何解題方法則必填)

檔案

這個索引鍵用來指定全賽道共通的檔案位置。與其讓維護者在每個練習的 config.json 檔案中手動設定 files 索引鍵,configlet 可以透過這些全賽道樣式自動填入。

files 物件中定義的檔案樣式支援以下佔位符:

  • %{kebab_slug}:kebab-case 的練習 slug(例如 bit-manipulation)
  • %{snake_slug}:snake_case 的練習 slug(例如 bit_manipulation)
  • %{camel_slug}:camelCase 的練習 slug(例如 bitManipulation)
  • %{pascal_slug}:PascalCase 的練習 slug(例如 BitManipulation)

configlet 之後將支援使用這些樣式,在練習的 .meta/config.json 檔案中填入 files 索引鍵。

範例

{
  "language": "C#",
  "slug": "csharp",
  "active": true,
  "status": {
    "concept_exercises": true,
    "test_runner": true,
    "representer": false,
    "analyzer": false
  },
  "blurb": "C# is a modern, object-oriented language with lots of great features, such as type-inference and async/await. The tooling is excellent, and there is extensive, well-written documentation.",
  "version": 3,
  "online_editor": {
    "indent_style": "space",
    "indent_size": 4,
    "highlightjs_language": "csharp"
  },
  "test_runner": {
    "average_run_time": 2
  },
  "files": {
    "solution": [
      "%{pascal_slug}.cs"
    ],
    "test": [
      "%{pascal_slug}Tests.cs"
    ],
    "example": [
      ".meta/Example.cs"
    ],
    "exemplar": [
      ".meta/Exemplar.cs"
    ]
  }
}

練習

頂層的 exercises 索引鍵是一個物件,可包含三個索引鍵:

  • concept:這是一個陣列,列出賽道的概念練習
  • practice:這是一個陣列,列出賽道的實作練習
  • foregone:這是一個陣列,列出賽道不會實作的練習 slug

概念練習

每個概念練習都是 exercises.concept 陣列中的一個項目。 網站上練習的排序與本檔案中列出的順序相同,且應符合一般建議的解題順序。 概念練習由以下欄位組成:

  • uuid:一個 V4 UUID,用來唯一識別該練習。此 UUID 在賽道內以及所有賽道之間都必須是唯一的,且絕對不能變更
  • slug:練習的 slug,是一個 kebab-case 小寫字串。在賽道內,該 slug 在所有概念與實作練習的 slug 中必須是唯一的。長度必須 <= 255。
  • name:練習的名稱。長度必須 <= 255。
  • concepts:此概念練習所教授的概念 slug 陣列
  • prerequisites:學生必須先解鎖才能開始此練習的概念 slug 陣列
  • status(選填):練習的狀態,為 "wip"、"beta"、"active" 或 "deprecated" 其中之一;未指定時預設為 "active"
    • wip:尚在開發中、還沒準備好公開的練習。帶有此標記的練習不會在 UI 上顯示給學生,也不會用於解鎖邏輯。維護者可能會看到它們。
    • beta:這代表新推出、我們希望收到回饋的啟用中練習。我們會在網站上為這些練習顯示 beta 標籤,並附上「請給我們回饋。」的行動呼籲。
    • active:啟用中練習的一般狀態
    • deprecated:不再顯示給尚未開始該練習的學生(在此階段已無法使用)。詳情請參閱已棄用的練習。

範例

{
  "exercises": {
    "concept": [
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ]
      },
      ...
    ]
  }
}

開發中範例

{
  "exercises": {
    "concept": [
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ],
        "status": "wip"
      },
      ...
    ]
  }
}

實作練習

每個實作練習都是 exercises.practice 陣列中的一個項目。實作練習由以下欄位組成:

  • uuid:一個 V4 UUID,用來唯一識別該練習。此 UUID 在賽道內以及所有賽道之間都必須是唯一的,且絕對不能變更
  • slug:練習的 slug,是一個 kebab-case 小寫字串。在賽道內,該 slug 在所有概念與實作練習的 slug 中必須是唯一的。長度必須 <= 255。
  • name:練習的名稱。長度必須 <= 255。
  • practices:此練習幫助學生練習的概念 slug 陣列
  • prerequisites:學生必須先解鎖才能開始此練習的概念 slug 陣列
  • difficulty:一個數字,表示練習的難度。數字必須落在 1(最簡單)到 10(最難)之間。網站會依下列方式解讀難度:
    • 1、2、3:簡單
    • 4、5、6、7:中等
    • 8、9、10:困難
  • status(選填):練習的狀態,為 "wip"、"beta"、"active" 或 "deprecated" 其中之一;未指定時預設為 "active"
    • wip:尚在開發中、還沒準備好公開的練習。帶有此標記的練習不會在 UI 上顯示給學生,也不會用於解鎖邏輯。維護者可能會看到它們。
    • beta:這代表新推出、我們希望收到回饋的啟用中練習。我們會在網站上為這些練習顯示 beta 標籤,並附上「請給我們回饋」的行動呼籲
    • active:啟用中練習的一般狀態
    • deprecated:不再顯示給尚未開始該練習的學生(在此階段已無法使用)。

網站上實作練習的「建議順序」對應到 practice 陣列中練習的順序。

範例

{
  "exercises": {
    "practice": [
      {
        "slug": "leap",
        "name": "Leap",
        "uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
        "practices": [
          "if-statements",
          "numbers",
          "operator-precedence"
        ],
        "prerequisites": [
          "if-statements",
          "numbers"
        ],
        "difficulty": 1
      },
      ...
    ]
  }
}

beta 範例

{
  "exercises": {
    "practice": [
      {
        "slug": "leap",
        "name": "Leap",
        "uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
        "practices": [
          "if-statements",
          "numbers",
          "operator-precedence"
        ],
        "prerequisites": [
          "if-statements",
          "numbers"
        ],
        "difficulty": 1,
        "status": "beta"
      },
      ...
    ]
  }
}

已略過的練習

如果某個賽道確定不想實作 Problem Specifications 儲存庫 中定義的某個練習,可以將該練習的 slug 加入 exercises.foregone 索引鍵。configlet 在輸出賽道尚未實作的練習時,會忽略已略過的練習。

賽道可能不想實作某個練習的原因包括:

  • 該練習無法由這個語言合理地實作。舉例來說,lens-person 練習 需要語言支援 lens。
  • 練習的主題不適合這個語言。例如,對某些高階語言來說,低階的位元操作練習可能沒有意義。

範例

{
  "exercises": {
    "foregone": [
      "lens-person"
    ]
  }
}

概念

每個概念都是頂層 concepts 陣列中的一個項目。概念由以下欄位組成:

  • uuid:一個 V4 UUID,用來唯一識別該概念。此 UUID 在賽道內以及所有賽道之間都必須是唯一的,且絕對不能變更
  • slug:概念的 slug,是一個 kebab-case 小寫字串。在賽道內,該 slug 在所有概念中必須是唯一的。長度必須 <= 255。
  • name:概念的名稱。長度必須 <= 255。
  • tags:指定提交內容在何種條件下會與某個解題方法連結。(選填)
    • all:提交內容必須全部具備的標籤陣列(選填,除非 any 沒有任何元素)
    • any:提交內容至少須具備其中一個的標籤陣列(選填,除非 all 沒有任何元素)
    • not:提交內容不得具備其中任何一個標籤(選填)

範例

{
  "concepts": [
    {
      "uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
      "slug": "numbers",
      "name": "Numbers",
      "tags": {
        "all": [
          "concept:number"
        ]
      }
    }
  ]
}

關鍵特色

語言的關鍵特色簡潔地描述該語言最重要的特色。 它們旨在向潛在學生推廣語言中較有趣的功能。 標題應盡量少用技術行話,請記住,學生在學習該語言之前,可能還不熟悉該語言專有的行話代表什麼意思。

關鍵特色定義在頂層 key_features 欄位中,該欄位定義為一個物件陣列,物件包含以下欄位:

  • title:關鍵特色的簡潔標題。長度必須 <= 25。不支援 Markdown。
  • content:關鍵特色的描述。長度必須 <= 100。不支援 Markdown。
  • icon:要為該特色顯示的圖示。你可以挑選任何你認為合適的圖示,無須在意其名稱。可使用以下圖示:
    • community
    • concurrency
    • cross-platform
    • documentation
    • dynamically-typed
    • easy
    • embeddable
    • evolving
    • expressive
    • extensible
    • fast
    • fun
    • functional
    • garbage-collected
    • general-purpose
    • homoiconic
    • immutable
    • interactive
    • interop
    • multi-paradigm
    • portable
    • powerful
    • productive
    • safe
    • scientific
    • small
    • stable
    • statically-typed
    • tooling
    • web
    • widely-used

你可以在關鍵特色圖示區段查看這些圖示的外觀。

必須正好指定 6 個關鍵特色。

範例

{
  "key_features": [
    {
      "title": "Fault-tolerant",
      "content": "Elixir runs on the Erlang VM, known for running low-latency, distributed and fault-tolerant systems.",
      "icon": "safe"
    },
    ...
  ],
}

標籤

賽道可以加上標籤註記,讓我們能依特定標籤組合搜尋賽道。

賽道應根據其語言的一般用途來選擇標籤。舉例來說,想像有個學生心想:「我想做機器學習,該選哪個語言?」,或「我想學函式式程式設計,該選哪個語言?」。如果你的語言會是不錯的選擇,就給它那個標籤。如果你的語言支援某些函式式概念,但很少人使用,或者只有少數人用它做機器學習,但這很罕見,就不要套用那些標籤。

標籤定義在頂層 tags 欄位中,該欄位定義為一個字串陣列。可使用以下標籤(依類別分組):

範式

  • paradigm/array:該語言是陣列程式語言
  • paradigm/declarative:該語言支援宣告式程式設計風格
  • paradigm/functional:該語言支援函式式程式設計風格
  • paradigm/imperative:該語言支援命令式程式設計風格
  • paradigm/logic:該語言支援以邏輯為基礎的程式設計風格
  • paradigm/object_oriented:該語言支援物件導向程式設計風格
  • paradigm/procedural:該語言支援程序式程式設計風格
  • paradigm/stack-oriented:該語言支援堆疊導向程式設計風格

型別

  • typing/static:該語言使用靜態型別
  • typing/gradual:該語言使用漸進式型別
  • typing/dynamic:該語言使用動態型別
  • typing/strong:該語言使用強型別
  • typing/weak:該語言使用弱型別

執行模式

  • execution_mode/compiled:程式碼會先經過編譯再執行
  • execution_mode/interpreted:程式碼直接以直譯方式執行

平台

  • platform/windows:在 Windows 上執行
  • platform/mac:在 Mac 上執行
  • platform/linux:在 Linux 上執行
  • platform/ios:在 iOS 上執行
  • platform/android:在 Android 上執行
  • platform/web:在瀏覽器上執行

執行環境

  • runtime/standalone_executable:以獨立執行檔執行
  • runtime/language_specific:在語言專屬的執行環境上執行
  • runtime/clr:在 Common Language Runtime (.NET) 上執行
  • runtime/jvm:在 JVM (Java) 上執行
  • runtime/beam:在 BEAM (Erlang) 上執行
  • runtime/wasmtime:在 Wasmtime (WebAssembly) 上執行

用途

  • used_for/artificial_intelligence:人工智慧
  • used_for/backends:後端
  • used_for/cross_platform_development:跨平台開發
  • used_for/embedded_systems:嵌入式系統
  • used_for/financial_systems:金融系統
  • used_for/frontends:前端
  • used_for/games:遊戲
  • used_for/guis:圖形使用者介面
  • used_for/mobile:行動裝置
  • used_for/robotics:機器人
  • used_for/scientific_calculations:科學運算
  • used_for/scripts:指令碼
  • used_for/web_development:網頁開發

請注意,從單一類別中包含多個標籤是完全沒問題的。

範例

{
  "tags": [
    "paradigm/declarative",
    "paradigm/functional",
    "paradigm/object_oriented",
    "platform/linux",
    "platform/windows",
    "runtime/jvm"
  ]
}

範例

這是有效的 config.json 檔案可能長什麼樣子的範例:

{
  "language": "C#",
  "slug": "csharp",
  "active": true,
  "status": {
    "concept_exercises": true,
    "test_runner": true,
    "representer": false,
    "analyzer": false
  },
  "blurb": "C# is a modern, object-oriented language with lots of great features, such as type-inference and async/await. The tooling is excellent, and there is extensive, well-written documentation.",
  "version": 3,
  "online_editor": {
    "indent_style": "space",
    "indent_size": 4,
    "highlightjs_language": "csharp"
  },
  "test_runner": {
    "average_run_time": 2
  },
  "files": {
    "solution": [
      "%{pascal_slug}.cs"
    ],
    "test": [
      "%{pascal_slug}Tests.cs"
    ],
    "example": [
      ".meta/Example.cs"
    ],
    "exemplar": [
      ".meta/Exemplar.cs"
    ]
  },
  "exercises": {
    "concept": [
      {
        "slug": "lucians-luscious-lasagna",
        "name": "Lucian's Luscious Lasagna",
        "uuid": "7d358894-4fbd-4c91-b49f-d68f1c5aa6bc",
        "concepts": [
          "basics"
        ],
        "prerequisites": []
      },
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ],
        "status": "wip"
      }
    ],
    "practice": [
      {
        "slug": "hello-world",
        "name": "Hello, World!",
        "uuid": "6c88f46b-5acb-4fae-a6ec-b48ae3f8168f",
        "practices": [
          "strings"
        ],
        "prerequisites": [
          "basics"
        ],
        "difficulty": 1
      },
      {
        "slug": "leap",
        "name": "Leap",
        "uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
        "practices": [
          "if-statements",
          "numbers",
          "operator-precedence"
        ],
        "prerequisites": [
          "if-statements",
          "numbers"
        ],
        "difficulty": 2,
        "status": "beta"
      }
    ]
  },
  "concepts": [
    {
      "uuid": "2eb4a463-355f-46ef-ac55-a75ec5afdf86",
      "slug": "basics",
      "name": "Basics"
    },
    {
      "uuid": "4466e33e-dcd2-4b1f-9d9d-2c4315bf5188",
      "slug": "if-statements",
      "name": "If Statements"
    },
    {
      "uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
      "slug": "numbers",
      "name": "Numbers"
    },
    {
      "uuid": "7a86561d-173b-45c0-a53c-1ffd7b9ff259",
      "slug": "strings",
      "name": "Strings"
    }
  ],
  "key_features": [
    {
      "title": "Modern",
      "content": "C# is a modern, fast-evolving language.",
      "icon": "expressive"
    },
    {
      "title": "Cross-platform",
      "content": "C# runs on almost any platform and chipset.",
      "icon": "cross-platform"
    },
    {
      "title": "Multi-paradigm",
      "content": "C# is primarily an object-oriented language, but also has lots of functional features.",
      "icon": "multi-paradigm"
    },
    {
      "title": "General purpose",
      "content": "C# can be used for a wide variety of workloads, like websites, console applications, and even games.",
      "icon": "general-purpose"
    },
    {
      "title": "Tooling",
      "content": "C# has excellent tooling, with linting and advanced refactoring options built-in.",
      "icon": "tooling"
    },
    {
      "title": "Documentation",
      "content": "Documentation is excellent and exhaustive, making it easy to get started with C#.",
      "icon": "documentation"
    }
  ],
  "tags": [
    "paradigm/declarative",
    "paradigm/functional",
    "paradigm/object_oriented",
    "platform/linux",
    "platform/windows",
    "runtime/jvm"
  ]
}