Skip to content

Commit b3a9a1e

Browse files
committed
Properly parse and render tables
1 parent 7da5437 commit b3a9a1e

8 files changed

Lines changed: 101 additions & 91 deletions

File tree

07_robot.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{{meta {chap_num: 7, prev_link: 06_object, next_link: 08_error, load_files: ["code/chapter/07_robot.js", "code/animatevillage.js"], zip: html}}}
22

3-
# Project: The Robot
3+
# Project: A Robot
44

55
{{quote {author: "Edsger Dijkstra", title: "The Threats to Computing Science", chapter: true}
66

09_regexp.md

Lines changed: 72 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44

55
{{quote {author: "Jamie Zawinski", chapter: true}
66

7-
Some people, when confronted with a
8-
problem, think ‘I know, I'll use regular expressions.’ Now they have
9-
two problems.
7+
Some people, when confronted with a problem, think ‘I know, I'll use
8+
regular expressions.’ Now they have two problems.
109

1110
quote}}
1211

@@ -24,11 +23,11 @@ if}}
2423

2524
{{index "Zawinski, Jamie", evolution, adoption, integration}}
2625

27-
Programming
28-
((tool))s and techniques survive and spread in a chaotic, evolutionary
29-
way. It's not always the pretty or brilliant ones that win but rather
30-
the ones that function well enough within the right niche—for example,
31-
by being integrated with another successful piece of technology.
26+
Programming ((tool))s and techniques survive and spread in a chaotic,
27+
evolutionary way. It's not always the pretty or brilliant ones that
28+
win but rather the ones that function well enough within the right
29+
niche—for example, by being integrated with another successful piece
30+
of technology.
3231

3332
{{index "domain-specific language"}}
3433

@@ -57,8 +56,8 @@ written as a literal value by enclosing the pattern in forward slash
5756
(`/`) characters.
5857

5958
```
60-
var re1 = new RegExp("abc");
61-
var re2 = /abc/;
59+
let re1 = new RegExp("abc");
60+
let re2 = /abc/;
6261
```
6362

6463
Both of these regular expression objects represent the same
@@ -84,7 +83,7 @@ expressions and must be preceded by a backslash if they are meant to
8483
represent the character itself.
8584

8685
```
87-
var eighteenPlus = /eighteen\+/;
86+
let eighteenPlus = /eighteen\+/;
8887
```
8988

9089
Knowing precisely what characters to backslash-escape when writing
@@ -121,10 +120,9 @@ start), `test` will return `true`.
121120

122121
{{index "regular expression", "indexOf method"}}
123122

124-
Finding out whether a
125-
string contains _abc_ could just as well be done with a call to
126-
`indexOf`. Regular expressions allow us to go beyond that and express
127-
more complicated ((pattern))s.
123+
Finding out whether a string contains _abc_ could just as well be done
124+
with a call to `indexOf`. Regular expressions allow us to express more
125+
complicated ((pattern))s.
128126

129127
Say we want to match any ((number)). In a regular expression, putting
130128
a ((set)) of characters between square brackets makes that part of the
@@ -156,22 +154,21 @@ same thing as `[0-9]`.
156154

157155
{{index "newline character"}}
158156

159-
[cols="1,5"]
160-
|====
161-
|`\d` |Any ((digit)) character
162-
|`\w` |An alphanumeric character (“((word character))”)
163-
|`\s` |Any ((whitespace)) character (space, tab, newline, and similar)
164-
|`\D` |A character that is _not_ a digit
165-
|`\W` |A nonalphanumeric character
166-
|`\S` |A nonwhitespace character
167-
|`.` |Any character except for newline
168-
|====
157+
{{table {cols: [1, 5]}}}
158+
159+
`\d` | Any ((digit)) character
160+
`\w` | An alphanumeric character (“((word character))”)
161+
`\s` | Any ((whitespace)) character (space, tab, newline, and similar)
162+
`\D` | A character that is _not_ a digit
163+
`\W` | A nonalphanumeric character
164+
`\S` | A nonwhitespace character
165+
`.` | Any character except for newline
169166

170167
So you could match a ((date)) and ((time)) format like 30-01-2003
171168
15:20 with the following expression:
172169

