Skip to content

Commit 09e19c4

Browse files
committed
Improve epub generation
* styling * inclusion of html-specific pieces, rather than raw LaTeX * hint chapter * colophon
1 parent d793cbc commit 09e19c4

32 files changed

Lines changed: 243 additions & 170 deletions

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
/img/generated/*
2020
/img/cover.xcf
2121
/epub/[012]*.xhtml
22+
/epub/hints.xhtml
2223
/epub/img/*
2324
/epub/content.opf
24-
/Eloquent_JavaScript.epub
25+
/book.epub

00_intro.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,12 +358,12 @@ in an actual JavaScript interpreter, to get immediate feedback on
358358
whether what you are doing is working or not, and, hopefully, to be
359359
tempted to ((experiment)) and go beyond the exercises.
360360

361-
ifdef::html_target[]
361+
ifdef::interactive_target[]
362362

363363
When reading this book in your browser, you can edit (and run) all
364364
example programs by clicking on them.
365365

366-
endif::html_target[]
366+
endif::interactive_target[]
367367

368368
ifdef::book_target[]
369369

02_program_structure.txt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,13 @@ but most browsers open it when you press F12 or, on Mac, when you
252252
press Command-Option-I. If that does not work, search through the
253253
menus for an item named “web console” or “developer tools”.
254254

255-
ifdef::html_target[]
255+
ifdef::interactive_target[]
256256

257257
When running the examples, or your own code, on the pages of this
258258
book, `console.log` output will be shown after the example, instead of
259259
in the browser's JavaScript console.
260260

261-
endif::html_target[]
261+
endif::interactive_target[]
262262

263263
[source,javascript]
264264
----
@@ -658,15 +658,15 @@ a condition that always produces `true`, your program would get stuck
658658
in an _((infinite loop))_. A program stuck in an infinite loop will
659659
never finish running, which is usually a bad thing.
660660

661-
ifdef::html_target[]
661+
ifdef::interactive_target[]
662662

663663
If you create an infinite loop in one of the examples on these pages,
664664
you'll usually be asked whether you want to stop the script after a
665665
few seconds. If that fails, you will have to close the tab that you're
666666
working in, or on some browsers close your whole browser, in order to
667667
recover.
668668

669-
endif::html_target[]
669+
endif::interactive_target[]
670670

671671
(((continue keyword)))The `continue` keyword is similar to `break`, in
672672
that it influences the progress of a loop. When `continue` is
@@ -866,7 +866,7 @@ exercises, refer to the end of the introduction.
866866

867867
Each exercise starts with a problem description. Read that and try to
868868
solve the exercise. If you run into problems, consider reading the
869-
hints (!html after the exercise!)(!book at the link:solutions[end of the book]!).
869+
hints (!interactive after the exercise!)(!book at the link:solutions[end of the book]!).
870870
Full solutions to the exercises are not included in this
871871
book, but you can find them online at
872872
http://eloquentjavascript.net/code[_eloquentjavascript.net/code_].
@@ -900,7 +900,7 @@ console.log(abc.length);
900900
// → 3
901901
----
902902

903-
ifdef::html_target[]
903+
ifdef::interactive_target[]
904904

905905
Most exercises contain a piece of code that you can modify to solve
906906
the exercise. Remember that you can click code blocks to edit them.
@@ -909,7 +909,7 @@ the exercise. Remember that you can click code blocks to edit them.
909909
----
910910
// Your code here.
911911
----
912-
endif::html_target[]
912+
endif::interactive_target[]
913913

914914
!!hint!!
915915

@@ -941,12 +941,12 @@ for numbers that are divisible by both 3 and 5.
941941
weed out a significant percentage of programmer candidates. So if you
942942
solved it, you're now allowed to feel good about yourself.)
943943

944-
ifdef::html_target[]
944+
ifdef::interactive_target[]
945945
[source,javascript]
946946
----
947947
// Your code here.
948948
----
949-
endif::html_target[]
949+
endif::interactive_target[]
950950

951951
!!hint!!
952952

@@ -993,12 +993,12 @@ When you have a program that generates this pattern, define a
993993
((variable)) `size = 8` and change the program so that it works for
994994
any `size`, outputting a grid of the given width and height.
995995

996-
ifdef::html_target[]
996+
ifdef::interactive_target[]
997997
[source,javascript]
998998
----
999999
// Your code here.
10001000
----
1001-
endif::html_target[]
1001+
endif::interactive_target[]
10021002

10031003
!!hint!!
10041004

03_functions.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,7 @@ introduced the standard function `Math.min` that returns its smallest
898898
argument. We can do that ourselves now. Write a function `min` that
899899
takes two arguments and returns their minimum.
900900

901-
ifdef::html_target[]
901+
ifdef::interactive_target[]
902902

903903
// test: no
904904

@@ -911,7 +911,7 @@ console.log(min(0, 10));
911911
console.log(min(0, -10));
912912
// → -10
913913
----
914-
endif::html_target[]
914+
endif::interactive_target[]
915915

916916
!!hint!!
917917

@@ -945,7 +945,7 @@ return a Boolean.
945945
(((stack overflow)))Test it on 50 and 75. See how it behaves on -1.
946946
Why? Can you think of a way to fix this?
947947

948-
ifdef::html_target[]
948+
ifdef::interactive_target[]
949949

950950
// test: no
951951

@@ -960,7 +960,7 @@ console.log(isEven(75));
960960
console.log(isEven(-1));
961961
// → ??
962962
----
963-
endif::html_target[]
963+
endif::interactive_target[]
964964

965965
!!hint!!
966966

@@ -1002,7 +1002,7 @@ except it takes a second argument that indicates the character that is
10021002
to be counted (rather than counting only uppercase "B" characters).
10031003
Rewrite `countBs` to make use of this new function.
10041004

1005-
ifdef::html_target[]
1005+
ifdef::interactive_target[]
10061006

10071007
// test: no
10081008

@@ -1015,7 +1015,7 @@ console.log(countBs("BBC"));
10151015
console.log(countChar("kakkerlak", "k"));
10161016
// → 4
10171017
----
1018-
endif::html_target[]
1018+
endif::interactive_target[]
10191019

10201020
!!hint!!
10211021

04_data.txt

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,8 @@ _ϕ_ can be computed using the following formula, where n refers to the table:
479479
ifdef::html_target[]
480480

481481
++++
482-
<style>sub { font-size: 60%; }</style>
482+
<div>
483+
<style scoped="scoped">sub { font-size: 60%; }</style>
483484
<table style="border-collapse: collapse; margin-left: 1em;"><tr>
484485
<td style="vertical-align: middle"><em>ϕ</em> =</td>
485486
<td style="padding-left: .5em">
@@ -489,30 +490,31 @@ ifdef::html_target[]
489490
</span></div>
490491
</td>
491492
</tr></table>
493+
</div>
492494
++++
493495

494496
endif::html_target[]
495497

496-
ifdef::book_target[]
498+
ifdef::tex_target[]
497499

498500
pass:[\begin{equation}\phi = \frac{n_{11}n_{00}-n_{10}n_{01}}{\sqrt{n_{1\bullet}n_{0\bullet}n_{\bullet1}n_{\bullet0}}}\end{equation}]
499501

500-
endif::book_target[]
502+
endif::tex_target[]
501503

502-
The notation (!html _n_~01~!)(!book pass:[$n_{01}$]!) indicates the
504+
The notation (!html _n_~01~!)(!tex pass:[$n_{01}$]!) indicates the
503505
number of measurements where the first measurement (pizza) is false
504506
(0) and the second measurement (squirrelness) is true (1). In this
505-
example, (!html _n_~01~!)(!book pass:[$n_{01}$]!) is 4.
507+
example, (!html _n_~01~!)(!tex pass:[$n_{01}$]!) is 4.
506508

507-
The value (!html _n_~1•~!)(!book pass:[$n_{1\bullet}$]!) refers to the
509+
The value (!html _n_~1•~!)(!tex pass:[$n_{1\bullet}$]!) refers to the
508510
sum of all measurements where the first variable is true, which is 10
509-
in the example table. Likewise, (!html _n_~•0~!)(!book pass:[$n_{\bullet0}$]!)
511+
in the example table. Likewise, (!html _n_~•0~!)(!tex pass:[$n_{\bullet0}$]!)
510512
refers to the sum of the measurements where the squirrel variable is false.
511513

512514
(((correlation)))(((phi coefficient)))So for the pizza table, the part
513515
above the division line (the dividend) would be 1×76 - 9×4 = 40, and
514516
the part below it (the divisor) would be the square root of
515-
10×80×5×85, or (!html √340000!)(!book pass:[$\sqrt{340000}$]!). This
517+
10×80×5×85, or (!html √340000!)(!tex pass:[$\sqrt{340000}$]!). This
516518
comes out to _ϕ_ ≈ 0.069, which is tiny. Eating ((pizza)) does not
517519
appear to have influence on the transformations.
518520

@@ -556,7 +558,7 @@ console.log(phi([76, 9, 4, 1]));
556558
translation of the _ϕ_ formula into JavaScript. `Math.sqrt` is the
557559
square root function, as provided by the `Math` object in a standard
558560
JavaScript environment. We have to sum two fields from the table to
559-
get fields like (!html n~1•~!)(!book pass:[$n_{1\bullet}$]!) because
561+
get fields like (!html n~1•~!)(!tex pass:[$n_{1\bullet}$]!) because
560562
the sums of rows or columns are not stored directly in our data
561563
structure.
562564

@@ -1186,7 +1188,7 @@ behavior. The function call `range(1, 10, 2)` should return `[1, 3, 5,
11861188
7, 9]`. Make sure it also works with negative step values so that
11871189
`range(5, 2, -1)` produces `[5, 4, 3, 2]`.
11881190

1189-
ifdef::html_target[]
1191+
ifdef::interactive_target[]
11901192

11911193
// test: no
11921194

@@ -1199,7 +1201,7 @@ console.log(sum(range(1, 10)));
11991201
console.log(range(5, 2, -1));
12001202
// → [5, 4, 3, 2]
12011203
----
1202-
endif::html_target[]
1204+
endif::interactive_target[]
12031205

12041206
!!hint!!
12051207

@@ -1249,7 +1251,7 @@ the notes about side effects and pure functions in the
12491251
link:03_functions.html#pure[previous chapter], which variant do you
12501252
expect to be useful in more situations? Which one is more efficient?
12511253

1252-
ifdef::html_target[]
1254+
ifdef::interactive_target[]
12531255

12541256
// test: no
12551257

@@ -1264,7 +1266,7 @@ reverseArrayInPlace(arrayValue);
12641266
console.log(arrayValue);
12651267
// → [5, 4, 3, 2, 1]
12661268
----
1267-
endif::html_target[]
1269+
endif::interactive_target[]
12681270

12691271
!!hint!!
12701272

@@ -1342,7 +1344,7 @@ is no such element.
13421344
(((recursion)))If you haven't already, also write a recursive version
13431345
of `nth`.
13441346

1345-
ifdef::html_target[]
1347+
ifdef::interactive_target[]
13461348

13471349
// test: no
13481350

@@ -1359,7 +1361,7 @@ console.log(prepend(10, prepend(20, null)));
13591361
console.log(nth(arrayToList([10, 20, 30]), 1));
13601362
// → 20
13611363
----
1362-
endif::html_target[]
1364+
endif::interactive_target[]
13631365

13641366
!!hint!!
13651367

@@ -1414,7 +1416,7 @@ it produces `"object"` for both values, you should do a deep
14141416
comparison. But you have to take one silly exception into account: by
14151417
a historical accident, `typeof null` also produces `"object"`.
14161418

1417-
ifdef::html_target[]
1419+
ifdef::interactive_target[]
14181420

14191421
// test: no
14201422

@@ -1430,7 +1432,7 @@ console.log(deepEqual(obj, {here: 1, object: 2}));
14301432
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
14311433
// → true
14321434
----
1433-
endif::html_target[]
1435+
endif::interactive_target[]
14341436

14351437
!!hint!!
14361438

05_higher_order.txt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
= Higher-Order Functions =
77

8-
ifdef::html_target[]
8+
ifdef::interactive_target[]
99

1010
[chapterquote="true"]
1111
[quote, Master Yuan-Ma, The Book of Programming]
@@ -18,7 +18,7 @@ Yuan-Ma said, ‘My best program has five hundred lines.’ Hearing this,
1818
Tzu-li and Tzu-ssu were enlightened.
1919
____
2020

21-
endif::html_target[]
21+
endif::interactive_target[]
2222

2323
[chapterquote="true"]
2424
[quote, C.A.R. Hoare, 1980 ACM Turing Award Lecture]
@@ -104,7 +104,7 @@ Soak peas for 12 hours. Simmer for 2 hours in 4 cups of water
104104
____
105105

106106
(((vocabulary)))The second is shorter and easier to interpret. But
107-
you do need to understand a few more cooking-related words—_soak_,
107+
you do need to understand a few more cooking-related words—__soak__,
108108
_simmer_, _chop_, and, I guess, _vegetable_.
109109

110110
When programming, we can't rely on all the words we need to be waiting
@@ -918,7 +918,7 @@ method)))(((array)))Use the `reduce` method in combination with
918918
the `concat` method to “flatten” an array of arrays into a single
919919
array that has all the elements of the input arrays.
920920

921-
ifdef::html_target[]
921+
ifdef::interactive_target[]
922922

923923
// test: no
924924

@@ -928,7 +928,7 @@ var arrays = [[1, 2, 3], [4, 5], [6]];
928928
// Your code here.
929929
// → [1, 2, 3, 4, 5, 6]
930930
----
931-
endif::html_target[]
931+
endif::interactive_target[]
932932

933933
=== Mother-child age difference ===
934934

@@ -944,7 +944,7 @@ are themselves present in the array. The `byName` object, which makes
944944
it easy to find a person's object from their name, might be useful
945945
here.
946946

947-
ifdef::html_target[]
947+
ifdef::interactive_target[]
948948

949949
// test: no
950950
// include_code
@@ -965,7 +965,7 @@ ancestry.forEach(function(person) {
965965

966966
// → 31.2
967967
----
968-
endif::html_target[]
968+
endif::interactive_target[]
969969

970970
!!hint!!
971971

@@ -994,7 +994,7 @@ in the ancestry data set per century. A person is assigned to a
994994
((century)) by taking their year of death, dividing it by 100,
995995
and rounding it up, as in `Math.ceil(person.died / 100)`.
996996

997-
ifdef::html_target[]
997+
ifdef::interactive_target[]
998998

999999
// test: no
10001000

@@ -1014,7 +1014,7 @@ function average(array) {
10141014
// 20: 84.7
10151015
// 21: 94
10161016
----
1017-
endif::html_target[]
1017+
endif::interactive_target[]
10181018

10191019
!!hint!!
10201020

@@ -1061,7 +1061,7 @@ Write two functions, `every` and `some`, that behave like these
10611061
methods, except that they take the array as their first argument
10621062
rather than being a method.
10631063

1064-
ifdef::html_target[]
1064+
ifdef::interactive_target[]
10651065

10661066
// test: no
10671067

@@ -1078,7 +1078,7 @@ console.log(some([NaN, 3, 4], isNaN));
10781078
console.log(some([2, 3, 4], isNaN));
10791079
// → false
10801080
----
1081-
endif::html_target[]
1081+
endif::interactive_target[]
10821082

10831083
!!hint!!
10841084

0 commit comments

Comments
 (0)