]> git.lizzy.rs Git - rust.git/commitdiff
mk: rewrite the documentation handling.
authorHuon Wilson <dbau.pp+github@gmail.com>
Sat, 8 Mar 2014 14:41:31 +0000 (01:41 +1100)
committerHuon Wilson <dbau.pp+github@gmail.com>
Sun, 9 Mar 2014 08:34:40 +0000 (19:34 +1100)
This converts it to be very similar to crates.mk, with a single list of
the documentation items creating all the necessary bits and pieces.

Changes include:
- rustdoc is used to render HTML & test standalone docs
- documentation building now obeys NO_REBUILD=1
- testing standalone docs now obeys NO_REBUILD=1
- L10N is slightly less broken (in particular, it shares dependencies
  and code with the rest of the code)
- PDFs can be built for all documentation items, not just tutorial and
  manual
- removes the obsolete & unused extract-tests.py script
- adjust the CSS for standalone docs to use the rustdoc syntax
  highlighting

mk/clean.mk
mk/crates.mk
mk/docs.mk
mk/tests.mk
src/doc/rust.css
src/etc/extract-tests.py [deleted file]

index bc5961a99813165e54e97cdad6f63350f74ca900..73813a4b7512b41a8a32e1d5f16c4b0f47f3ab1d 100644 (file)
@@ -41,7 +41,6 @@ clean-misc:
        @$(call E, cleaning)
        $(Q)rm -f $(RUNTIME_OBJS) $(RUNTIME_DEF)
        $(Q)rm -f $(RUSTLLVM_LIB_OBJS) $(RUSTLLVM_OBJS_OBJS) $(RUSTLLVM_DEF)