173170
```
174-
var dateTime = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/;
171+
let dateTime = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/;
175172
console.log(dateTime.test("30-01-2003 15:20"));
176173
// → true
177174
console.log(dateTime.test("30-jan-2003 15:20"));
@@ -203,7 +200,7 @@ character _except_ the ones in the set—you can write a caret (`^`)
203200
character after the opening bracket.
204201

205202
```
206-
var notBinary = /[^01]/;
203+
let notBinary = /[^01]/;
207204
console.log(notBinary.test("1100100010100110"));
208205
// → false
209206
console.log(notBinary.test("1100100010200110"));
@@ -251,7 +248,7 @@ occur zero or one time. In the following example, the _u_ character
251248
is allowed to occur, but the pattern also matches when it is missing.
252249

253250
```
254-
var neighbor = /neighbou?r/;
251+
let neighbor = /neighbou?r/;
255252
console.log(neighbor.test("neighbour"));
256253
// → true
257254
console.log(neighbor.test("neighbor"));
@@ -272,7 +269,7 @@ allows both single- and double-((digit)) days, months, and hours. It
272269
is also slightly more readable.
273270

274271
```
275-
var dateTime = /\d{1,2}-\d{1,2}-\d{4} \d{1,2}:\d{2}/;
272+
let dateTime = /\d{1,2}-\d{1,2}-\d{4} \d{1,2}:\d{2}/;
276273
console.log(dateTime.test("30-1-2003 8:45"));
277274
// → true
278275
```
@@ -292,7 +289,7 @@ as a single element as far as the operators following it are
292289
concerned.
293290

294291
```
295-
var cartoonCrying = /boo+(hoo+)+/i;
292+
let cartoonCrying = /boo+(hoo+)+/i;
296293
console.log(cartoonCrying.test("Boohoooohoohooo"));
297294
// → true
298295
```
@@ -322,7 +319,7 @@ match was found and return an object with information about the match
322319
otherwise.
323320

324321
```
325-
var match = /\d+/.exec("one two 100");
322+
let match = /\d+/.exec("one two 100");
326323
console.log(match);
327324
// → ["100"]
328325
console.log(match.index);
@@ -358,7 +355,7 @@ matched by the first group (the one whose opening parenthesis comes
358355
first in the expression), then the second group, and so on.
359356

360357
```
361-
var quotedText = /'([^']*)'/;
358+
let quotedText = /'([^']*)'/;
362359
console.log(quotedText.exec("she said 'hello'"));
363360
// → ["'hello'", "hello"]
364361
```
@@ -462,8 +459,8 @@ object from a string.
462459

463460
```
464461
function findDate(string) {
465-
var dateTime = /(\d{1,2})-(\d{1,2})-(\d{4})/;
466-
var match = dateTime.exec(string);
462+
let dateTime = /(\d{1,2})-(\d{1,2})-(\d{4})/;
463+
let match = dateTime.exec(string);
467464
return new Date(Number(match[3]),
468465
Number(match[2]) - 1,
469466
Number(match[1]));
@@ -528,7 +525,7 @@ there is a nicer way. The ((pipe character)) (`|`) denotes a
528525
right. So I can say this:
529526

530527
```
531-
var animalCount = /\b\d+ (pig|cow|chicken)s?\b/;
528+
let animalCount = /\b\d+ (pig|cow|chicken)s?\b/;
532529
console.log(animalCount.test("15 pigs"));
533530
// → true
534531
console.log(animalCount.test("15 pigchickens"));
@@ -742,7 +739,7 @@ arguments, and its return value will be inserted into the new string.
742739
Here's a simple example:
743740

