diff --git a/README.md b/README.md index 1b4bae039e1250adadb87458884e2cf4069b2508..b9ea41e1a11dd4cea7ef21b17309d3dc1d98944c 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,13 @@ pip install -r requirement.txt ## `知识节点` 的导出习题选项配置编辑 +目前我们支持使用 markdown 语法直接编辑习题和各选项,或者编写习题代码和替换规则,让程序动态生成选项。 + +我们先介绍使用替换规则的习题如何编辑,在最后介绍 markdown 方式编写习题的方法。对于 Java 技能树,我们更*推荐* +使用 markdown 方式编写习题。 + +### 使用替换规则编写习题 + 首先,在知识节点下增加一个习题代码,例如在 `data/1.Java初阶/1.Java概述/1.什么是Java` 下增加一个`HelloWorld.java`代码: ```java @@ -83,7 +90,7 @@ public class App { 其次,增加一个同名的选项配置文件`HelloWorld.json`,目前有三种配置规则 -### 单行替换规则 +#### 单行替换规则 * 配置由`one_line`字段指定的单行替换字典 * 格式是:`"<源字符串>"`: [`"<替换字符串A>"`, `<替换字符串B>`,...], @@ -127,7 +134,7 @@ public class App { 这些变种代码将会作为技能树该知识点该代码选择题的选项。 -### 多行替换规则 +#### 多行替换规则 * 配置由`multiline`字段指定的多行替换数组 * 数组的每个元素是一组替换规则,会整组被替换 @@ -179,7 +186,7 @@ public class App { 这些变种代码将会作为技能树该知识点该代码选择题的选项。 -### 预制的替换规则 +#### 预制的替换规则 * 配置由 `prepared` 字段制定的预制文件数组 * 数组每一个元素是一个预制的代码文件的路径文件名 @@ -223,7 +230,125 @@ class App { } ``` +### 使用 markdown 编写习题 + +如前内容,我们在知识节点下增加一个习题配置,例如在 `data/1.Java初阶/1.Java概述/1.什么是Java` 下增加一个`HelloWorld.json`代码: + +```json +{ + "type": "code_options", + "author": "刘鑫", + "source": "HelloWorld.md", + "exercise_id":"1190bb7834904da0b1f20915960714d5", + "notebook_enable": true +} +``` +其中 type 字段目前都固定是 `code_options`。exercise_id 可以不写,处理程序会自动填补这个数据。根据具体情况写好其它字段,注意这里 source 的文件名,我们指定了一个 markdwon 文件。现在我们新建一个 HelloWorld.md 并编辑为: + +````markdown +# Hello World + + +以下 `Hello World` 程序中,能够正确输出内容的是: + +## 答案 + +```java + +public class App { + public static void main(String[] args){ + System.out.println("Hello World"); + } +} +``` + +## 选项 + +### A + +```java + +public class App { + public int main(){ + System.out.printf("Hello World"); + return 0; + } +} +``` + +### B + +```java + +public class App { + public static void main(String[] args){ + println("Hello World"); + } +} +``` + +### C + +```java +import stdout + +public class App { + public int main(){ + print("Hello World\n"); + return 0; + } +} + +``` + +```` + +这是一个最基本的习题结构,它包含标题、答案、选项,注意这几个一级和二级标题必须填写正确,解释器会读取这几个标题。而选项的标题会被直接忽略掉,在 +最终生成的习题中不包含选项的三级标题,所以这个标题可以用来标注一些编辑信息,例如“此选项没有关闭文件连接”,“类型错误”等等。 + +### 增强信息 + +为了编写习题和生成 notebook 的需要,markdown 解释器支持两种模板能力,如果我们在答案之前,有一个名为 aop 的二级标题: + +````markdown + +## aop + +### before + +```java +System.out.print("hello world"); +``` + +### after + +```java +App.main(new String[]{}); +``` +```` + +那么在创建notebook的时候,before 会插入到源代码前一个单元,after 则会插入到源代码后。aop 章节可以只包含 before 或 after 中的某一个,也可以两个都有。 + +另一些情况下,我们可能需要把各个选项中重复的代码提取出来,建立一个模板,此时可以在答案之前建立一个名为 template 的二级标题,例如: + +````markdwon + +## template + +```java +public class App { + public static void main(String[] args){ + // 下面的 code 占位符会被替换成答案和选项代码 + $code + } +} +``` + +```` + +注意这里的代码中,有一个 `$code` 占位符,它在管道程序处理过程中,会替换成答案和个选项内容中的代码。 +在后续的数据处理流程中,markdown 会被编译为 prepared 类型的习题。 ## 技能树合成 diff --git "a/data/1.Java\345\210\235\351\230\266/21.XML/config.json" "b/data/1.Java\345\210\235\351\230\266/21.XML/config.json" deleted file mode 100644 index f6416a1a57a86a638c71ad1c8742a38349a88fe3..0000000000000000000000000000000000000000 --- "a/data/1.Java\345\210\235\351\230\266/21.XML/config.json" +++ /dev/null @@ -1,6 +0,0 @@ -{ - "node_id": "569d5e11c4fc5de7844053d9a733c5e8", - "keywords": [], - "children": [], - "export": [] -} \ No newline at end of file diff --git "a/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/1.\344\273\200\344\271\210\346\230\257JDK/config.json" "b/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/1.\344\273\200\344\271\210\346\230\257JDK/config.json" deleted file mode 100644 index f6416a1a57a86a638c71ad1c8742a38349a88fe3..0000000000000000000000000000000000000000 --- "a/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/1.\344\273\200\344\271\210\346\230\257JDK/config.json" +++ /dev/null @@ -1,6 +0,0 @@ -{ - "node_id": "569d5e11c4fc5de7844053d9a733c5e8", - "keywords": [], - "children": [], - "export": [] -} \ No newline at end of file diff --git "a/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/2.\345\256\211\350\243\205JDK/config.json" "b/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/2.\345\256\211\350\243\205JDK/config.json" deleted file mode 100644 index f6416a1a57a86a638c71ad1c8742a38349a88fe3..0000000000000000000000000000000000000000 --- "a/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/2.\345\256\211\350\243\205JDK/config.json" +++ /dev/null @@ -1,6 +0,0 @@ -{ - "node_id": "569d5e11c4fc5de7844053d9a733c5e8", - "keywords": [], - "children": [], - "export": [] -} \ No newline at end of file diff --git "a/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/3.JDK\347\233\256\345\275\225\344\273\213\347\273\215/config.json" "b/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/3.JDK\347\233\256\345\275\225\344\273\213\347\273\215/config.json" deleted file mode 100644 index f6416a1a57a86a638c71ad1c8742a38349a88fe3..0000000000000000000000000000000000000000 --- "a/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/3.JDK\347\233\256\345\275\225\344\273\213\347\273\215/config.json" +++ /dev/null @@ -1,6 +0,0 @@ -{ - "node_id": "569d5e11c4fc5de7844053d9a733c5e8", - "keywords": [], - "children": [], - "export": [] -} \ No newline at end of file diff --git "a/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/config.json" "b/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/config.json" deleted file mode 100644 index f6416a1a57a86a638c71ad1c8742a38349a88fe3..0000000000000000000000000000000000000000 --- "a/data/1.Java\345\210\235\351\230\266/23.JDK\347\232\204\344\275\277\347\224\250/config.json" +++ /dev/null @@ -1,6 +0,0 @@ -{ - "node_id": "569d5e11c4fc5de7844053d9a733c5e8", - "keywords": [], - "children": [], - "export": [] -} \ No newline at end of file