-       $(Q)rm -Rf $(DOCS)
        $(Q)rm -Rf $(GENERATED)
        $(Q)rm -Rf tmp/*
        $(Q)rm -Rf rust-stage0-*.tar.bz2 $(PKG_NAME)-*.tar.gz $(PKG_NAME)-*.exe dist
index 45b6ed1a058d0c748266af3359aa545b3ad857aa..70560d41b8d4cc3227286f75a432cc1c862bef35 100644 (file)
@@ -92,6 +92,7 @@ TOOL_SOURCE_rustc := $(S)src/driver/driver.rs
 ################################################################################
 
 DOC_CRATES := $(filter-out rustc, $(filter-out syntax, $(CRATES)))
+COMPILER_DOC_CRATES := rustc syntax
 
 # This macro creates some simple definitions for each crate being built, just
 # some munging of all of the parameters above.
index 7861888482ebe784c347edfba8a640665dc78940..f3fd94678ff136837efd7217849ed4c576393b0f 100644 (file)
@@ -9,24 +9,93 @@
 # except according to those terms.
 
 ######################################################################
-# Doc variables and rules
+# The various pieces of standalone documentation: guides, tutorial,
+# manual etc.
+#
+# The DOCS variable is their names (with no file extension).
+#
+# RUSTDOC_FLAGS_xyz variables are extra arguments to pass to the
+# rustdoc invocation for xyz.
+#
+# RUSTDOC_DEPS_xyz are extra dependencies for the rustdoc invocation
+# on xyz.
+#
+# L10N_LANGS are the languages for which the docs have been
+# translated.
 ######################################################################
+DOCS := index tutorial guide-ffi guide-macros guide-lifetimes \
+       guide-tasks guide-container guide-pointers \
+       complement-cheatsheet guide-runtime \
+       rust
+
+RUSTDOC_DEPS_rust := doc/full-toc.inc
+RUSTDOC_FLAGS_rust := --markdown-in-header=doc/full-toc.inc
+
+L10N_LANGS := ja
+
+# Generally no need to edit below here.
 
-DOCS :=
-CDOCS :=
-DOCS_L10N :=
-HTML_DEPS := doc/
+# The options are passed to the documentation generators.
+RUSTDOC_HTML_OPTS = --markdown-css rust.css \
+       --markdown-before-content=doc/version_info.html \
+       --markdown-in-header=doc/favicon.inc --markdown-after-content=doc/footer.inc
 
-BASE_DOC_OPTS := --standalone --toc --number-sections
-HTML_OPTS = $(BASE_DOC_OPTS) --to=html5 --section-divs --css=rust.css \
-    --include-before-body=doc/version_info.html \
-    --include-in-header=doc/favicon.inc --include-after-body=doc/footer.inc
-TEX_OPTS = $(BASE_DOC_OPTS) --include-before-body=doc/version.md \
-    --from=markdown --include-before-body=doc/footer.tex --to=latex
-EPUB_OPTS = $(BASE_DOC_OPTS) --to=epub
+PANDOC_BASE_OPTS := --standalone --toc --number-sections
+PANDOC_TEX_OPTS = $(PANDOC_BASE_OPTS) --include-before-body=doc/version.md \
+       --from=markdown --include-before-body=doc/footer.tex --to=latex
+PANDOC_EPUB_OPTS = $(PANDOC_BASE_OPTS) --to=epub
+
+
+
+# The rustdoc executable...
+RUSTDOC_EXE = $(HBIN2_H_$(CFG_BUILD))/rustdoc$(X_$(CFG_BUILD))
+# ...with rpath included in case --disable-rpath was provided to
+# ./configure
+RUSTDOC = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(RUSTDOC_EXE)
 
 D := $(S)src/doc
 
+DOC_TARGETS :=
+COMPILER_DOC_TARGETS :=
+DOC_L10N_TARGETS :=
+
+# If NO_REBUILD is set then break the dependencies on rustdoc so we
+# build the documentation without having to rebuild rustdoc.
+ifeq ($(NO_REBUILD),)
+HTML_DEPS := $(RUSTDOC_EXE)
+else
+HTML_DEPS :=
+endif
+
+# Check for the various external utilities for the EPUB/PDF docs:
+
+ifeq ($(CFG_PDFLATEX),)
+  $(info cfg: no pdflatex found, omitting doc/rust.pdf)
+  NO_PDF_DOCS = 1
+else
+  ifeq ($(CFG_XETEX),)
+    $(info cfg: no xetex found, disabling doc/rust.pdf)
+    NO_PDF_DOCS = 1
+  else
+    ifeq ($(CFG_LUATEX),)
+       $(info cfg: lacking luatex, disabling pdflatex)
+       NO_PDF_DOCS = 1
+       endif
+  endif
+endif
+
+
+ifeq ($(CFG_PANDOC),)
+$(info cfg: no pandoc found, omitting PDF and EPUB docs)
+ONLY_HTML_DOCS = 1
+endif
+
+ifeq ($(CFG_NODE),)
+$(info cfg: no node found, omitting PDF and EPUB docs)
+ONLY_HTML_DOCS = 1
+endif
+
+
 ######################################################################
 # Rust version
 ######################################################################
@@ -46,7 +115,7 @@ doc/version_info.html: $(D)/version_info.html.template $(MKFILE_DEPS) \
 GENERATED += doc/version.md doc/version_info.html
 
 ######################################################################
-# Docs, from pandoc, rustdoc (which runs pandoc), and node
+# Docs, from rustdoc and sometimes pandoc & node
 ######################################################################
 
 doc/:
@@ -75,184 +144,78 @@ doc/footer.tex: $(D)/footer.tex | doc/
        @$(call E, cp: $@)
        $(Q)cp -a $< $@ 2> /dev/null
 
-ifeq ($(CFG_PANDOC),)
-  $(info cfg: no pandoc found, omitting docs)
-  NO_DOCS = 1
-endif
+# The (english) documentation for each doc item.
 
-ifeq ($(CFG_NODE),)
-  $(info cfg: no node found, omitting docs)
-  NO_DOCS = 1
-endif
+define DEF_DOC
+
+# HTML (rustdoc)
+DOC_TARGETS += doc/$(1).html
+doc/$(1).html: $$(D)/$(1).md $$(HTML_DEPS) $$(RUSTDOC_DEPS_$(1)) | doc/
+       @$$(call E, rustdoc: $$@)
+       $$(RUSTDOC) $$(RUSTDOC_HTML_OPTS) $$(RUSTDOC_FLAGS_$(1)) $$<
+
+ifneq ($(ONLY_HTML_DOCS),1)
+
+# EPUB (pandoc directly)
+DOC_TARGETS += doc/$(1).epub
+doc/$(1).epub: $$(D)/$(1).md | doc/
+       @$$(call E, pandoc: $$@)
+       $$(Q)$$(CFG_NODE) $$(D)/prep.js --highlight $$< | \
+       $$(CFG_PANDOC) $$(PANDOC_EPUB_OPTS) --output=$$@
+
+# PDF (md =(pandoc)=> tex =(pdflatex)=> pdf)
+DOC_TARGETS += doc/$(1).tex
+doc/$(1).tex: $$(D)/$(1).md doc/footer.tex doc/version.md | doc/
+       @$$(call E, pandoc: $$@)
+       $$(Q)$$(CFG_NODE) $$(D)/prep.js $$< | \
+       $$(CFG_PANDOC) $$(PANDOC_TEX_OPTS) --output=$$@
+
+ifneq ($(NO_PDF_DOCS),1)
+DOC_TARGETS += doc/$(1).pdf
+doc/$(1).pdf: doc/$(1).tex
+       @$$(call E, pdflatex: $$@)
+       $$(Q)$$(CFG_PDFLATEX) \
+       -interaction=batchmode \
+       -output-directory=doc \
+       $$<
+endif # NO_PDF_DOCS
+
+endif # ONLY_HTML_DOCS
+
+endef
+
+$(foreach docname,$(DOCS),$(eval $(call DEF_DOC,$(docname))))
 
-ifneq ($(NO_DOCS),1)
-
-DOCS += doc/rust.html
-doc/rust.html: $(D)/rust.md doc/full-toc.inc $(HTML_DEPS) | doc/
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --include-in-header=doc/full-toc.inc --output=$@
-
-DOCS += doc/rust.tex
-doc/rust.tex: $(D)/rust.md doc/footer.tex doc/version.md | doc/
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js $< | \
-       $(CFG_PANDOC) $(TEX_OPTS) --output=$@
-
-DOCS += doc/rust.epub
-doc/rust.epub: $(D)/rust.md | doc/
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(EPUB_OPTS) --output=$@
-
-DOCS += doc/rustdoc.html
-doc/rustdoc.html: $(D)/rustdoc.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-DOCS += doc/tutorial.html
-doc/tutorial.html: $(D)/tutorial.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-DOCS += doc/tutorial.tex
-doc/tutorial.tex: $(D)/tutorial.md doc/footer.tex doc/version.md
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js $< | \
-       $(CFG_PANDOC) $(TEX_OPTS) --output=$@
-
-DOCS += doc/tutorial.epub
-doc/tutorial.epub: $(D)/tutorial.md
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(EPUB_OPTS) --output=$@
-
-
-DOCS_L10N += doc/l10n/ja/tutorial.html
-doc/l10n/ja/tutorial.html: doc/l10n/ja/tutorial.md doc/version_info.html doc/rust.css
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight doc/l10n/ja/tutorial.md | \
-          $(CFG_PANDOC) --standalone --toc \
-           --section-divs --number-sections \
-           --from=markdown --to=html5 --css=../../rust.css \
-           --include-before-body=doc/version_info.html \
-           --output=$@
-
-# Complementary documentation
+
+# Localized documentation
+
+# FIXME: I (huonw) haven't actually been able to test properly, since
+# e.g. (by default) I'm doing an out-of-tree build (#12763), but even
+# adjusting for that, the files are too old(?) and are rejected by
+# po4a.
 #
-DOCS += doc/index.html
-doc/index.html: $(D)/index.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-DOCS += doc/complement-lang-faq.html
-doc/complement-lang-faq.html: $(D)/complement-lang-faq.md doc/full-toc.inc $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --include-in-header=doc/full-toc.inc --output=$@
-
-DOCS += doc/complement-project-faq.html
-doc/complement-project-faq.html: $(D)/complement-project-faq.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-DOCS += doc/complement-cheatsheet.html
-doc/complement-cheatsheet.html: $(D)/complement-cheatsheet.md doc/full-toc.inc $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --include-in-header=doc/full-toc.inc --output=$@
-
-DOCS += doc/complement-bugreport.html
-doc/complement-bugreport.html: $(D)/complement-bugreport.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-# Guides
-
-DOCS += doc/guide-macros.html
-doc/guide-macros.html: $(D)/guide-macros.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-DOCS += doc/guide-container.html
-doc/guide-container.html: $(D)/guide-container.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-DOCS += doc/guide-ffi.html
-doc/guide-ffi.html: $(D)/guide-ffi.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-DOCS += doc/guide-testing.html
-doc/guide-testing.html: $(D)/guide-testing.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-DOCS += doc/guide-lifetimes.html
-doc/guide-lifetimes.html: $(D)/guide-lifetimes.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-DOCS += doc/guide-tasks.html
-doc/guide-tasks.html: $(D)/guide-tasks.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-DOCS += doc/guide-pointers.html
-doc/guide-pointers.html: $(D)/guide-pointers.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-DOCS += doc/guide-runtime.html
-doc/guide-runtime.html: $(D)/guide-runtime.md $(HTML_DEPS)
-       @$(call E, pandoc: $@)
-       $(Q)$(CFG_NODE) $(D)/prep.js --highlight $< | \
-       $(CFG_PANDOC) $(HTML_OPTS) --output=$@
-
-  ifeq ($(CFG_PDFLATEX),)
-    $(info cfg: no pdflatex found, omitting doc/rust.pdf)
-  else
-    ifeq ($(CFG_XETEX),)
-      $(info cfg: no xetex found, disabling doc/rust.pdf)
-    else
-      ifeq ($(CFG_LUATEX),)
-        $(info cfg: lacking luatex, disabling pdflatex)
-      else
-
-DOCS += doc/rust.pdf
-doc/rust.pdf: doc/rust.tex
-       @$(call E, pdflatex: $@)
-       $(Q)$(CFG_PDFLATEX) \
-        -interaction=batchmode \
-        -output-directory=doc \
-        $<
-
-DOCS += doc/tutorial.pdf
-doc/tutorial.pdf: doc/tutorial.tex
-       @$(call E, pdflatex: $@)
-       $(Q)$(CFG_PDFLATEX) \
-        -interaction=batchmode \
-        -output-directory=doc \
-        $<
-
-      endif
-    endif
-  endif
+# As such, I've attempted to get it working as much as possible (and
+# switching from pandoc to rustdoc), but preserving the old behaviour
+# (e.g. only running on the tutorial)
+.PHONY: l10n-mds
+l10n-mds: $(D)/po4a.conf \
+               $(foreach lang,$(L10N_LANG),$(D)/po/$(lang)/*.md.po)
+       $(warning WARNING: localized documentation is experimental)
+       po4a --copyright-holder="The Rust Project Developers" \
+               --package-name="Rust" \
+               --package-version="$(CFG_RELEASE)" \
+               -M UTF-8 -L UTF-8 \
+               $(D)/po4a.conf
+
+define DEF_L10N_DOC
+DOC_L10N_TARGETS += doc/l10n/$(1)/$(2).html
+doc/l10n/$(1)/$(2).html: l10n-mds $$(HTML_DEPS) $$(RUSTDOC_DEPS_$(2))
+       @$$(call E, rustdoc: $$@)
+       $$(RUSTDOC) $$(RUSTDOC_HTML_OPTS) $$(RUSTDOC_FLAGS_$(1)) doc/l10n/$(1)/$(2).md
+endef
+
+$(foreach lang,$(L10N_LANGS),$(eval $(call DEF_L10N_DOC,$(lang),tutorial)))
 
-endif # No pandoc / node
 
 ######################################################################
 # LLnextgen (grammar analysis from refman)
@@ -278,50 +241,44 @@ endif
 # Rustdoc (libstd/extra)
 ######################################################################
 
-# The rustdoc executable, rpath included in case --disable-rpath was provided to
-# ./configure
-RUSTDOC = $(HBIN2_H_$(CFG_BUILD))/rustdoc$(X_$(CFG_BUILD))
 
 # The library documenting macro
 #
 # $(1) - The crate name (std/extra)
 #
 # Passes --cfg stage2 to rustdoc because it uses the stage2 librustc.
-define libdoc
-doc/$(1)/index.html:                                                       \
-           $$(CRATEFILE_$(1))                                              \
-           $$(RSINPUTS_$(1))                                               \
-           $$(RUSTDOC)                                                     \
-           $$(foreach dep,$$(RUST_DEPS_$(1)),                              \
+define DEF_LIB_DOC
+
+# If NO_REBUILD is set then break the dependencies on rustdoc so we
+# build crate documentation without having to rebuild rustdoc.
+ifeq ($(NO_REBUILD),)
+LIB_DOC_DEP_$(1) = \
+       $$(CRATEFILE_$(1)) \
+       $$(RSINPUTS_$(1)) \
+       $$(RUSTDOC_EXE) \
+       $$(foreach dep,$$(RUST_DEPS_$(1)), \
                $$(TLIB2_T_$(CFG_BUILD)_H_$(CFG_BUILD))/stamp.$$(dep))
-       @$$(call E, rustdoc: $$@)
-       $$(Q)$$(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $$(RUSTDOC) \
-           --cfg stage2 $$<
+else
+LIB_DOC_DEP_$(1) = $$(CRATEFILE_$(1)) $$(RSINPUTS_$(1))
+endif
 
+$(2) += doc/$(1)/index.html
+doc/$(1)/index.html: $$(LIB_DOC_DEP_$(1))
+       @$$(call E, rustdoc $$@)
+       $$(Q)$$(RUSTDOC) --cfg stage2 $$<
 endef
 
-$(foreach crate,$(CRATES),$(eval $(call libdoc,$(crate))))
-
-DOCS += $(DOC_CRATES:%=doc/%/index.html)
-
-CDOCS += doc/rustc/index.html
-CDOCS += doc/syntax/index.html
+$(foreach crate,$(DOC_CRATES),$(eval $(call DEF_LIB_DOC,$(crate),DOC_TARGETS)))
+$(foreach crate,$(COMPILER_DOC_CRATES),$(eval $(call DEF_LIB_DOC,$(crate),COMPILER_DOC_TARGETS)))
 
 ifdef CFG_DISABLE_DOCS
   $(info cfg: disabling doc build (CFG_DISABLE_DOCS))
-  DOCS :=
+  DOC_TARGETS :=
 endif
 
-docs: $(DOCS)
-compiler-docs: $(CDOCS)
-
-docs-l10n: $(DOCS_L10N)
+docs: $(DOC_TARGETS)
+compiler-docs: $(COMPILER_DOC_TARGETS)
 
-doc/l10n/%.md: doc/po/%.md.po doc/po4a.conf
-       po4a --copyright-holder="The Rust Project Developers" \
-            --package-name="Rust" \
-            --package-version="$(CFG_RELEASE)" \
-            -M UTF-8 -L UTF-8 \
-            doc/po4a.conf
+docs-l10n: $(DOC_L10N_TARGETS)
 
 .PHONY: docs-l10n
index c55162d398c2d26e31cbea09679539c207ab53c3..8f48918d31aebf7e45fdde08fc8452f36ac4c611 100644 (file)
@@ -19,12 +19,6 @@ TEST_DOC_CRATES = $(DOC_CRATES)
 TEST_HOST_CRATES = $(HOST_CRATES)
 TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
 
-# Markdown files under doc/ that should have their code extracted and run
-DOC_TEST_NAMES = tutorial guide-ffi guide-macros guide-lifetimes \
-                 guide-tasks guide-container guide-pointers \
-                 complement-cheatsheet guide-runtime \
-                 rust
-
 ######################################################################
 # Environment configuration
 ######################################################################
@@ -318,7 +312,7 @@ check-stage$(1)-T-$(2)-H-$(3)-doc-crates-exec: \
            check-stage$(1)-T-$(2)-H-$(3)-doc-$$(crate)-exec)
 
 check-stage$(1)-T-$(2)-H-$(3)-doc-exec: \
-        $$(foreach docname,$$(DOC_TEST_NAMES), \
+        $$(foreach docname,$$(DOCS), \
            check-stage$(1)-T-$(2)-H-$(3)-doc-$$(docname)-exec)
 
 check-stage$(1)-T-$(2)-H-$(3)-pretty-exec: \
@@ -662,32 +656,56 @@ $(foreach host,$(CFG_HOST), \
    $(foreach pretty-name,$(PRETTY_NAMES), \
     $(eval $(call DEF_RUN_PRETTY_TEST,$(stage),$(target),$(host),$(pretty-name)))))))
 
-define DEF_RUN_DOC_TEST
 
-DOC_TEST_ARGS$(1)-T-$(2)-H-$(3)-doc-$(4) := \
-        $$(CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3))        \
-        --src-base $(3)/test/doc-$(4)/ \
-        --build-base $(3)/test/doc-$(4)/       \
-        --mode run-pass
+######################################################################
+# Crate & freestanding documentation tests
+######################################################################
+
+define DEF_RUSTDOC
+RUSTDOC_EXE_$(1)_T_$(2)_H_$(3) := $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3))
+RUSTDOC_$(1)_T_$(2)_H_$(3) := $$(RPATH_VAR$(1)_T_$(2)_H_$(3)) $$(RUSTDOC_EXE_$(1)_T_$(2)_H_$(3))
+endef
+
+$(foreach host,$(CFG_HOST), \
+ $(foreach target,$(CFG_TARGET), \
+  $(foreach stage,$(STAGES), \
+   $(eval $(call DEF_RUSTDOC,$(stage),$(target),$(host))))))
+
+# Freestanding
+
+define DEF_DOC_TEST
 
 check-stage$(1)-T-$(2)-H-$(3)-doc-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4))
 
-$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): \
-               $$(TEST_SREQ$(1)_T_$(2)_H_$(3))         \
-                doc-$(4)-extract$(3)
-       @$$(call E, run doc-$(4) [$(2)]: $$<)
-       $$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \
-                $$(DOC_TEST_ARGS$(1)-T-$(2)-H-$(3)-doc-$(4)) \
-               --logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),doc-$(4)) \
-                && touch $$@
+# If NO_REBUILD is set then break the dependencies on everything but
+# the source files so we can test documentation without rebuilding
+# rustdoc etc.
+ifeq ($(NO_REBUILD),)
+DOCTESTDEP_$(1)_$(2)_$(3)_$(4) = \
+       $$(D)/$(4).md \
+       $$(TEST_SREQ$(1)_T_$(2)_H_$(3))                         \
+       $$(RUSTDOC_EXE_$(1)_T_$(2)_H_$(3))
+else
+DOCTESTDEP_$(1)_$(2)_$(3)_$(4) = $$(D)/$(4).md
+endif
 
+ifeq ($(2),$$(CFG_BUILD))
+$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): $$(DOCTESTDEP_$(1)_$(2)_$(3)_$(4))
+       @$$(call E, run doc-$(4) [$(2)])
+       $$(Q)$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --test $$< --test-args "$$(TESTARGS)" && touch $$@
+else
+$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)):
+       touch $$@
+endif
 endef
 
 $(foreach host,$(CFG_HOST), \
  $(foreach target,$(CFG_TARGET), \
   $(foreach stage,$(STAGES), \
-   $(foreach docname,$(DOC_TEST_NAMES), \
-    $(eval $(call DEF_RUN_DOC_TEST,$(stage),$(target),$(host),$(docname)))))))
+   $(foreach docname,$(DOCS), \
+    $(eval $(call DEF_DOC_TEST,$(stage),$(target),$(host),$(docname)))))))
+
+# Crates
 
 define DEF_CRATE_DOC_TEST
 
@@ -695,21 +713,20 @@ define DEF_CRATE_DOC_TEST
 # the source files so we can test crate documentation without
 # rebuilding any of the parent crates.
 ifeq ($(NO_REBUILD),)
-DOCTESTDEP_$(1)_$(2)_$(3)_$(4) = \
+CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4) = \
        $$(TEST_SREQ$(1)_T_$(2)_H_$(3))                         \
        $$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4))              \
-       $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3))
+       $$(RUSTDOC_EXE_$(1)_T_$(2)_H_$(3))
 else
-DOCTESTDEP_$(1)_$(2)_$(3)_$(4) = $$(RSINPUTS_$(4))
+CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4) = $$(RSINPUTS_$(4))
 endif
 
 check-stage$(1)-T-$(2)-H-$(3)-doc-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4))
 
 ifeq ($(2),$$(CFG_BUILD))
-$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): $$(DOCTESTDEP_$(1)_$(2)_$(3)_$(4))
+$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): $$(CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4))
        @$$(call E, run doc-$(4) [$(2)])
-       $$(Q)$$(RPATH_VAR$(1)_T_$(2)_H_$(3)) \
-               $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) --test \
+       $$(Q)$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --test \
                $$(CRATEFILE_$(4)) --test-args "$$(TESTARGS)" && touch $$@
 else
 $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)):
@@ -724,26 +741,6 @@ $(foreach host,$(CFG_HOST), \
    $(foreach crate,$(TEST_DOC_CRATES), \
     $(eval $(call DEF_CRATE_DOC_TEST,$(stage),$(target),$(host),$(crate)))))))
 
-######################################################################
-# Extracting tests for docs
-######################################################################
-
-EXTRACT_TESTS := "$(CFG_PYTHON)" $(S)src/etc/extract-tests.py
-
-define DEF_DOC_TEST_HOST
-
-doc-$(2)-extract$(1):
-       @$$(call E, extract: $(2) tests)
-       $$(Q)rm -f $(1)/test/doc-$(2)/*.rs
-       $$(Q)$$(EXTRACT_TESTS) $$(D)/$(2).md $(1)/test/doc-$(2)
-
-endef
-
-$(foreach host,$(CFG_HOST), \
- $(foreach docname,$(DOC_TEST_NAMES), \
-  $(eval $(call DEF_DOC_TEST_HOST,$(host),$(docname)))))
-
-
 ######################################################################
 # Shortcut rules
 ######################################################################
@@ -762,7 +759,7 @@ TEST_GROUPS = \
        debuginfo \
        codegen \
        doc \
-       $(foreach docname,$(DOC_TEST_NAMES),doc-$(docname)) \
+       $(foreach docname,$(DOCS),doc-$(docname)) \
        pretty \
        pretty-rpass \
        pretty-rpass-full \
@@ -830,9 +827,9 @@ $(foreach stage,$(STAGES), \
    $(eval $(call DEF_CHECK_FOR_STAGE_AND_HOSTS_AND_GROUP,$(stage),$(host),$(group))))))
 
 define DEF_CHECK_DOC_FOR_STAGE
-check-stage$(1)-docs: $$(foreach docname,$$(DOC_TEST_NAMES),\
+check-stage$(1)-docs: $$(foreach docname,$$(DOCS),\
                        check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-$$(docname)) \
-                     $$(foreach crate,$$(DOC_CRATE_NAMES),\
+                     $$(foreach crate,$$(TEST_DOC_CRATES),\
                        check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-$$(crate))
 endef
 
index 17100274688f7de2ed48fbe59510fcd542194a78..26681adad6d78bff14ada65bb7eed8f304153da2 100644 (file)
@@ -142,25 +142,18 @@ pre code {
 }
 
 /* Code highlighting */
