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 功能的物件:(必填)
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(最難)之間。網站會依下列方式解讀難度:
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
},
...
]
}
}
{
"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 在輸出賽道尚未實作的練習時,會忽略已略過的練習。
賽道可能不想實作某個練習的原因包括:
{
"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:要為該特色顯示的圖示。你可以挑選任何你認為合適的圖示,無須在意其名稱。可使用以下圖示:
communityconcurrencycross-platformdocumentationdynamically-typedeasyembeddableevolvingexpressiveextensiblefastfunfunctionalgarbage-collectedgeneral-purposehomoiconicimmutableinteractiveinteropmulti-paradigmportablepowerfulproductivesafescientificsmallstablestatically-typedtoolingwebwidely-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"
]
}