+++ /dev/null
-Cat Stevens
+++ /dev/null
-USING: help help.lint.pedantic help.markup help.syntax kernel
-strings words vocabs ;
-IN: help.lint.pedantic
-
-ABOUT: "help.lint.pedantic"
-
-ARTICLE: "help.lint.pedantic" "Pedantic help coverage"
-"The " { $vocab-link "help.lint.pedantic" } " vocabulary implements a very picky documentation completeness checker. Intended to be used alongside " { $vocab-link "help.lint" } " in writing documenation, the pedantic linter requires all ordinary words to have documentation defining the "
-{ $link $example } ", "
-{ $link $description } ", and "
-{ $link $values }
-" sections (see " { $link "element-types" } ")."
-$nl
-"The following words are provided to aid in writing more complete documentation:"
-{ $subsections
- word-pedant
- vocab-pedant
- prefix-pedant
-} ;
-
-{ word-pedant vocab-pedant prefix-pedant } related-words
-
-HELP: ordinary-word-missing-section
-{ $values { "missing-section" string } { "word-name" string } }
-{ $description "Throws an " { $link ordinary-word-missing-section } " error." }
-{ $error-description "Thrown when an ordinary word's documentation is missing one of the sections " { $links $values $description $example } "." } ;
-
-HELP: prefix-pedant
-{ $values { "prefix" string } { "private?" boolean } }
-{ $description "Runs the help coverage checker on every child vocabulary of the given " { $snippet "prefix" } ", including the base vocabulary. If " { $snippet "private?" } " is " { $snippet "f" } ", the prefix's child " { $snippet ".private" } " vocabularies are not checked. If " { $snippet "private?" } " is " { $snippet "t" } ", " { $emphasis "all" } " child vocabularies are checked." }
-{ $errors
- { $link empty-examples } " if a word has an empty " { $snippet "$examples" } " section
-"
- { $link ordinary-word-missing-section } " if a word is missing a section entirely"
-}
-{ $examples
- { $example
- "USING: help.lint.pedantic ;"
- "\"help.lint.pedantic\" f prefix-pedant"
- ""
- }
-} ;
-
-HELP: word-pedant
-{ $values { "word" { $or string word } } }
-{ $description "Runs the help coverage checker on the word described by " { $snippet "word-desc" } "." }
-{ $errors
- { $link empty-examples } " if a word has an empty " { $snippet "$examples" } " section
-"
- { $link ordinary-word-missing-section } " if a word is missing a section entirely"
-}
-{ $examples
- { $example
- "USING: help.lint.pedantic ;"
- "\\ word-pedant word-pedant"
- ""
- }
-} ;
-
-HELP: vocab-pedant
-{ $values { "vocab-spec" { $or vocab string } } }
-{ $description "Runs the help coverage checker on the vocabulary in the given " { $snippet "vocab-spec" } "." }
-{ $errors
- { $link empty-examples } " if a word has an empty " { $snippet "$examples" } " section
-"
- { $link ordinary-word-missing-section } " if a word is missing a section entirely"
-}
-{ $examples
- { $example
- "USING: help.lint.pedantic ;"
- "\"help.lint.pedantic\" vocab-pedant"
- ""
- }
-} ;
+++ /dev/null
-USING: accessors classes combinators.short-circuit eval
-formatting fry help help.lint help.lint.checks help.markup
-kernel namespaces parser prettyprint sequences sorting splitting
-strings summary vocabs words ;
-IN: help.lint.pedantic
-
-ERROR: ordinary-word-missing-section missing-section word-name ;
-ERROR: empty-examples word-name ;
-
-M: empty-examples summary
- word-name>> "Word '%s' has defined empty $examples section" sprintf ;
-
-M: ordinary-word-missing-section summary
- [ word-name>> ] [ missing-section>> ] bi
- "Word '%s' should define %s help section" sprintf ;
-
-<PRIVATE
-
-: elements-by ( element elt-type -- seq )
- swap elements ;
-
-: checked-ordinary-word? ( word -- ? )
- {
- [ word-help \ $predicate elements-by empty? ]
- [ class? not ]
- } 1&& ;
-
-: check-ordinary-word-sections ( word -- )
- [ word-help ] keep '[
- [ elements-by ] keep swap
- [ name>> _ ordinary-word-missing-section ]
- [ 2drop ] if-empty
- ]
- { [ \ $values ] [ \ $description ] [ \ $examples ] }
- [ prepose ] with map
- [ call( x -- ) ] with each ;
-
-: missing-examples? ( word -- ? )
- word-help \ $examples elements-by empty? ;
-
-: check-ordinary-word-examples ( word -- )
- [ missing-examples? ] keep '[ _ empty-examples ] when ;
-PRIVATE>
-
-GENERIC: word-pedant ( word -- )
-M: word word-pedant
- dup checked-ordinary-word? [
- [ check-ordinary-word-sections ] [ check-ordinary-word-examples ] bi
- ] [ drop ] if ; inline
-
-M: string word-pedant
- "\\ " prepend eval( -- word ) word-pedant ; inline
-
-: vocab-pedant ( vocab-spec -- )
- [ auto-use? off vocab-words natural-sort [ word-pedant ] each ] with-scope ;
-
-: prefix-pedant ( prefix private? -- )
- [
- auto-use? off group-articles vocab-articles set
- [ loaded-child-vocab-names natural-sort ] dip not
- [ [ ".private" ?tail nip not ] filter ] when
- [ vocab-pedant ] each
- ] with-scope ;
+++ /dev/null
-Pedantic help coverage checker
--- /dev/null
+Cat Stevens
--- /dev/null
+USING: help help.lint.pedantic help.lint.pedantic.private help.markup help.syntax kernel
+sequences strings vocabs words ;
+IN: help.lint.pedantic
+
+ABOUT: "help.lint.pedantic"
+
+ARTICLE: "help.lint.pedantic" "Pedantic help coverage"
+"pedant, " { $emphasis "n." } " one who pays more attention to formal rules and book learning than they merit."
+$nl
+"The " { $vocab-link "help.lint.pedantic" } " vocabulary implements a very picky documentation completeness checker -- your very own documentation pedant."
+$nl
+"The pedantic linter requires most words to have documentation defining the "
+{ $links $values $description $error-description $class-description $examples } " sections (see " { $links "element-types" } ")."
+$nl
+"This vocabulary is intended to be used alongside and after " { $vocab-link "help.lint" } ", not as a replacement for it."
+$nl
+"These words are provided to aid in writing more complete documentation:"
+{ $subsections
+ word-pedant
+ vocab-pedant
+ prefix-pedant
+} ;
+
+{ word-pedant vocab-pedant prefix-pedant } related-words
+{ missing-sections empty-examples } related-words
+
+HELP: missing-sections
+{ $values { "missing-sections" sequence } { "word-name" word } }
+{ $description "Throws an " { $link missing-sections } " error." }
+{ $error-description "Thrown when a word's documentation is missing one or more sections required for it by " { $link should-define } "." } ;
+
+HELP: empty-examples
+{ $values { "word-name" word } }
+{ $description "Throws an " { $link empty-examples } " error." }
+{ $error-description "Thrown when a word's " { $link $examples } " section is missing or empty." } ;
+
+HELP: prefix-pedant
+{ $values { "prefix" string } { "private?" boolean } }
+{ $description "Runs the help coverage checker on every child vocabulary of the given " { $snippet "prefix" } ", including the base vocabulary. If " { $snippet "private?" } " is " { $snippet "f" } ", the prefix's child " { $snippet ".private" } " vocabularies are not checked. If " { $snippet "private?" } " is " { $snippet "t" } ", " { $emphasis "all" } " child vocabularies are checked." }
+{ $errors
+ { $link empty-examples } " if a word has an empty " { $snippet "$examples" } " section
+"
+ { $link missing-sections } " if a word is missing a section entirely"
+}
+{ $examples
+ { $example
+ "USING: help.lint.pedantic ;"
+ "\"help.lint.pedantic\" f prefix-pedant"
+ ""
+ }
+} ;
+
+HELP: word-pedant
+{ $values { "word" { $or string word } } }
+{ $description "Runs the help coverage checker on the word described by " { $snippet "word-desc" } "." }
+{ $errors
+ { $link empty-examples } " if a word has an empty " { $snippet "$examples" } " section
+"
+ { $link missing-sections } " if a word is missing a section entirely"
+}
+{ $examples
+ { $example
+ "USING: help.lint.pedantic ;"
+ "\\ word-pedant word-pedant"
+ ""
+ }
+} ;
+
+HELP: vocab-pedant
+{ $values { "vocab-spec" { $or vocab string } } }
+{ $description "Runs the help coverage checker on the vocabulary in the given " { $snippet "vocab-spec" } "." }
+{ $errors
+ { $link empty-examples } " if a word has an empty " { $snippet "$examples" } " section
+"
+ { $link missing-sections } " if a word is missing a section entirely"
+}
+{ $examples
+ { $example
+ "USING: help.lint.pedantic ;"
+ "\"help.lint.pedantic\" vocab-pedant"
+ ""
+ }
+} ;
--- /dev/null
+USING: accessors arrays classes combinators
+combinators.short-circuit continuations english eval formatting
+fry help help.lint help.lint.checks help.markup kernel
+namespaces parser prettyprint sequences sets sorting splitting
+strings summary vocabs words ;
+FROM: namespaces => set ;
+IN: help.lint.pedantic
+
+ERROR: missing-sections
+ { word-name word initial: POSTPONE: f }
+ { missing-sections sequence initial: { } } ;
+ERROR: empty-examples { word-name initial: POSTPONE: f } ;
+
+<PRIVATE
+DEFER: ?pluralize
+
+M: empty-examples summary
+ word-name>> "Word '%s' has defined empty $examples section" sprintf ;
+
+M: missing-sections summary
+ [ word-name>> ] [
+ missing-sections>> dup [
+ length "section" ?pluralize
+ ] dip
+ [ name>> ] map ", " join
+ ] bi
+ "Word '%s' should define help %s: %s" sprintf ;
+
+: sorted-loaded-child-vocabs ( prefix -- assoc )
+ loaded-child-vocab-names natural-sort ; inline
+
+: filter-private ( seq -- no-private )
+ [ ".private" ?tail nip not ] filter ; inline
+
+: ?pluralize ( n singular -- singular/plural )
+ count-of-things " " split1 nip ;
+
+: should-define ( word -- spec )
+ {
+ { [ dup predicate? ] [ drop { } ] } ! predicate?s have generated docs
+ { [ dup error? ] [ drop { $values $description $error-description } ] }
+ { [ dup class? ] [ drop { $class-description } ] }
+ { [ dup word? ] [ drop { $values $description $examples } ] }
+ [ drop no-cond ]
+ } cond ;
+
+: word-defines-sections ( word -- seq )
+ word-help [ first ] map ;
+
+: missing-examples? ( word -- ? )
+ word-help \ $examples swap elements empty? ;
+
+: check-examples ( word -- )
+ [ missing-examples? ] keep '[ _ empty-examples ] when ;
+
+: check-sections ( word -- )
+ [ ] [ should-define ] [ word-defines-sections ] tri
+ diff [ drop ] [ missing-sections ] if-empty ;
+PRIVATE>
+
+GENERIC: word-pedant ( word -- )
+M: word word-pedant
+ {
+ { [ dup predicate? ] [ drop ] }
+ { [ dup error? ] [ check-sections ] }
+ { [ dup word? ] [ [ check-sections ] [ check-examples ] bi ] }
+ [ drop no-cond ]
+ } cond ; inline
+
+M: string word-pedant
+ "\\ " prepend eval( -- word ) word-pedant ; inline
+
+: vocab-pedant ( vocab-spec -- )
+ [ auto-use? off vocab-words natural-sort [ word-pedant ] each ] with-scope ;
+
+: prefix-pedant ( prefix private? -- )
+ [
+ auto-use? off group-articles vocab-articles set
+ [ sorted-loaded-child-vocabs ] dip not
+ [ filter-private ] when
+ [ vocab-pedant ] each
+ ] with-scope ;
--- /dev/null
+Pedantic help coverage checker