744741
```
745-
var s = "the cia and fbi";
742+
let s = "the cia and fbi";
746743
console.log(s.replace(/\b(fbi|cia)\b/g, function(str) {
747744
return str.toUpperCase();
748745
}));
@@ -752,7 +749,7 @@ console.log(s.replace(/\b(fbi|cia)\b/g, function(str) {
752749
And here's a more interesting one:
753750

754751
```
755-
var stock = "1 lemon, 2 cabbages, and 101 eggs";
752+
let stock = "1 lemon, 2 cabbages, and 101 eggs";
756753
function minusOne(match, amount, unit) {
757754
amount = Number(amount) - 1;
758755
if (amount == 1) // only one left, remove the 's'
@@ -858,9 +855,9 @@ But you can build up a string and use the `RegExp` ((constructor)) on
858855
that. Here's an example:
859856

860857
```
861-
var name = "harry";
862-
var text = "Harry is a suspicious character.";
863-
var regexp = new RegExp("\\b(" + name + ")\\b", "gi");
858+
let name = "harry";
859+
let text = "Harry is a suspicious character.";
860+
let regexp = new RegExp("\\b(" + name + ")\\b", "gi");
864861
console.log(text.replace(regexp, "_$1_"));
865862
// → _Harry_ is a suspicious character.
866863
```
@@ -887,10 +884,10 @@ have a special meaning. But escaping everything that's not
887884
alphanumeric or ((whitespace)) is safe.
888885

889886
```
890-
var name = "dea+hl[]rd";
891-
var text = "This dea+hl[]rd guy is super annoying.";
892-
var escaped = name.replace(/[^\w\s]/g, "\\$&");
893-
var regexp = new RegExp("\\b(" + escaped + ")\\b", "gi");
887+
let name = "dea+hl[]rd";
888+
let text = "This dea+hl[]rd guy is super annoying.";
889+
let escaped = name.replace(/[^\w\s]/g, "\\$&");
890+
let regexp = new RegExp("\\b(" + escaped + ")\\b", "gi");
894891
console.log(text.replace(regexp, "_$1_"));
895892
// → This _dea+hl[]rd_ guy is super annoying.
896893
```
@@ -942,9 +939,9 @@ would have been to just allow an extra argument to be passed to
942939
regular expression interface.
943940

944941
```
945-
var pattern = /y/g;
942+
let pattern = /y/g;
946943
pattern.lastIndex = 3;
947-
var match = pattern.exec("xyzzy");
944+
let match = pattern.exec("xyzzy");
948945
console.log(match.index);
949946
// → 4
950947
console.log(pattern.lastIndex);
@@ -967,7 +964,7 @@ cause problems. Your regular expression might be accidentally starting
967964
at an index that was left over from a previous call.
968965

969966
```
970-
var digit = /\d/g;
967+
let digit = /\d/g;
971968
console.log(digit.exec("here it is: 1"));
972969
// → ["1"]
973970
console.log(digit.exec("and now: 1"));
@@ -1003,9 +1000,9 @@ that gives us access to the match object in the loop body, by using
10031000
`lastIndex` and `exec`.
10041001

10051002
```
1006-
var input = "A string with 3 numbers in it... 42 and 88.";
1007-
var number = /\b(\d+)\b/g;
1008-
var match;
1003+
let input = "A string with 3 numbers in it... 42 and 88.";
1004+
let number = /\b(\d+)\b/g;
1005+
let match;
10091006
while (match = number.exec(input))
10101007
console.log("Found", match[1], "at", match.index);
10111008
// → Found 3 at 14
@@ -1086,11 +1083,11 @@ in a way that allows both `"\n"` and `"\r\n"` between lines.
10861083
```
10871084
function parseINI(string) {
10881085
// Start with an object to hold the top-level fields
1089-
var currentSection = {name: null, fields: []};
1090-
var categories = [currentSection];
1086+
let currentSection = {name: null, fields: []};
1087+
let categories = [currentSection];
10911088
10921089
string.split(/\r?\n/).forEach(function(line) {
1093-
var match;
1090+
let match;
10941091
if (/^\s*(;.*)?$/.test(line)) {
10951092
return;
10961093
} else if (match = line.match(/^\[(.*)\]$/)) {
@@ -1183,27 +1180,26 @@ unfortunately looks like they won't be realized in the near ((future)).
11831180
Regular expressions are objects that represent patterns in strings.
11841181
They use their own syntax to express these patterns.
11851182

1186-
[cols="1,5"]
1187-
|====
1188-
|`/abc/` |A sequence of characters
1189-
|`/[abc]/` |Any character from a set of characters
1190-
|`/[^abc]/` |Any character _not_ in a set of characters
1191-
|`/[0-9]/` |Any character in a range of characters
1192-
|`/x+/` |One or more occurrences of the pattern `x`
1193-
|`/x+?/` |One or more occurrences, nongreedy
1194-
|`/x*/` |Zero or more occurrences
1195-
|`/x?/` |Zero or one occurrence
1196-
|`/x{2,4}/` |Between two and four occurrences
1197-
|`/(abc)/` |A group
1198-
|_/a{brvbar}b{brvbar}c/_ |Any one of several patterns
1199-
|`/\d/` |Any digit character
1200-
|`/\w/` |An alphanumeric character (“word character”)
1201-
|`/\s/` |Any whitespace character
1202-
|`/./` |Any character except newlines
1203-
|`/\b/` |A word boundary
1204-
|`/^/` |Start of input
1205-
|`/$/` |End of input
1206-
|====
1183+
{{table {cols: [1, 5]}}}
1184+
1185+
`/abc/` | A sequence of characters
1186+
`/[abc]/` | Any character from a set of characters
1187+
`/[^abc]/` | Any character _not_ in a set of characters
1188+
`/[0-9]/` | Any character in a range of characters
1189+
`/x+/` | One or more occurrences of the pattern `x`
1190+
`/x+?/` | One or more occurrences, nongreedy
1191+
`/x*/` | Zero or more occurrences
1192+
`/x?/` | Zero or one occurrence
1193+
`/x{2,4}/` | Between two and four occurrences
1194+
`/(abc)/` | A group
1195+
`/a|b|c/` | Any one of several patterns
1196+
`/\d/` | Any digit character
1197+
`/\w/` | An alphanumeric character (“word character”)
1198+
`/\s/` | Any whitespace character
1199+
`/./` | Any character except newlines
1200+
`/\b/` | A word boundary
1201+
`/^/` | Start of input
1202+
`/$/` | End of input
12071203

12081204
A regular expression has a method `test` to test whether a given
12091205
string matches it. It also has an `exec` method that, when a match is
@@ -1341,7 +1337,7 @@ does the proper replacement.
13411337

13421338
{{if interactive
13431339
```{test: no}
1344-
var text = "'I'm the cook,' he said, 'it's my job.'";
1340+
let text = "'I'm the cook,' he said, 'it's my job.'";
13451341
// Change this call.
13461342
console.log(text.replace(/A/g, "B"));
13471343
// → "I'm the cook," he said, "it's my job."
@@ -1388,7 +1384,7 @@ are valid JavaScript numbers, but a lone dot _isn't_.
13881384
{{if interactive
13891385
```{test: no}
13901386
// Fill in this regular expression.
1391-
var number = /^...$/;
1387+
let number = /^...$/;
13921388
13931389
// Tests:
13941390
["1", "-1", "+15", "1.55", ".5", "5.", "1.3e2", "1E-4",

18_forms.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,13 @@ field's style. These are some commonly used `<input>` types:
4545

4646
{{index "password field", checkbox, "radio button", "file field"}}
4747

48-
[cols="1,5"]
49-
|====
50-
|`text` |A single-line ((text field))
51-
|`password`|Same as `text` but hides the text that is typed
52-
|`checkbox`|An on/off switch
53-
|`radio` |(Part of) a ((multiple-choice)) field
54-
|`file` |Allows the user to choose a file from their computer
55-
|====
48+
{{table {cols: [1,5]}}}
49+
50+
`text` | A single-line ((text field))
51+
`password` | Same as `text` but hides the text that is typed
52+
`checkbox` | An on/off switch
53+
`radio` | (Part of) a ((multiple-choice)) field
54+
`file` | Allows the user to choose a file from their computer
5655

5756
{{index "value attribute", "checked attribute", "form (HTML tag)"}}
5857

html/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ <h3>(Part 1: Language)</h3>
6464
<li><a href="04_data.html">Data Structures: Objects and Arrays</a>
6565
<li><a href="05_higher_order.html">Higher-order Functions</a>
6666
<li><a href="06_object.html">The Secret Life of Objects</a>
67-
<li><a href="07_robot.html">Project: The Robot</a>
67+
<li><a href="07_robot.html">Project: A Robot</a>
6868
<li><a href="08_error.html">Bugs and Errors</a>
6969
<li><a href="09_regexp.html">Regular Expressions</a>
7070
<li><a href="10_modules.html">Modules</a>

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"markdown-it": "^8.4.0",
1717
"markdown-it-sub": "^1.0.0",
1818
"markdown-it-sup": "^1.0.0",
19+
"markdown-it-synapse-table": "^1.0.6",
1920
"mold-template": "^2.0.1",
2021
"uglify-js": "^2.0.0"
2122
},

src/markdown.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,4 @@ module.exports = markdownIt({html: true})
139139
.use(plugin)
140140
.use(require("markdown-it-sup"))
141141
.use(require("markdown-it-sub"))
142+
.use(require("markdown-it-synapse-table"))

0 commit comments

Comments
 (0)