From ec37410bf1dbc80752f91dbc196429ff29bbfb67 Mon Sep 17 00:00:00 2001
From: Greg Wilson The configuration might not come directly from a JSON file—for example,
- it might be embedded in a larger file or generated by anothe prrogram—so
+ it might be embedded in a larger file or generated by another program—so
we should modify the constructor to take the loaded JSON configuration as input.Section 19.4: A Better Design
Section 3.1: Getting Started
-
@@ -539,7 +539,7 @@ aaa
-aaa
-aaa
-bb
-bb
-c
+
+aaa
+aaa
+aaa
+bb
+bb
c
Section 3.2: Hashing Files
but is it?
As a more stringent test,
let’s try hashing every line of text in
-Project Gutenberg‘s version of the novel Dracula
+the Project Gutenberg version of the novel Dracula
and plot the distribution (Figure 3.3).
Consider the bicycle–more specifically, +
Consider the bicycle: +more specifically, the De Rosa SK Pininfarina (Figure 27.1). I think it’s beautiful, but I wouldn’t call it art, diff --git a/docs/intro/index.html b/docs/intro/index.html index 0a5d45b3c..f53e64d70 100644 --- a/docs/intro/index.html +++ b/docs/intro/index.html @@ -559,7 +559,7 @@
This one’s for Mike and Jon:
- I’m glad you always found time to chat.
Our file fiewer has four classes (Figure 24.1):
+Our file viewer has four classes (Figure 24.1):
A Window
can draw lines and report its size.
Action
to have a .save
method
that tells the application whether or not to save this action.
-The default implemenation returns True
,
+The default implementation returns True
,
but we override it in Undo
to return False
:
class Undo(Action):
diff --git a/info/bibliography.bib b/info/bibliography.bib
index b79b872e1..e9c4d346a 100644
--- a/info/bibliography.bib
+++ b/info/bibliography.bib
@@ -29,7 +29,7 @@ @book{Brand1995
@book{Bentley1982,
author = {Jon Louis Bentley},
title = {Writing Efficient Programs},
- publisher = {Prentice Hall {PTR}},
+ publisher = {Prentice-Hall {PTR}},
year = {1982},
isbn = {978-0139702440}
}
diff --git a/info/glossary.yml b/info/glossary.yml
index 5f1bd770a..c37b31a0a 100644
--- a/info/glossary.yml
+++ b/info/glossary.yml
@@ -22,7 +22,7 @@
en:
term: abstract base class
def: >
- An [abstract_class](#abstract_class) from which the [class](#class)
+ An [abstract class](#abstract_class) from which the [class](#class)
in question is derived.
- key: abstract_class
@@ -1427,7 +1427,7 @@
full : JavaScript Object Notation
def: >
A way to represent data by combining basic values like numbers and
- character strings in [lists](#list) and [key/value](#dictionary)
+ character strings in [lists](#list) and [key-value](#dictionary)
structures. The acronym stands for "JavaScript Object Notation"; unlike
better-defined standards like [XML](#xml), it is unencumbered by a syntax
for comments or ways to define a [schema](#schema).
diff --git a/info/wordlist.txt b/info/wordlist.txt
index 404dd1683..c4c442b03 100644
--- a/info/wordlist.txt
+++ b/info/wordlist.txt
@@ -1,333 +1,619 @@
-ABCDEF
-ACM
-AST
-Andreas
-Aniche
-Bitwise
-Breakpoint
-Buildability
-CPUs
-CSV
-CTAN
-CamelCase
-Connor
-Cryptographic
-Ctrl
-DNS
-DOM
-Dataframes
-De
-Docstrings
-EJS
-Enforceability
-Extensibility
-Filesystem
-Fortran
-Fucci
-Gitlet
-Globals
-Globbing
-Glosario
-GrandChild
-Harrelson's
-Hermans
-Hoye
-HyperText
-JSON
-Kamin
-Kerievsky
-Kernighan
-Kohavi
-LaTeX
-LeftChild
-Licensor
-Licensor's
-Lifecycle
-Linearize
-Linters
-Liskov
-Loewy
-Lorgat
-Lorgat's
-MERCHANTABILITY
-Matcher
-Maël
-Meszaros
-Mixin
-NONINFRINGEMENT
-Nison
-Nison's
-NonCommercial
-Nystrom
-Nystrom's
-OLAP
-OLTP
-Oram
-PNG
-Panchekha
-Pavel
-Petre
-PicoSAT
-Pininfarina
-Polge
-Polge's
-Polymorphism
-Pre
-Prover
-Pythonic
-Recurse
-Reim's
-Reimplemented
-Reproducibility
-RightChild
-Runtime
-Ruten's
-SHA
-SIGSOFT's
-SVG
-Schon
-Sinel
-Snakemake
-TCP
-TLL
-Teardown
-Templated
-Thibault
-Tichy
-Tokenize
-Tokenizer
-Tokenizing
-UTF
-Unix's
-Unsatisfiable
-VM
-VM's
-Wasim
-Watchpoints
-YAML
-Yim
-Zeller's
-aaa
-abc
-abcx
+16-bit
+1970s
+19th
+2-digit
+2000s
+20th
+256-bit
+2nd
+3-bit
+32-bit
+4-letter
+4.anything
+4k
+64-bit
+64-character
+64k
+7-bit
+8-bit
+acknowledgments
acyclic
-analytics
-andreas
-aosa
+addison-wesley
+adilov
+affordance
+affordances
+akand
+alexapolsky
+alexey
+aliased
+aliasing
+all-in-one-file
+alvee
+andré
+andrén
+aniche
+annotating
+ansi
api
+apis
+apparently-random
+append
+appending
+appends
+application-specific
archiver
archivers
-ast
-attr
-attrs
-bb
-beq
+arpan
+as-is
+as-yet-unwritten
+ascii
+assembler
+asynchronous
+ats
+auto-completion
+automating
+bacchelli
+backspace-delete
+backward-compatible
+bahman
+base-10
+base-16
+bellini
+better-defined
+bibliography
+bidirectional
+big-endian
+big-oh
bitwise
-blockcol
+block-based
+boole
+boolean
breakpoint
+breakpoints
+browser-based
+browsers
brubeck
+brute-force
+buildability
+buildable
+built-in
+built-ins
+burak
bytecode
-cProfile
-chainmap
-chris
-christopher
-clarkes
-classdef
-cls
-combinatorial
+callable
+callout
+camelcase
+canino
+chunking
+circularity
+client-server
+closely-related
+co-author
+co-founder
+column-wise
+comma-separated
+command-line
+commonly-used
+compaction
+compacts
compatibilities
+compilers
composable
-config
-connor
-contrib
-cprofile
-cryptographic
+concatenate
+concatenates
+concatenating
+conditionals
+conery
+correa
+cpus
+crc
+cross-references
+cs
csv
ctan
-data's
+ctrl-c
+ctrl-x
+currently-visible
+curses-based
dataframe
-dataframe's
dataframes
+dataset
datasets
datatypes
-debugger's
-dep
-derosa
-df
-dir
+davide
+debugger
+debuggers
+decrement
+delete-in-place
+denominators
+dependencies
+depth-first
+devanagari
+dibernardo
+dictionary-based
+dictionary-like
+difficult-to-debug
disassembler
disassemblers
+disassembles
dns
+do-nothing
docstring
docstrings
-dom
-dracula
-dup
+dominguez
+double-precision
+double-quoted
+dozenth
+drumm
+dynamically
+e-book
+ece
ejs
-elif
-else's
-encodings
+end-of-line
endian
-eniac
-env
-eq
-evans
+endpoint
+enforceability
+enumeration
+equivalently
+error-handling
+error-prone
+ever-larger
+ex-or
+exception-based
+exclusions
expander
exponentiality
-expr
extensibility
+extensible
+falsy
+faq
+felienne
+file-backed
+filename
+filenames
filesystem
+filesystems
+firas
+fixed-size
fixme
-fs
-fullwidth
-func
-funcobj
-funcs
+flake8
+floating-point
+flowchart
+fortran
+four-digit
+four-part
+frameworks
+fraser
+fucci
+full-featured
+fully-functional
+general-purpose
+genever
+github
gitlet
globals
globbing
glosario
+gnu
+gorcenski
gutenberg
+guyer
+gvwilson
+hand-written
+harassment-free
harrelson
-hashlib
+hashes
+hashing-based
hennessy
-hippocratic
+hermans
+high-level
+higher-level
+histogram
+hoek
+hostname
+hostnames
hoye
html
+html-like
+html5
http
-img
-init
-interp
-io
-ip
+human-readable
+hypertext
+hyphens
+ieee
+implementations
+in-memory
+incremented
+infix
+initializes
+insertable
+installable
+instantiated
+instantiates
+insulting/derogatory
+inter-package
+interactively
+interchangeably
+interleaving
+internally-generated
+interoperability
+interpreter-based
+introspect
+invalidation
+invalidity
+isbn
isort
+iterating
+iterator
+iterators
itertools
-jekyll
-joseph
-jpg
+javascript
json
-julia
-len
+juanan
+juristo
+just-in-time
+kamin
+karimi
+karlton
+kaufmann
+kerievsky
+kernighan
+key-to-sequence
+key-value
+keystroke-processing
+kilobyte
+knock-on
+kohavi
+landy
+large-scale
+left-to-right
+lexical
+licensee
licensor
-lifecycle
+line-wrapping
+linearize
linter
linters
+linting
liskov
+literals
+little-endian
loewy
+log-structured
+long-lived
+lookup-and-call
lorgat
-mael
-marthas
-mary
+low-level
+lower-case
+lower-level
+machine-readable
+made-up
+mahmoodur
+maintainable
+maintainers
+mantissa
+markdown
+markku
+mass-produced
matcher
matchers
-methoddef
-michael
+maurício
+maël
+mccloy
+mcgraw-hill
+mejia
+memory-to-memory
+merchantability
+meszaros
+micro-steps
mimetypes
-mis
+mini-language
+mini-languages
+miras
mixin
-multibyte
-multiline
-multiway
-mx
-nc
-ncol
+modulo
+moosvi
+multi-bit
+multi-byte
+multi-dimensional
+multi-file
+multi-letter
+multi-part
+multi-site
+multi-way
+mutually-compatible
+name-to-class
+name-value
+naming-at-creation
+new-and-improved
+newline
+newlines
+newly-created
+ng
+nisan
nison
-nrow
-num
+no-one
+noam
+non-commercial
+non-compliance
+non-empty
+non-interactive
+non-latin
+non-negative
+non-text
+non-zero
+noninfringement
+now-familiar
+numerators
nystrom
+object-oriented
+off-by-one
+oivo
+okamoto
olap
oltp
-oop
-paige
+one-byte
+one-dimensional
+one-line
+one-off
+open-closed
+operand
+operands
+optimizations
+optionally
+or'd
+oram
+orderings
+out-of-date
panchekha
-param
+parent-child
+parsed
+parser
parsers
-patterson
-pavel
-perf
+parses
+part-way
+partially-completed
+partially-formed
+partially-generated
+pass-fail-error
+pereira
persistable
+petre
pexpect
php
picosat
+pininfarina
+pipe-and-filter
+placeholders
+platform-independent
+plauger
+plos
+plug-in
+png
+png-formatted
+point-to-point
+polge
polymorphism
-profiler
+portability
+post-condition
+post-conditions
+postfix
+pothole_case
+pre-commit
+pre-condition
+pre-conditions
+pre-existing
+precisely-formatted
+predefined
+prentice-hall
+previously-injected
+previously-read
+printable
+production-quality
+properly-nested
+prototyping
prover
-prover's
provers
-prr
-py
+pseudo-random
+ptr
pyfakefs
pytest
+python-specific
pythonic
-quadruply
-raymond
+quadruply-nested
+quick-fix
+rahman
+re-add
+re-create
+re-creates
+re-defining
+re-draw
+re-match
+re-represent
+re-run
+re-set
+re-think
+re-use
+re-used
+re-uses
+re-using
+re-write
+real-world
+recalculation
+recently-accessed
+recompile
recurse
recursing
+recursion
+recursively
+red-green-blue
+redefinition
+refactor
+refactored
+refactoring
refactorings
+regex
+regexp
+register-to-register
reim
reimplemented
-repo
+renames
+reproducibility
+reproducible
resizeable
-roundtrip
+resizing
+result—typing
+right-to-left
+rightchild
+roundoff
+row-oriented
+row-wise
+run-time
runnable
runtime
ruten
-satisfiable
-semver
-sexualized
-sha
+saibene
+sarkar
+scalene
+scanniello
+schema
+schocken
+self-closing
+self-referential
+self-taught
+semantic-version
+sha-256
+shareable
+sheena
+shepperd
+shimon
+sigsoft
+sigweni
sinel
-smt
+single-argument
+single-byte
+single-letter
+single-process
+single-record
+single-step
+single-stepping
+single-variable
+singleton
snakemake
+socorro
+special-purpose
+specially-named
+specifiers
+sql
sqlite
-sqrt
-stmt
+square-specific
+stack-handling
storable
straightfoward
+strictly-typed
+struct
+sub-directories
+sub-expressions
+sub-keys
+sub-list
+sub-lists
+sub-patterns
sublicense
substrings
+subtracts
+superceded
svg
-tcp
-tcpip
-tdd
+tabular
+tavish
+tcp/ip
+teardown
+templated
templating
-testability's
+test-driven
+testability
+testable
textwrap
-th
+thermocouple
+three-bit
+tichy
+time-consuming
+timestamped
+timestamps
+timezone
tll
-toctou
-tok
tokenization
tokenize
tokenizer
tokenizing
-topo
+tool-based
+top-down
+top-level
+top-most
+top-to-bottom
tradeoffs
+traversal
+triply-nested
+truncating
truthy
-txt
-udhr
+tuple
+turhan
+turnator
+two-digit
+two-dimensional
+two-element
+two-part
+unaccented
+unaddressed
unenforceability
+unenforceable
unfittable
-ungc
unicode
+unimaginatively
unix
+unmaintainable
+unpacks
unparse
+unsurprisingly
upcall
upcalling
-url
-urlparse
+upcalls
+upper-case
+upper-left
+user-defined
+user-level
+user-specified
utc
-utf
-util
+utf-32
+utf-8
+uyaguari
validator
-varargs
+variable-length
+versioning
+viewable
viewport
+vlissides
vm
-wasim
+vms
watchpoint
watchpoints
-webaim
+well-defined
+well-designed
+well-known
+widely-used
+wildcards
+windowing
+workflows
wrappable
+write-only
+xml
+xor
+xunit
yaml
-yml
+yanina
+yes-or-no
+yim
+yundong
+z-buffering
+z3
zeller
+zines
diff --git a/lib/mccole/bin/post_spellcheck.py b/lib/mccole/bin/post_spellcheck.py
deleted file mode 100644
index 2ed4b59c5..000000000
--- a/lib/mccole/bin/post_spellcheck.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env python
-
-"""Compare standard input words to known words."""
-
-
-import sys
-
-
-def main(wordlist):
- """Main driver."""
- actual = {x.strip() for x in sys.stdin.readlines()}
- with open(wordlist, "r") as reader:
- expected = {x.strip() for x in reader.readlines()}
- report("unknown", actual - expected)
- report("unused", expected - actual)
-
-
-def report(title, words):
- """Report a set of words."""
- if not words:
- return
- print(f"# {title}")
- for w in sorted(words):
- print(w)
-
-
-if __name__ == "__main__":
- main(sys.argv[1])
diff --git a/lib/mccole/bin/pre_spellcheck.py b/lib/mccole/bin/pre_spellcheck.py
deleted file mode 100644
index 0bd323ee8..000000000
--- a/lib/mccole/bin/pre_spellcheck.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-
-"""Remove code and math before spell-checking."""
-
-
-import argparse
-
-import util
-from bs4 import BeautifulSoup
-from markdown import markdown
-
-
-def main():
- options = parse_args()
- handle(options.pages, expand)
- handle(options.slides, expand)
-
-
-def expand(text):
- return markdown(text, extensions=["md_in_html"])
-
-
-def handle(filenames, pre_processor=None):
- for f in filenames:
- with open(f, "r") as reader:
- text = reader.read()
- if pre_processor is not None:
- text = pre_processor(text)
- print(util.cleanup_html(BeautifulSoup(text, "html.parser")))
-
-
-def parse_args():
- parser = argparse.ArgumentParser()
- parser.add_argument("--pages", nargs="+", default=[], help="pages")
- parser.add_argument("--slides", nargs="+", default=[], help="slides")
- return parser.parse_args()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/mccole/bin/spelling.py b/lib/mccole/bin/spelling.py
new file mode 100644
index 000000000..7e95ec4e0
--- /dev/null
+++ b/lib/mccole/bin/spelling.py
@@ -0,0 +1,93 @@
+"""Produce or check consolidated vocabulary."""
+
+import argparse
+from markdown import markdown
+from pathlib import Path
+import re
+import string
+import sys
+from bs4 import BeautifulSoup
+from spellchecker import SpellChecker
+import util
+
+PAT_DOC = [
+ (re.compile(r'^\\\(.+?\\\)'), " "),
+ (re.compile(r'[–—]'), " "),
+]
+PAT_WORD = [
+ (re.compile(r'^[“”’‘…\(\)#]*'), ""),
+ (re.compile(r'[“”’‘…,\?\.:;\(\)°%]*$'), ""),
+ (re.compile(r'’s'), ""),
+ (re.compile(r'^(0x)?[\(\)\d\.×\+/–-]+$'), ""),
+ (re.compile(r'’'), "'"),
+]
+
+
+def main():
+ """Main driver."""
+ options = parse_args()
+ config = util.load_config(options.config)
+ extra_words = get_extra_words(options)
+ docs = read_docs(options, config)
+ words = extract_words(docs)
+ checker = SpellChecker()
+ unknown = checker.unknown(words) - extra_words
+ for word in sorted(unknown):
+ print(word)
+
+
+def extract_words(docs):
+ """Extract set of all words from documents."""
+ words = set()
+ for doc in docs:
+ text = normalize(doc.text, PAT_DOC)
+ words |= {normalize(w, PAT_WORD) for w in doc.text.split()}
+ return words
+
+
+def get_extra_words(options):
+ """Load list of extra known words."""
+ if not options.extra:
+ return set()
+ with open(options.extra, "r") as reader:
+ return {word.strip() for word in reader.readlines()}
+
+
+def normalize(text, patterns):
+ """Create normalized form of text."""
+ for (pat, replacement) in patterns:
+ text = pat.sub(replacement, text)
+ return text
+
+
+def parse_args():
+ """Parse arguments."""
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--config", required=True, help="Configuration file")
+ parser.add_argument("--extra", help="File containing list of extra known words")
+ parser.add_argument("--slides", default=False, action="store_true", help="Process slides")
+ return parser.parse_args()
+
+
+def read_docs(options, config):
+ """Read all HTML documents."""
+ result = [_read_doc(Path(config.out_dir, "index.html"), "main")]
+ for slug in [*config.chapters, *config.appendices]:
+ result.append(_read_doc(Path(config.out_dir, slug, "index.html"), "main"))
+ if options.slides:
+ for slug in config.chapters:
+ result.append(_read_doc(Path(config.out_dir, slug, "slides", "index.html"), "body"))
+ return result
+
+
+def _read_doc(filename, root):
+ """Read a single HTML document."""
+ with open(filename, "r") as reader:
+ text = reader.read()
+ text = markdown(text, extensions=["md_in_html"])
+ soup = BeautifulSoup(text, "html.parser").find(root)
+ return util.cleanup_html(soup, bib=True)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/lib/mccole/mccole.mk b/lib/mccole/mccole.mk
index c7d16c750..e4d76fd28 100644
--- a/lib/mccole/mccole.mk
+++ b/lib/mccole/mccole.mk
@@ -109,16 +109,7 @@ fonts:
## spelling: check spelling against known words
.PHONY: spelling
spelling:
- @make wordlist \
- | python ${MCCOLE}/bin/post_spellcheck.py ${ROOT}/info/wordlist.txt
-
-## wordlist: make a list of unknown and unused words
-.PHONY: wordlist
-wordlist: ${ROOT}/docs/index.html
- @python ${MCCOLE}/bin/pre_spellcheck.py --pages ${SRC_PAGES} --slides ${SRC_SLIDES} \
- | aspell -H list \
- | sort \
- | uniq
+ @python ${MCCOLE}/bin/spelling.py --config ${ROOT}/config.py --extra info/wordlist.txt
## index: show all index entries
.PHONY: index
diff --git a/src/binary/index.md b/src/binary/index.md
index 2cf70ee37..6f0a5f796 100644
--- a/src/binary/index.md
+++ b/src/binary/index.md
@@ -118,7 +118,7 @@ putting it another way,
Finally,
`~` flips its argument: 1 becomes 0, and 0 becomes 1.
-When these operators are used on multibit values
+When these operators are used on multi-bit values
they work on corresponding bits independently as shown in [%t binary-ops %].
diff --git a/src/build/index.md b/src/build/index.md
index 518fcaa78..790ca5297 100644
--- a/src/build/index.md
+++ b/src/build/index.md
@@ -176,7 +176,7 @@ Our implementation works,
but we can do better:
1. The configuration might not come directly from a JSON file—for example,
- it might be embedded in a larger file or generated by anothe prrogram—so
+ it might be embedded in a larger file or generated by another program—so
we should modify the constructor to take the loaded JSON configuration as input.
2. Printing actions to the screen isn't very useful,
diff --git a/src/dup/index.md b/src/dup/index.md
index 3b75e787b..7042100f7 100644
--- a/src/dup/index.md
+++ b/src/dup/index.md
@@ -49,7 +49,7 @@ we create a `tests` directory with six files:
| `a1.txt` | `a2.txt` | `a3.txt` | `b1.txt` | `b2.txt` | `c1.txt` |
| ---- | ---- | ---- | ---- | ---- | ---- |
-| aaa | aaa | aaa | bb | bb | c |
+| `aaa` | `aaa` | `aaa` | `bb` | `bb` | `c` |
We expect the three `a` files and the two `b` files to be reported as duplicates.
There's no particular reason for these tests—we just have to start somewhere.
@@ -124,7 +124,7 @@ The output seems random,
but is it?
As a more stringent test,
let's try hashing every line of text in
-[Project Gutenberg][gutenberg]'s version of the novel *Dracula*
+the [Project Gutenberg][gutenberg] version of the novel *Dracula*
and plot the distribution ([%f dup-naive-dracula %]).
[% figure
@@ -193,7 +193,7 @@ other than generating random strings of bytes and hashing them.
Cryptographic hash functions are hard to write—or rather,
it's very hard to prove that a particular algorithm has the properties we require.
We will therefore use a function from Python's [hashing library][py_hashlib]
-that implements the [%g sha256 "SHA256" %] algorithm.
+that implements the [%g sha256 "SHA-256" %] algorithm.
Given some bytes as input,
this function produces a 256-bit hash,
which is normally written as a 64-character [%g hexadecimal "hexadecimal" %] string.
@@ -290,9 +290,9 @@ What are the actual odds?
- Why do `hash(123)` and `hash("123")` work but `hash([123])` raise an exception?
-### How Good Is SHA256? {: .exercise}
+### How Good Is SHA-256? {: .exercise}
-- Write a function that calculate the SHA256 hash code
+- Write a function that calculate the SHA-256 hash code
of each unique line of a text file.
- Convert the hex digests of those hash codes to integers.
diff --git a/src/finale/index.md b/src/finale/index.md
index 4f5ea2d69..6966d4f27 100644
--- a/src/finale/index.md
+++ b/src/finale/index.md
@@ -5,7 +5,8 @@
caption="De Rosa SK Pininfarina bicycle."
%]
-Consider the bicycle–more specifically,
+Consider the bicycle:
+more specifically,
the De Rosa SK Pininfarina ([%f finale-bicycle %]).
I think it's beautiful,
but I wouldn't call it art,
diff --git a/src/ftp/index.md b/src/ftp/index.md
index 41afe8baa..597a8d196 100644
--- a/src/ftp/index.md
+++ b/src/ftp/index.md
@@ -104,8 +104,8 @@ when we run the client and server in separate terminal windows.
[% figure
slug="ftp-interaction"
img="interaction.svg"
- alt="Client/server interaction"
- caption="Steps and messages in client/server interaction."
+ alt="Client-server interaction"
+ caption="Steps and messages in client-server interaction."
%]
There's a *lot* going on here,
diff --git a/src/intro/index.md b/src/intro/index.md
index ce457ef57..2a142611f 100644
--- a/src/intro/index.md
+++ b/src/intro/index.md
@@ -129,7 +129,7 @@ All of the written material in this book
is licensed under the [Creative Commons - Attribution - NonCommercial 4.0 International license][cc_by_nc]
(CC-BY-NC-4.0),
while the software is covered by the [Hippocratic License][hippocratic_license].
-The first license allows you to use and remix this material for non-commercial purposes,
+The first license allows you to use and remix this material for noncommercial purposes,
as-is or in adapted form,
provided you cite its original source;
if you want to sell copies or make money from this material in any other way,
@@ -207,5 +207,5 @@ we all get a lot.
*This one's for Mike and Jon:*
- *I'm glad you always found time to chat.*
+ *I am glad you always found time to chat.*
diff --git a/src/intro/syllabus_linear.svg b/src/intro/syllabus_linear.svg
index a8ca291f5..55d13c522 100644
--- a/src/intro/syllabus_linear.svg
+++ b/src/intro/syllabus_linear.svg
@@ -76,7 +76,7 @@
Archiver
-
+
dup->archive
@@ -99,7 +99,7 @@
-
+
glob->archive
@@ -192,7 +192,7 @@
Machine
-
+
interp->vm
@@ -209,7 +209,7 @@
-
+
mock->archive
@@ -353,7 +353,7 @@
-
+
binary->vm
@@ -442,7 +442,7 @@
A Debugger
-
+
viewer->debugger
@@ -453,7 +453,7 @@
-
+
vm->debugger
diff --git a/src/intro/syllabus_regular.svg b/src/intro/syllabus_regular.svg
index 487b70d09..19220fb7a 100644
--- a/src/intro/syllabus_regular.svg
+++ b/src/intro/syllabus_regular.svg
@@ -59,7 +59,7 @@
Archiver
-
+
dup->archive
@@ -84,7 +84,7 @@
-
+
glob->archive
@@ -162,7 +162,7 @@
Machine
-
+
interp->vm
@@ -174,7 +174,7 @@
-
+
mock->archive
@@ -273,7 +273,7 @@
-
+
binary->vm
@@ -332,13 +332,13 @@
A Debugger
-
+
viewer->debugger
-
+
vm->debugger
diff --git a/src/persist/index.md b/src/persist/index.md
index eafc33d8a..5802e1875 100644
--- a/src/persist/index.md
+++ b/src/persist/index.md
@@ -182,7 +182,7 @@ we can follow the Open-Closed Principle by rewriting our functions as classes.
We will also use [%i "dynamic dispatch" %][%/i%]
as we did in [%x interp %]
to handle each item
-so that we don't have to modify a multiway `if` statement
+so that we don't have to modify a multi-way `if` statement
each time we add a new capability.
The core of our saving class is:
diff --git a/src/undo/index.md b/src/undo/index.md
index 64ea3d75f..daec80d6c 100644
--- a/src/undo/index.md
+++ b/src/undo/index.md
@@ -15,7 +15,7 @@ which will introduce another commonly-used software design pattern.
## Getting Started {: #undo-start}
-Our file fiewer has four classes ([%f undo-classes %]):
+Our file viewer has four classes ([%f undo-classes %]):
- A `Window` can draw lines and report its size.
@@ -239,7 +239,7 @@ we are appending the action to the history before doing the action,
so we are essentially undoing our undo forever.
The solution is to modify the base class `Action` to have a `.save` method
that tells the application whether or not to save this action.
-The default implemenation returns `True`,
+The default implementation returns `True`,
but we override it in `Undo` to return `False`:
[% inc file="undoable.py" keep="Undo" %]