-.cm-s-default span.cm-keyword {color: #8959A8;}
-.cm-s-default span.cm-atom {color: #219;}
-.cm-s-default span.cm-number {color: #3E999F;}
-.cm-s-default span.cm-def {color: #4271AE;}
-/*.cm-s-default span.cm-variable {color: #C82829;}*/
-.cm-s-default span.cm-variable-2 {color: #6F906C;}
-.cm-s-default span.cm-variable-3 {color: #B76514;}
-.cm-s-default span.cm-property {color: black;}
-.cm-s-default span.cm-operator {color: black;}
-.cm-s-default span.cm-comment {color: #8E908C;}
-.cm-s-default span.cm-string {color: #718C00;}
-.cm-s-default span.cm-string-2 {color: #866544;}
-.cm-s-default span.cm-meta {color: #555;}
-/*.cm-s-default span.cm-error {color: #F00;}*/
-.cm-s-default span.cm-qualifier {color: #555;}
-.cm-s-default span.cm-builtin {color: #30A;}
-.cm-s-default span.cm-bracket {color: #CC7;}
-.cm-s-default span.cm-tag {color: #C82829;}
-.cm-s-default span.cm-attribute {color: #00C;}
+pre.rust .kw { color: #8959A8; }
+pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
+pre.rust .number { color: #718C00; }
+pre.rust .self { color: #C13928; }
+pre.rust .boolval { color: #C13928; }
+pre.rust .prelude-val { color: #C13928; }
+pre.rust .comment { color: #8E908C; }
+pre.rust .doccomment { color: #4D4D4C; }
+pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999f; }
+pre.rust .string { color: #718C00; }
+pre.rust .lifetime { color: #C13928; }
+pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; }
 
 /* The rest
    ========================================================================== */
diff --git a/src/etc/extract-tests.py b/src/etc/extract-tests.py
deleted file mode 100644 (file)
index 2900023..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-# Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-# file at the top-level directory of this distribution and at
-# http://rust-lang.org/COPYRIGHT.
-#
-# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-# option. This file may not be copied, modified, or distributed
-# except according to those terms.
-
-"""
-Script for extracting compilable fragments from markdown documentation. See
-prep.js for a description of the format recognized by this tool. Expects
-a directory fragments/ to exist under the current directory, and writes the
-fragments in there as individual .rs files.
-"""
-from __future__ import print_function
-from codecs import open
-from collections import deque
-from itertools import imap
-import os
-import re
-import sys
-
-# regexes
-CHAPTER_NAME_REGEX = re.compile(r'# (.*)')
-CODE_BLOCK_DELIM_REGEX = re.compile(r'~~~')
-COMMENT_REGEX = re.compile(r'^# ')
-COMPILER_DIRECTIVE_REGEX = re.compile(r'\#\[(.*)\];')
-ELLIPSES_REGEX = re.compile(r'\.\.\.')
-EXTERN_CRATE_REGEX = re.compile(r'\bextern crate extra\b')
-MAIN_FUNCTION_REGEX = re.compile(r'\bfn main\b')
-TAGS_REGEX = re.compile(r'\.([\w-]*)')
-
-# tags to ignore
-IGNORE_TAGS = \
-        frozenset(["abnf", "ebnf", "field", "keyword", "notrust", "precedence"])
-
-# header for code snippet files
-OUTPUT_BLOCK_HEADER = '\n'.join((
-    "#[ deny(warnings) ];",
-    "#[ allow(unused_variable) ];",
-    "#[ allow(dead_assignment) ];",
-    "#[ allow(unused_mut) ];",
-    "#[ allow(attribute_usage) ];",
-    "#[ allow(dead_code) ];",
-    "#[ feature(macro_rules, globs, struct_variant, managed_boxes) ];\n",))
-
-
-def add_extern_mod(block):
-    if not has_extern_mod(block):
-        # add `extern crate extra;` after compiler directives
-        directives = []
-        while len(block) and is_compiler_directive(block[0]):
-            directives.append(block.popleft())
-
-        block.appendleft("\nextern crate extra;\n\n")
-        block.extendleft(reversed(directives))
-
-    return block
-
-
-def add_main_function(block):
-    if not has_main_function(block):
-        prepend_spaces = lambda x: '    ' + x
-        block = deque(imap(prepend_spaces, block))
-        block.appendleft("\nfn main() {\n")
-        block.append("\n}\n")
-    return block
-
-
-def extract_code_fragments(dest_dir, lines):
-    """
-    Extracts all the code fragments from a file that do not have ignored tags
-    writing them to the following file:
-
-        [dest dir]/[chapter name]_[chapter_index].rs
-    """
-    chapter_name = None
-    chapter_index = 0
-
-    for line in lines:
-        if is_chapter_title(line):
-            chapter_name = get_chapter_name(line)
-            chapter_index = 1
-            continue
-
-        if not is_code_block_delim(line):
-            continue
-
-        assert chapter_name, "Chapter name missing for code block."
-        tags = get_tags(line)
-        block = get_code_block(lines)
-
-        if tags & IGNORE_TAGS:
-            continue
-
-        block = add_extern_mod(add_main_function(block))
-        block.appendleft(OUTPUT_BLOCK_HEADER)
-
-        if "ignore" in tags:
-            block.appendleft("//ignore-test\n")
-        elif "should_fail" in tags:
-            block.appendleft("//should-fail\n")
-
-        output_filename = os.path.join(
-                dest_dir,
-                chapter_name + '_' + str(chapter_index) + '.rs')
-
-        write_file(output_filename, block)
-        chapter_index += 1
-
-
-def has_extern_mod(block):
-    """Checks if a code block has the line `extern crate extra`."""
-    find_extern_mod = lambda x: re.search(EXTERN_CRATE_REGEX, x)
-    return any(imap(find_extern_mod, block))
-
-
-def has_main_function(block):
-    """Checks if a code block has a main function."""
-    find_main_fn = lambda x: re.search(MAIN_FUNCTION_REGEX, x)
-    return any(imap(find_main_fn, block))
-
-
-def is_chapter_title(line):
-    return re.match(CHAPTER_NAME_REGEX, line)
-
-
-def is_code_block_delim(line):
-    return re.match(CODE_BLOCK_DELIM_REGEX, line)
-
-
-def is_compiler_directive(line):
-    return re.match(COMPILER_DIRECTIVE_REGEX, line)
-
-
-def get_chapter_name(line):
-    """Get the chapter name from a `# Containers` line."""
-    return re.sub(
-            r'\W',
-            '_',
-            re.match(CHAPTER_NAME_REGEX, line).group(1)).lower()
-
-
-def get_code_block(lines):
-    """
-    Get a code block surrounded by ~~~, for example:
-
-        1: ~~~ { .tag }
-        2: let u: ~[u32] = ~[0, 1, 2];
-        3: let v: &[u32] = &[0, 1, 2, 3];
-        4: let w: [u32, .. 5] = [0, 1, 2, 3, 4];
-        5:
-        6: println!("u: {}, v: {}, w: {}", u.len(), v.len(), w.len());
-        7: ~~~
-
-    Returns lines 2-6. Assumes line 1 has been consumed by the caller.
-    """
-    strip_comments = lambda x: re.sub(COMMENT_REGEX, '', x)
-    strip_ellipses = lambda x: re.sub(ELLIPSES_REGEX, '', x)
-
-    result = deque()
-
-    for line in lines:
-        if is_code_block_delim(line):
-            break
-        result.append(strip_comments(strip_ellipses(line)))
-    return result
-
-
-def get_lines(filename):
-    with open(filename) as f:
-        for line in f:
-            yield line
-
-
-def get_tags(line):
-    """
-    Retrieves all tags from the line format:
-        ~~~ { .tag1 .tag2 .tag3 }
-    """
-    return set(re.findall(TAGS_REGEX, line))
-
-
-def write_file(filename, lines):
-    with open(filename, 'w', encoding='utf-8') as f:
-        for line in lines:
-            f.write(unicode(line, encoding='utf-8', errors='replace'))
-
-
-def main(argv=None):
-    if not argv:
-        argv = sys.argv
-
-    if len(sys.argv) < 2:
-        sys.stderr.write("Please provide an input filename.")
-        sys.exit(1)
-    elif len(sys.argv) < 3:
-        sys.stderr.write("Please provide a destination directory.")
-        sys.exit(1)
-
-    input_file = sys.argv[1]
-    dest_dir = sys.argv[2]
-
-    if not os.path.exists(input_file):
-        sys.stderr.write("Input file does not exist.")
-        sys.exit(1)
-
-    if not os.path.exists(dest_dir):
-        os.mkdir(dest_dir)
-
-    extract_code_fragments(dest_dir, get_lines(input_file))
-
-
-if __name__ == "__main__":
-    sys.exit(main())