diff --git a/basis/help/cookbook/cookbook.factor b/basis/help/cookbook/cookbook.factor
index aef6ce6809..9fb837a873 100755
--- a/basis/help/cookbook/cookbook.factor
+++ b/basis/help/cookbook/cookbook.factor
@@ -312,13 +312,13 @@ ARTICLE: "cookbook-pitfalls" "Pitfalls to avoid"
{ "When a source file uses two vocabularies which define words with the same name, the order of the vocabularies in the " { $link POSTPONE: USE: } " or " { $link POSTPONE: USING: } " forms is important. The parser prints warnings when vocabularies shadow words from other vocabularies; see " { $link "vocabulary-search-shadow" } ". The " { $vocab-link "qualified" } " vocabulary implements qualified naming, which can be used to resolve ambiguities." }
{ "If a literal object appears in a word definition, the object itself is pushed on the stack when the word executes, not a copy. If you intend to mutate this object, you must " { $link clone } " it first. See " { $link "syntax-literals" } "." }
{ "For a discussion of potential issues surrounding the " { $link f } " object, see " { $link "booleans" } "." }
- { "Factor's object system is quite flexible. Careless usage of union, mixin and predicate classes can lead to similar problems to those caused by ``multiple inheritance'' in other languages. In particular, it is possible to have two classes such that they have a non-empty intersection and yet neither is a subclass of the other. If a generic word defines methods on two such classes, method precedence is undefined for objects that are instances of both classes. See " { $link "method-order" } " for details." }
+ { "Factor's object system is quite flexible. Careless usage of union, mixin and predicate classes can lead to similar problems to those caused by ``multiple inheritance'' in other languages. In particular, it is possible to have two classes such that they have a non-empty intersection and yet neither is a subclass of the other. If a generic word defines methods on two such classes, various disambiguation rules are applied to ensure method dispatch remains deterministic, however they may not be what you expect. See " { $link "method-order" } " for details." }
{ "Performance-sensitive code should have a static stack effect so that it can be compiled by the optimizing word compiler, which generates more efficient code than the non-optimizing quotation compiler. See " { $link "inference" } " and " { $link "compiler" } "."
$nl
"This means that methods defined on performance sensitive, frequently-called core generic words such as " { $link nth } " should have static stack effects which are consistent with each other, since a generic word will only have a static stack effect if all methods do."
$nl
- "Unit tests for the " { $vocab-link "inference" } " vocabulary can be used to ensure that any methods your vocabulary defines on core generic words have static stack effects:"
- { $code "\"inference\" test" }
+ "Unit tests for the " { $vocab-link "stack-checker" } " vocabulary can be used to ensure that any methods your vocabulary defines on core generic words have static stack effects:"
+ { $code "\"stack-checker\" test" }
"In general, you should strive to write code with inferable stack effects, even for sections of a program which are not performance sensitive; the " { $link infer. } " tool together with the optimizing compiler's error reporting can catch many bugs ahead of time." }
{ "Be careful when calling words which access variables from a " { $link make-assoc } " which constructs an assoc with arbitrary keys, since those keys might shadow variables." }
{ "If " { $link run-file } " throws a stack depth assertion, it means that the top-level form in the file left behind values on the stack. The stack depth is compared before and after loading a source file, since this type of situation is almost always an error. If you have a legitimate need to load a source file which returns data in some manner, define a word in the source file which produces this data on the stack and call the word after loading the file." }
diff --git a/basis/help/handbook/handbook.factor b/basis/help/handbook/handbook.factor
index 4e136d81c2..51750d772f 100755
--- a/basis/help/handbook/handbook.factor
+++ b/basis/help/handbook/handbook.factor
@@ -1,10 +1,10 @@
USING: help help.markup help.syntax help.definitions help.topics
namespaces words sequences classes assocs vocabs kernel arrays
prettyprint.backend kernel.private io generic math system
-strings sbufs vectors byte-arrays
-quotations io.streams.byte-array
-classes.builtin parser lexer classes.predicate classes.union
-classes.intersection classes.singleton classes.tuple ;
+strings sbufs vectors byte-arrays quotations
+io.streams.byte-array classes.builtin parser lexer
+classes.predicate classes.union classes.intersection
+classes.singleton classes.tuple tools.vocabs.browser ;
IN: help.handbook
ARTICLE: "conventions" "Conventions"
@@ -139,7 +139,7 @@ ARTICLE: "collections" "Collections"
{ $subsection "heaps" }
{ $subsection "graphs" }
{ $subsection "buffers" }
-"There are many other collections in " { $snippet "extra/" } ", such as " { $vocab-link "disjoint-sets" } ", " { $vocab-link "persistent-vectors" } ", and " { $vocab-link "tuple-arrays" } "." ;
+"There are also many other vocabularies tagged " { $link T{ vocab-tag { name "collections" } } } " in the library." ;
USING: io.encodings.utf8 io.encodings.utf16 io.encodings.binary io.encodings.ascii io.files ;
@@ -244,7 +244,8 @@ ARTICLE: "handbook-language-reference" "Language reference"
{ $subsection "program-org" }
{ $subsection "numbers" }
{ $subsection "collections" }
-{ $subsection "io" } ;
+{ $subsection "io" }
+"Vocabularies tagged " { $link T{ vocab-tag { name "extensions" } } } " implement various additional language abstractions." ;
ARTICLE: "handbook-environment-reference" "Environment reference"
{ $subsection "prettyprint" }
diff --git a/basis/help/lint/lint.factor b/basis/help/lint/lint.factor
index d49262e7c8..be6206f59c 100755
--- a/basis/help/lint/lint.factor
+++ b/basis/help/lint/lint.factor
@@ -61,10 +61,10 @@ IN: help.lint
: vocab-exists? ( name -- ? )
dup vocab swap "all-vocabs" get member? or ;
-: check-modules ( word element -- )
- nip \ $vocab-link swap elements [
+: check-modules ( element -- )
+ \ $vocab-link swap elements [
second
- vocab-exists? [ "Missing vocabulary" throw ] unless
+ vocab-exists? [ "$vocab-link to non-existent vocabulary" throw ] unless
] each ;
: check-rendering ( word element -- )
@@ -91,7 +91,7 @@ M: help-error error.
2dup check-examples
2dup check-values
2dup check-see-also
- 2dup check-modules
+ 2dup nip check-modules
2dup drop check-rendering
] assert-depth 2drop
] check-something
@@ -101,12 +101,20 @@ M: help-error error.
: check-article ( article -- )
[
- [ dup check-rendering ] assert-depth drop
+ dup article-content [
+ 2dup check-modules check-rendering
+ ] assert-depth 2drop
] check-something ;
+: files>vocabs ( -- assoc )
+ vocabs
+ [ [ [ vocab-docs-path ] keep ] H{ } map>assoc ]
+ [ [ [ vocab-source-path ] keep ] H{ } map>assoc ]
+ bi assoc-union ;
+
: group-articles ( -- assoc )
articles get keys
- vocabs [ dup vocab-docs-path swap ] H{ } map>assoc
+ files>vocabs
H{ } clone [
'[
dup >link where dup
diff --git a/basis/html/components/components.factor b/basis/html/components/components.factor
index b78e3473a7..18e1aad9eb 100644
--- a/basis/html/components/components.factor
+++ b/basis/html/components/components.factor
@@ -9,7 +9,7 @@ xmode.code2html lcs.diff2html farkup
html.elements html.streams html.forms ;
IN: html.components
-GENERIC: render* ( value name render -- )
+GENERIC: render* ( value name renderer -- )
: render ( name renderer -- )
prepare-value
diff --git a/basis/html/forms/forms-docs.factor b/basis/html/forms/forms-docs.factor
index 7a2134c996..6556d2eac2 100644
--- a/basis/html/forms/forms-docs.factor
+++ b/basis/html/forms/forms-docs.factor
@@ -73,6 +73,7 @@ HELP: with-each-value
{ $notes "This word is used to implement the " { $snippet "t:each" } " tag of the " { $vocab-link "html.templates.chloe" } " templating system. It can also be called directly from " { $vocab-link "html.templates.fhtml" } " templates." } ;
HELP: with-each-object
+{ $values { "name" string } { "quot" quotation } }
{ $description "Calls the quotation with each element of the value named " { $snippet "name" } "; the value must be a sequence. The quotation is called in a new dynamic scope where the object's slots become named values, as if " { $link from-object } " was called." }
{ $notes "This word is used to implement the " { $snippet "t:bind-each" } " tag of the " { $vocab-link "html.templates.chloe" } " templating system. It can also be called directly from " { $vocab-link "html.templates.fhtml" } " templates." } ;
diff --git a/basis/html/streams/streams-docs.factor b/basis/html/streams/streams-docs.factor
index 7c5bea805d..d7638a2817 100644
--- a/basis/html/streams/streams-docs.factor
+++ b/basis/html/streams/streams-docs.factor
@@ -18,6 +18,7 @@ HELP: with-html-stream
{ $description "Calls the quotation in a new dynamic scope with " { $link output-stream } " rebound to an " { $link html-stream } " wrapping the current " { $link output-stream } "." }
{ $examples
{ $example
+ "USING: io io.styles html.streams ;"
"[ \"Hello\" { { font-style bold } } format nl ] with-html-stream"
"Hello
"
}
diff --git a/basis/html/templates/templates-docs.factor b/basis/html/templates/templates-docs.factor
index ff53ca978a..3251b46b3e 100644
--- a/basis/html/templates/templates-docs.factor
+++ b/basis/html/templates/templates-docs.factor
@@ -28,7 +28,6 @@ HELP: set-title
{ $description "Sets the title of the current page. This is usually called by child templates, and a master template calls " { $link write-title } "." } ;
HELP: write-title
-{ $values { "string" string } }
{ $description "Writes the title of the current page, previously set by " { $link set-title } ". This is usually called by a master template after rendering a child template." } ;
HELP: add-style