📄 doc.jam
字号:
# Print out the given rules. for local rule-name in [ sequence.insertion-sort $(name) ] { if $(.option.show-locals) || ! $($(module-name).$(rule-name).is-local) { local signature = $($(module-name).$(rule-name).signature:J=" ") ; signature ?= "" ; print.section "Rule '$(module-name).$(rule-name) ( $(signature) )'" $($(module-name).$(rule-name).docs) ; if $($(module-name).$(rule-name).args) { print.list-start ; for local arg-name in $($(module-name).$(rule-name).args) { print.list-item $(arg-name): $($(module-name).$(rule-name).args.$(arg-name).docs) ; } print.list-end ; } } } }}# Generate documentation for a set of classes in a module.#local rule print-help-classes ( module-name # Module of the classes. : name * # Optional list of classes to describe.){ name ?= $($(module-name).classes) ; if [ set.intersection $(name) : $($(module-name).classes) ] { # Print out the given classes. for local class-name in [ sequence.insertion-sort $(name) ] { if $(.option.show-locals) || ! $($(module-name).$(class-name).is-local) { local signature = $($(module-name).$(class-name).signature:J=" ") ; signature ?= "" ; print.section "Class '$(module-name).$(class-name) ( $(signature) )'" $($(module-name).$(class-name).docs) "Inherits from '"$($(module-name).$(class-name).super-name)"'." ; if $($(module-name).$(class-name).args) { print.list-start ; for local arg-name in $($(module-name).$(class-name).args) { print.list-item $(arg-name): $($(module-name).$(class-name).args.$(arg-name).docs) ; } print.list-end ; } } # Print out the documented rules of the class. print-help-module-section $(module-name) $(class-name).class-rules : "Class '$(module-name).$(class-name)' rules" Use --help $(module-name).<rule-name> to get more information. ; # Print out all the rules if details are requested. if $(.option.detailed) { print-help-rules $(module-name) : $($(module-name).$(class-name).class-rules) ; } } }}# Generate documentation for a set of variables in a module.#local rule print-help-variables ( module-name ? # Module of the variables. : name * # Optional list of variables to describe.){ name ?= $($(module-name).variables) ; if [ set.intersection $(name) : $($(module-name).variables) ] { # Print out the given variables. for local variable-name in [ sequence.insertion-sort $(name) ] { print.section "Variable '$(module-name).$(variable-name)'" $($(module-name).$(variable-name).docs) ; if $($(module-name).$(variable-name).default) || $($(module-name).$(variable-name).initial) { print.list-start ; if $($(module-name).$(variable-name).default) { print.list-item "default value:" '$($(module-name).$(variable-name).default:J=" ")' ; } if $($(module-name).$(variable-name).initial) { print.list-item "initial value:" '$($(module-name).$(variable-name).initial:J=" ")' ; } print.list-end ; } } }}# Generate documentation for a project.#local rule print-help-project ( unused ? : jamfile * # The project Jamfile.){ if $(jamfile<$(jamfile)>.docs) { # Print the docs. print.section "Project-specific help" Project has jamfile at $(jamfile) ; print.lines $(jamfile<$(jamfile)>.docs) "" ; }}# Generate documentation for a config file.#local rule print-help-config ( unused ? : type # The type of configuration file user or site. config-file # The configuration Jamfile.){ if $(jamfile<$(config-file)>.docs) { # Print the docs. print.section "Configuration help" Configuration file at $(config-file) ; print.lines $(jamfile<$(config-file)>.docs) "" ; }}ws = " " ;# Extract the text from a block of comments.#local rule extract-comment ( var # The name of the variable to extract from.){ local comment = ; local line = $($(var)[1]) ; local l = [ MATCH "^[$(ws)]*(#)(.*)$" : $(line) ] ; while $(l[1]) && $($(var)) { if $(l[2]) { comment += [ MATCH "^[$(ws)]?(.*)$" : $(l[2]) ] ; } else { comment += "" ; } $(var) = $($(var)[2-]) ; line = $($(var)[1]) ; l = [ MATCH "^[$(ws)]*(#)(.*)$" : $(line) ] ; } return $(comment) ;}# Extract s single line of Jam syntax, ignoring any comments.#local rule extract-syntax ( var # The name of the variable to extract from.){ local syntax = ; local line = $($(var)[1]) ; while ! $(syntax) && ! [ MATCH "^[$(ws)]*(#)" : $(line) ] && $($(var)) { local m = [ MATCH "^[$(ws)]*(.*)$" : $(line) ] ; if $(m) && ! $(m) = "" { syntax = $(m) ; } $(var) = $($(var)[2-]) ; line = $($(var)[1]) ; } return $(syntax) ;}# Extract the next token, this is either a single Jam construct or a comment as# a single token.#local rule extract-token ( var # The name of the variable to extract from.){ local parts = ; while ! $(parts) { parts = [ MATCH "^[$(ws)]*([^$(ws)]+)[$(ws)]*(.*)" : $($(var)[1]) ] ; if ! $(parts) { $(var) = $($(var)[2-]) ; } } local token = ; if [ MATCH "^(#)" : $(parts[1]) ] { token = $(parts:J=" ") ; $(var) = $($(var)[2-]) ; } else { token = $(parts[1]) ; $(var) = $(parts[2-]:J=" ") $($(var)[2-]) ; } return $(token) ;}# Scan for a rule declaration as the next item in the variable.#local rule scan-rule ( syntax ? # The first part of the text which contains the rule declaration. : var # The name of the variable to extract from.){ local rule-parts = [ MATCH "^[$(ws)]*(rule|local[$(ws)]*rule)[$(ws)]+([^$(ws)]+)[$(ws)]*(.*)" : $(syntax:J=" ") ] ; if $(rule-parts[1]) { # Mark as doc for rule. local rule-name = $(rule-parts[2]) ; if $(scope-name) { rule-name = $(scope-name).$(rule-name) ; } local is-local = [ MATCH "^(local).*" : $(rule-parts[1]) ] ; if $(comment-block) { set-rule-doc $(rule-name) $(module-name) $(is-local) : $(comment-block) ; } # Parse args of rule. $(var) = $(rule-parts[3-]) $($(var)) ; set-rule-arguments-signature $(rule-name) $(module-name) : [ scan-rule-arguments $(var) ] ; # Scan within this rules scope. local scope-level = [ extract-token $(var) ] ; local scope-name = $(rule-name) ; while $(scope-level) { local comment-block = [ extract-comment $(var) ] ; local syntax-block = [ extract-syntax $(var) ] ; if [ scan-rule $(syntax-block) : $(var) ] { } else if [ MATCH "^(\\{)" : $(syntax-block) ] { scope-level += "{" ; } else if [ MATCH "^[^\\}]*([\\}])[$(ws)]*$" : $(syntax-block) ] { scope-level = $(scope-level[2-]) ; } } return true ; }}# Scan the arguments of a rule.#local rule scan-rule-arguments ( var # The name of the variable to extract from.){ local arg-syntax = ; local token = [ extract-token $(var) ] ; while $(token) != "(" && $(token) != "{" { token = [ extract-token $(var) ] ; } if $(token) != "{" { token = [ extract-token $(var) ] ; } local arg-signature = ; while $(token) != ")" && $(token) != "{" { local arg-name = ; local arg-qualifier = " " ; local arg-doc = ; if $(token) = ":" { arg-signature += $(token) ; token = [ extract-token $(var) ] ; } arg-name = $(token) ; arg-signature += $(token) ; token = [ extract-token $(var) ] ; if [ MATCH "^([\\*\\+\\?])" : $(token) ] { arg-qualifier = $(token) ; arg-signature += $(token) ; token = [ extract-token $(var) ] ; } if $(token) = ":" { arg-signature += $(token) ; token = [ extract-token $(var) ] ; } if [ MATCH "^(#)" : $(token) ] { $(var) = $(token) $($(var)) ; arg-doc = [ extract-comment $(var) ] ; token = [ extract-token $(var) ] ; } set-argument-doc $(arg-name) $(arg-qualifier) $(rule-name) $(module-name) : $(arg-doc) ; } while $(token) != "{" { token = [ extract-token $(var) ] ; } $(var) = "{" $($(var)) ; arg-signature ?= "" ; return $(arg-signature) ;}# Scan for a variable declaration.#local rule scan-variable ( syntax ? # The first part of the text which contains the variable declaration. : var # The name of the variable to extract from.){ # [1] = name, [2] = value(s) local var-parts = [ MATCH "^[$(ws)]*([^$(ws)]+)[$(ws)]+([\\?\\=]*)[$(ws)]+([^\\;]*)\\;" : $(syntax) ] ; if $(var-parts) { local value = [ MATCH "^(.*)[ ]$" : $(var-parts[3-]:J=" ") ] ; local default-value = "" ; local initial-valie = "" ; if $(var-parts[2]) = "?=" { default-value = $(value) ; default-value ?= "(empty)" ; } else { initial-value = $(value) ; initial-value ?= "(empty)" ; } if $(comment-block) { set-variable-doc $(var-parts[1]) $(default-value) $(initial-value) $(module-name) : $(comment-block) ; } return true ; }}# Scan a class declaration.#local rule scan-class ( syntax ? # The syntax text for the class declaration.){ # [1] = class?, [2] = name, [3] = superclass local class-parts = [ MATCH "^[$(ws)]*([^$(ws)]+)[$(ws)]+([^$(ws)]+)[$(ws)]+:*[$(ws)]*([^$(ws);]*)" : $(syntax) ] ; if $(class-parts[1]) = "class" || $(class-parts[1]) = "class.class" { set-class-doc $(class-parts[2]) $(module-name) : $(class-parts[3]) ; }}# Scan a module file for documentation comments. This also invokes any actions# assigned to the module. The actions are the rules that do the actual output of# the documentation. This rule is invoked as the header scan rule for the module# file.#rule scan-module ( target # The module file. : text * # The text in the file, one item per line. : action * # Rule to call to output docs for the module.){ if $(.option.debug) { ECHO "HELP:" scanning module target '$(target)' ; } local module-name = $(target:B) ; local module-documented = ; local comment-block = ; local syntax-block = ; # This is a hack because we can not get the line of a file if it happens to # not have a new-line termination. text += "}" ; while $(text) { comment-block = [ extract-comment text ] ; syntax-block = [ extract-syntax text ] ; if $(.option.debug) { ECHO "HELP:" comment block; '$(comment-block)' ; ECHO "HELP:" syntax block; '$(syntax-block)' ; } if [ scan-rule $(syntax-block) : text ] { } else if [ scan-variable $(syntax-block) : text ] { } else if [ scan-class $(syntax-block) ] { } else if [ MATCH .*([cC]opyright).* : $(comment-block:J=" ") ] { # mark as the copy for the module. set-module-copyright $(module-name) : $(comment-block) ; } else if $(action[1]) in "print-help-project" "print-help-config" && ! $(jamfile<$(target)>.docs) { # special module docs for the project jamfile. jamfile<$(target)>.docs = $(comment-block) ; } else if ! $(module-documented) { # document the module. set-module-doc $(module-name) : $(comment-block) ; module-documented = true ; } } if $(action) { $(action[1]) $(module-name) : $(action[2-]) ; }}# Import scan-module to global scope, so that it is available during header# scanning phase.#IMPORT $(__name__) : scan-module : : doc.scan-module ;# Read in a file using the SHELL builtin and return the individual lines as# would be done for header scanning.#local rule read-file ( file # The file to read in.){ file = [ path.native [ path.root [ path.make $(file) ] [ path.pwd ] ] ] ; if ! $(.file<$(file)>.lines) { local content ; switch [ modules.peek : OS ] { case NT : content = [ SHELL "TYPE \"$(file)\"" ] ; case * : content = [ SHELL "cat \"$(file)\"" ] ; } local lines ; local nl = "" ; local << = "([^$(nl)]*)[$(nl)](.*)" ; local line+ = [ MATCH "$(<<)" : "$(content)" ] ; while $(line+) { lines += $(line+[1]) ; line+ = [ MATCH "$(<<)" : "$(line+[2])" ] ; } .file<$(file)>.lines = $(lines) ; } return $(.file<$(file)>.lines) ;}# Add a scan action to perform to generate the help documentation. The action# rule is passed the name of the module as the first argument. The second# argument(s) are optional and passed directly as specified here.#local rule do-scan ( modules + # The modules to scan and perform the action on. : action * # The action rule, plus the secondary arguments to pass to the action rule.){ if $(help-output) = text { print.output $(help-output-file).txt plain ; ALWAYS $(help-output-file).txt ; DEPENDS all : $(help-output-file).txt ; } if $(help-output) = html { print.output $(help-output-file).html html ; ALWAYS $(help-output-file).html ; DEPENDS all : $(help-output-file).html ; } for local module-file in $(modules[1--2]) { scan-module $(module-file) : [ read-file $(module-file) ] ; } scan-module $(modules[-1]) : [ read-file $(modules[-1]) ] : $(action) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -