Просмотр исходного кода

Merge pull request #1060 from bmkiefer/markdown-add-to-track

markdown: add to track
Stuart Kent 8 лет назад
Родитель
Сommit
18d82f291b
Аккаунт пользователя с таким Email не найден

+ 13
- 0
config.json Просмотреть файл

@@ -941,6 +941,19 @@
941 941
     {
942 942
       "core": false,
943 943
       "difficulty": 7,
944
+      "slug": "markdown",
945
+      "topics": [
946
+        "strings",
947
+        "conditionals",
948
+        "pattern_matching",
949
+        "refactoring"
950
+      ],
951
+      "unlocked_by": "scrabble-score",
952
+      "uuid": "cc18f2e5-4e36-47d6-aa60-8ca5ff54019a"
953
+    },
954
+    {
955
+      "core": false,
956
+      "difficulty": 7,
944 957
       "slug": "poker",
945 958
       "topics": [
946 959
         "games",

+ 96
- 0
exercises/markdown/.meta/src/reference/java/Markdown.java Просмотреть файл

@@ -0,0 +1,96 @@
1
+class Markdown {
2
+    
3
+    String parse(String markdown) {
4
+        String[] lines = markdown.split("\n");
5
+        StringBuilder result = new StringBuilder();
6
+        boolean activeList = false;
7
+
8
+        for (int i = 0; i < lines.length; i++) {
9
+            String lineResult = parseLine(lines[i]);
10
+
11
+            if (lineResult.matches("(<li>).*") && !activeList) {
12
+                activeList = true;
13
+                result.append("<ul>");
14
+                result.append(lineResult);
15
+            } else if (!lineResult.matches("(<li>).*") && activeList) {
16
+                activeList = false;
17
+                result.append("</ul>");
18
+                result.append(lineResult);
19
+            } else {
20
+                result.append(lineResult);
21
+            }
22
+        }
23
+
24
+        if (activeList) {
25
+            result.append("</ul>");
26
+        }
27
+
28
+        return result.toString();
29
+    }
30
+
31
+    private String parseLine(String markdown) {
32
+        String result = parseHeader(markdown);
33
+
34
+        if (result == null) {
35
+            result = parseListItem(markdown);
36
+        }
37
+
38
+        if (result == null) {
39
+            result = parseParagraph(markdown);
40
+        }
41
+
42
+        return result;
43
+    }
44
+
45
+    private String parseHeader(String markdown) {
46
+        int count = 0;
47
+
48
+        for (int i = 0; i < markdown.length(); i++) {
49
+            if (markdown.charAt(i) == '#') {
50
+                count++;
51
+            } else {
52
+                break;
53
+            }
54
+        }
55
+
56
+        if (count == 0) {
57
+            return null;
58
+        }
59
+
60
+        return wrap(markdown.substring(count + 1), "h" + Integer.toString(count));
61
+    }
62
+
63
+    private String parseListItem(String markdown) {
64
+        if (markdown.startsWith("*")) {
65
+            return wrap(parseText(markdown.substring(2)), "li");
66
+        }
67
+
68
+        return null;
69
+    }
70
+
71
+    private String parseParagraph(String markdown) {
72
+        return wrap(parseText(markdown), "p");
73
+    }
74
+
75
+    private String parseText(String markdown) {
76
+        return parseUnderscore(parseDoubleUnderscore(markdown));
77
+    }
78
+
79
+    private String parseUnderscore(String markdown) {
80
+        return parseViaRegex(markdown, "_", "em");
81
+    }
82
+
83
+    private String parseDoubleUnderscore(String markdown) {
84
+        return parseViaRegex(markdown, "__", "strong");
85
+    }
86
+
87
+    private String parseViaRegex(String markdown, String delimiter, String tag) {
88
+        String pattern = delimiter + "(.+)" + delimiter;
89
+        String replacement = wrap("$1", tag);
90
+        return markdown.replaceAll(pattern, replacement);
91
+    }
92
+
93
+    private String wrap(String text, String tag) {
94
+        return "<" + tag + ">" + text + "</" + tag + ">";
95
+    }
96
+}

+ 1
- 0
exercises/markdown/.meta/version Просмотреть файл

@@ -0,0 +1 @@
1
+1.1.0

+ 30
- 0
exercises/markdown/README.md Просмотреть файл

@@ -0,0 +1,30 @@
1
+# Markdown
2
+
3
+Refactor a Markdown parser.
4
+
5
+The markdown exercise is a refactoring exercise. There is code that parses a
6
+given string with [Markdown
7
+syntax](https://guides.github.com/features/mastering-markdown/) and returns the
8
+associated HTML for that string. Even though this code is confusingly written
9
+and hard to follow, somehow it works and all the tests are passing! Your
10
+challenge is to re-write this code to make it easier to read and maintain
11
+while still making sure that all the tests keep passing.
12
+
13
+It would be helpful if you made notes of what you did in your refactoring in
14
+comments so reviewers can see that, but it isn't strictly necessary. The most
15
+important thing is to make the code better!
16
+
17
+# Running the tests
18
+
19
+You can run all the tests for an exercise by entering
20
+
21
+```sh
22
+$ gradle test
23
+```
24
+
25
+in your terminal.
26
+
27
+
28
+## Submitting Incomplete Solutions
29
+
30
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.

+ 18
- 0
exercises/markdown/build.gradle Просмотреть файл

@@ -0,0 +1,18 @@
1
+apply plugin: "java"
2
+apply plugin: "eclipse"
3
+apply plugin: "idea"
4
+
5
+repositories {
6
+    mavenCentral()
7
+}
8
+
9
+dependencies {
10
+    testCompile "junit:junit:4.12"
11
+}
12
+
13
+test {
14
+    testLogging {
15
+        exceptionFormat = 'full'
16
+        events = ["passed", "failed", "skipped"]
17
+    }
18
+}

+ 83
- 0
exercises/markdown/src/main/java/Markdown.java Просмотреть файл

@@ -0,0 +1,83 @@
1
+class Markdown {
2
+  
3
+    String parse(String markdown) {
4
+
5
+        String[] lines = markdown.split("\n");
6
+
7
+        String result = "";
8
+
9
+        boolean activeList = false;
10
+
11
+        for (int i = 0; i < lines.length; i++) {
12
+
13
+            String theLine = parseHeader(lines[i]);
14
+          
15
+            if (theLine == null) {
16
+              theLine = parseListItem(lines[i]);
17
+            }
18
+    
19
+            if (theLine == null) 
20
+            {
21
+                theLine = parseParagraph(lines[i]);
22
+            }
23
+
24
+            if (theLine.matches("(<li>).*") && !theLine.matches("(<h).*") && !theLine.matches("(<p>).*") && !activeList) {
25
+                activeList = true;
26
+              result = result + "<ul>";
27
+                result = result + theLine;
28
+            } 
29
+            
30
+            else if (!theLine.matches("(<li>).*") && activeList) {
31
+                activeList = false;
32
+                result = result + "</ul>";
33
+                result = result + theLine;
34
+            } else {
35
+              result = result + theLine;
36
+            }
37
+        }
38
+
39
+        if (activeList) {
40
+            result = result + "</ul>";
41
+        }
42
+
43
+        return result;
44
+    }
45
+
46
+    private String parseHeader(String markdown) {
47
+        int count = 0;
48
+
49
+        for (int i = 0; i < markdown.length() && markdown.charAt(i) == '#'; i++) 
50
+        {
51
+            count++;
52
+        }
53
+
54
+        if (count == 0) { return null; }
55
+
56
+        return "<h" + Integer.toString(count) + ">" + markdown.substring(count + 1) + "</h" + Integer.toString(count)+ ">";
57
+    }
58
+
59
+    private String parseListItem(String markdown) {
60
+        if (markdown.startsWith("*")) {
61
+            String skipAsterisk = markdown.substring(2);
62
+            String listItemString = parseSomeSymbols(skipAsterisk);
63
+            return "<li>" + listItemString + "</li>";
64
+        }
65
+
66
+        return null;
67
+    }
68
+
69
+    private String parseParagraph(String markdown) {
70
+        return "<p>" + parseSomeSymbols(markdown) + "</p>";
71
+    }
72
+
73
+    private String parseSomeSymbols(String markdown) {
74
+
75
+        String lookingFor = "__(.+)__";
76
+        String update = "<strong>$1</strong>";
77
+        String workingOn = markdown.replaceAll(lookingFor, update);
78
+
79
+        lookingFor = "_(.+)_";
80
+        update = "<em>$1</em>";
81
+        return workingOn.replaceAll(lookingFor, update);
82
+    }
83
+}

+ 95
- 0
exercises/markdown/src/test/java/MarkdownTest.java Просмотреть файл

@@ -0,0 +1,95 @@
1
+import org.junit.Before;
2
+import org.junit.Ignore;
3
+import org.junit.Test;
4
+
5
+import static org.junit.Assert.assertEquals;
6
+
7
+public class MarkdownTest {
8
+
9
+    private Markdown markdown;
10
+
11
+    @Before
12
+    public void setup() {
13
+        markdown = new Markdown();
14
+    }
15
+
16
+    @Test
17
+    public void normalTextAsAParagraph() {
18
+        String input = "This will be a paragraph";
19
+        String expected = "<p>This will be a paragraph</p>";
20
+
21
+        assertEquals(expected, markdown.parse(input));
22
+    }
23
+
24
+    @Ignore("Remove to run test")
25
+    @Test
26
+    public void italics() {
27
+        String input = "_This will be italic_";
28
+        String expected = "<p><em>This will be italic</em></p>";
29
+
30
+        assertEquals(expected, markdown.parse(input));
31
+    }
32
+
33
+    @Ignore("Remove to run test")
34
+    @Test
35
+    public void boldText() {
36
+        String input = "__This will be bold__";
37
+        String expected = "<p><strong>This will be bold</strong></p>";
38
+
39
+        assertEquals(expected, markdown.parse(input));
40
+    }
41
+
42
+    @Ignore("Remove to run test")
43
+    @Test
44
+    public void normalItalicsAndBoldText() {
45
+        String input = "This will _be_ __mixed__";
46
+        String expected = "<p>This will <em>be</em> <strong>mixed</strong></p>";
47
+
48
+        assertEquals(expected, markdown.parse(input));
49
+    }
50
+
51
+    @Ignore("Remove to run test")
52
+    @Test
53
+    public void withH1HeaderLevel() {
54
+        String input = "# This will be an h1";
55
+        String expected = "<h1>This will be an h1</h1>";
56
+
57
+        assertEquals(expected, markdown.parse(input));
58
+    }
59
+
60
+    @Ignore("Remove to run test")
61
+    @Test
62
+    public void withH2HeaderLevel() {
63
+        String input = "## This will be an h2";
64
+        String expected = "<h2>This will be an h2</h2>";
65
+
66
+        assertEquals(expected, markdown.parse(input));
67
+    }
68
+
69
+    @Ignore("Remove to run test")
70
+    @Test
71
+    public void withH6HeaderLevel() {
72
+        String input = "###### This will be an h6";
73
+        String expected = "<h6>This will be an h6</h6>";
74
+
75
+        assertEquals(expected, markdown.parse(input));
76
+    }
77
+
78
+    @Ignore("Remove to run test")
79
+    @Test
80
+    public void unorderedLists() {
81
+        String input = "* Item 1\n* Item 2";
82
+        String expected = "<ul><li>Item 1</li><li>Item 2</li></ul>";
83
+
84
+        assertEquals(expected, markdown.parse(input));
85
+    }
86
+
87
+    @Ignore("Remove to run test")
88
+    @Test
89
+    public void aLittleBitOfEverything() {
90
+        String input = "# Header!\n* __Bold Item__\n* _Italic Item_";
91
+        String expected = "<h1>Header!</h1><ul><li><strong>Bold Item</strong></li><li><em>Italic Item</em></li></ul>";
92
+
93
+        assertEquals(expected, markdown.parse(input));
94
+    }
95
+}

+ 1
- 0
exercises/settings.gradle Просмотреть файл

@@ -39,6 +39,7 @@ include 'largest-series-product'
39 39
 include 'linked-list'
40 40
 include 'list-ops'
41 41
 include 'luhn'
42
+include 'markdown'
42 43
 include 'matrix'
43 44
 include 'meetup'
44 45
 include 'minesweeper'