config.json文件描述 track 的配置,其中包含 track 的练习和概念等重要信息。
以下顶层属性包含 track 的常规元数据:
language:track 的语言(例如"C#")。长度必须 <= 255。(必填)slug:以小写 kebab-case 字符串表示的 track 语言(例如"csharp")。长度必须 <= 255。(必填)active:一个boolean值,表示该 track 是否处于活跃状态(即学生能否在网站上加入该 track)(必填)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 网站的界面会相应变化,以表明该 track 已有可用的概念练习。test_runner:一个boolean值,表示是否已实现 test runner(必填)。为true时,我们会让提交的解答经过我们的测试基础设施,并在网站上显示结果。网站还允许学生直接在在线编辑器里发起一次测试运行。representer:一个boolean值,表示是否已实现 representer(必填)analyzer:一个boolean值,表示是否已实现 analyzer(必填)files:练习中所用文件位置的模式,相对于该练习的目录。(可选)
solution:存根实现文件的模式(可选)test:测试文件的模式(可选)example:示例实现文件的模式(可选)exemplar:范例实现文件的模式(可选)editor:额外的只读编辑器文件模式(可选)test_runner:描述该 track 的 test runner 的对象(如果有):(当status.test_runner为true时必填)
average_run_time:test runner 平均运行秒数的整数number值(例如4)(当status.test_runner为true时必填)approaches:包含该 track 各 approach 元数据的对象:(当该 track 有任何 approach 时必填)
snippet_extension:用于代码片段文件扩展名的字符串值(例如rb)(当该 track 有任何 approach 时必填)该键用于指定整个 track 的文件位置。有了它,维护者不必再手动在每个练习的config.json文件中设置files键,configlet 可以依据这些 track 级模式自动填充它。
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:这是一个数组,列出该 track 的概念练习practice:这是一个数组,列出该 track 的实践练习foregone:这是一个数组,列出该 track 不会实现的练习的 slug每个概念练习都是exercises.concept数组中的一个条目。
网站上练习的顺序与本文件中列出的顺序一致,而且应当与通常的解题顺序相符。
概念练习由以下字段组成:
uuid:唯一标识该练习的 V4 UUID。该 UUID 在同一 track 内以及所有 track 之间都必须唯一,且绝不能更改slug:练习的 slug,一个全小写的 kebab-case 字符串。该 slug 在同一 track 内所有概念练习和实践练习的 slug 中必须唯一。长度必须 <= 255。name:练习的名称。长度必须 <= 255。concepts:该概念练习所教授的概念 slug 数组prerequisites:学生开始该练习之前必须已解锁的概念 slug 数组status(可选):练习的状态,取值为"wip"、"beta"、"active"或"deprecated"之一;未指定时默认为"active"
wip:尚未完成、还不适合公开的练习。带有此标记的练习不会在界面上显示给学生,也不参与解锁逻辑。它们可能会对维护者显示。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 在同一 track 内以及所有 track 之间都必须唯一,且绝不能更改slug:练习的 slug,一个全小写的 kebab-case 字符串。该 slug 在同一 track 内所有概念练习和实践练习的 slug 中必须唯一。长度必须 <= 255。name:练习的名称。长度必须 <= 255。practices:该练习帮助学生练习的概念 slug 数组prerequisites:学生开始该练习之前必须已解锁的概念 slug 数组difficulty:表示练习难度的数字。该数字必须在 1(最简单)到 10(最难)之间。网站对难度的解读如下:
status(可选):练习的状态,取值为"wip"、"beta"、"active"或"deprecated"之一;未指定时默认为"active"
wip:尚未完成、还不适合公开的练习。带有此标记的练习不会在界面上显示给学生,也不参与解锁逻辑。它们可能会对维护者显示。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"
},
...
]
}
}
如果某个 track 知道自己不想实现 Problem Specifications 仓库中定义的某个练习,可以把该练习的 slug 添加到exercises.foregone键中。configlet 在输出该 track 未实现的练习时会忽略已放弃的练习。
某个 track 可能不想实现某个练习,原因可以是:
{
"exercises": {
"foregone": [
"lens-person"
]
}
}
每个概念都是顶层concepts数组中的一个条目。概念由以下字段组成:
uuid:唯一标识该概念的 V4 UUID。该 UUID 在同一 track 内以及所有 track 之间都必须唯一,且绝不能更改slug:概念的 slug,一个全小写的 kebab-case 字符串。该 slug 在同一 track 内所有概念中必须唯一。长度必须 <= 255。name:概念的名称。长度必须 <= 255。tags:指定提交在何种条件下与某个 approach 关联。(可选)
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"
},
...
],
}
可以为 track 添加标签,这样就可以按特定的标签组合搜索 track。
track 应根据其语言的一般用途来选择标签。例如,想象一个学生正在想:“我想做机器学习,该选哪门语言?”,或者“我想学函数式编程,该选哪门语言?”。如果你的语言很合适,就给它加上那个标签。如果你的语言支持一些函数式思想,但很少用到,或者只有少数人用它做机器学习,而且并不常见,那就不要加这些标签。
标签在顶层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:Web 开发注意,同一个类别中包含多个标签是完全可以的。
示例
{
"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"
]
}