diff options
author | 2016-08-29 10:25:17 +0000 | |
---|---|---|
committer | 2016-08-29 12:59:49 +0000 | |
commit | 915dbdf187d52fda5547b5336e21339dceeb8e37 (patch) | |
tree | cdf8f59e41abdd7cebfd1dab55c70aed26bad493 /src/main/java/com/google/devtools/build | |
parent | 3bae1defc1d6198a7d73a616e2c448011250782d (diff) |
Implement generating single-page Build Encyclopedia.
* Adds a --single_page flag to the BE docgen for generating a single-page
version of the Build Encyclopedia.
* Refactor BuildEncyclopediaProcessor common logic into a base class and add
subclasses for generating single- and multi-page BE respectively.
* Enable RuleLinkExpander to expand rule references to single-page hrefs
(headings on the current page).
* Update docgen velocity templates to use RuleLinkExpander to ensure links are
correct on both single- and multi-page versions of the BE.
--
MOS_MIGRATED_REVID=131574793
Diffstat (limited to 'src/main/java/com/google/devtools/build')
16 files changed, 502 insertions, 149 deletions
diff --git a/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java b/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java index 00e1d50f30..69bad6c867 100644 --- a/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java +++ b/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java @@ -25,7 +25,6 @@ import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.RuleClass; - import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -48,18 +47,17 @@ public class BuildDocCollector { private ConfiguredRuleClassProvider ruleClassProvider; private boolean printMessages; - public BuildDocCollector(ConfiguredRuleClassProvider ruleClassProvider, - boolean printMessages) { + public BuildDocCollector(ConfiguredRuleClassProvider ruleClassProvider, boolean printMessages) { this.ruleClassProvider = ruleClassProvider; this.printMessages = printMessages; } /** - * Parse the file containing black-listed rules for documentation. The list is simply a list of + * Parse the file containing blacklisted rules for documentation. The list is simply a list of * rules separated by new lines. Line comments can be added to the file by starting them with #. * - * @param blackList The name of the file containing the black list. - * @return The set of black listed rules. + * @param blackList The name of the file containing the blacklist. + * @return The set of blacklisted rules. * @throws IOException */ @VisibleForTesting @@ -80,14 +78,27 @@ public class BuildDocCollector { } /** - * Collects all the rule and attribute documentation present in inputDirs, integrates the - * attribute documentation in the rule documentation and returns the rule documentation. + * Creates a map of rule names (keys) to rule documentation (values). + * + * <p>This method crawls the specified input directories for rule class definitions (as Java + * source files) which contain the rules' and attributes' definitions as comments in a + * specific format. The keys in the returned Map correspond to these rule classes. + * + * <p>In the Map's values, all references pointing to other rules, rule attributes, and general + * documentation (e.g. common definitions, make variables, etc.) are expanded into hyperlinks. + * The links generated follow either the multi-page or single-page Build Encyclopedia model + * depending on the mode set for the provided {@link RuleLinkExpander}. * * @param inputDirs list of directories to scan for documentation - * @param blackList specify an optional black list file that list some rules that should + * @param blackList specify an optional blacklist file that list some rules that should * not be listed in the output. + * @param expander The RuleLinkExpander, which is used for expanding links in the rule doc. + * @throws BuildEncyclopediaDocException + * @throws IOException + * @return Map of rule class to rule documentation. */ - public Map<String, RuleDocumentation> collect(List<String> inputDirs, String blackList) + public Map<String, RuleDocumentation> collect( + List<String> inputDirs, String blackList, RuleLinkExpander expander) throws BuildEncyclopediaDocException, IOException { // Read the blackList file Set<String> blacklistedRules = readBlackList(blackList); @@ -122,7 +133,7 @@ public class BuildDocCollector { } processAttributeDocs(ruleDocEntries.values(), attributeDocEntries); - RuleLinkExpander expander = buildRuleLinkExpander(ruleDocEntries.values()); + expander.addIndex(buildRuleIndex(ruleDocEntries.values())); for (RuleDocumentation rule : ruleDocEntries.values()) { rule.setRuleLinkExpander(expander); } @@ -130,14 +141,38 @@ public class BuildDocCollector { } /** + * Creates a map of rule names (keys) to rule documentation (values). + * + * <p>This method crawls the specified input directories for rule class definitions (as Java + * source files) which contain the rules' and attributes' definitions as comments in a + * specific format. The keys in the returned Map correspond to these rule classes. + * + * <p>In the Map's values, all references pointing to other rules, rule attributes, and general + * documentation (e.g. common definitions, make variables, etc.) are expanded into hyperlinks. + * The links generated follow the multi-page Build Encyclopedia model (one page per rule clas.). + * + * @param inputDirs list of directories to scan for documentation + * @param blackList specify an optional blacklist file that list some rules that should + * not be listed in the output. + * @throws BuildEncyclopediaDocException + * @throws IOException + * @return Map of rule class to rule documentation. + */ + public Map<String, RuleDocumentation> collect(List<String> inputDirs, String blackList) + throws BuildEncyclopediaDocException, IOException { + RuleLinkExpander expander = new RuleLinkExpander(/* singlePage */ false); + return collect(inputDirs, blackList, expander); + } + + /** * Generates an index mapping rule name to its normalized rule family name. */ - private RuleLinkExpander buildRuleLinkExpander(Iterable<RuleDocumentation> rules) { + private Map<String, String> buildRuleIndex(Iterable<RuleDocumentation> rules) { Map<String, String> index = new HashMap<>(); for (RuleDocumentation rule : rules) { index.put(rule.getRuleName(), RuleFamily.normalize(rule.getRuleFamily())); } - return new RuleLinkExpander(index); + return index; } /** @@ -200,8 +235,28 @@ public class BuildDocCollector { } /** - * Goes through all the html files and subdirs under inputPath and collects the rule - * and attribute documentations using the ruleDocEntries and attributeDocEntries variable. + * Crawls the specified inputPath and collects the raw rule and rule attribute documentation. + * + * <p>This method crawls the specified input directory (recursively calling itself for all + * subdirectories) and reads each Java source file using {@link SourceFileReader} to extract the + * raw rule and attribute documentation embedded in comments in a specific format. The extracted + * documentation is then further processed, such as by + * {@link BuildDocCollector#collect(List<String>, String, RuleLinkExpander), collect}, in order + * to associate each rule's documentation with its attribute documentation. + * + * <p>This method returns the following through its parameters: the set of Java source files + * processed, a map of rule name to the source file it was extracted from, a map of rule name + * to the documentation to the rule, and a multimap of attribute name to attribute documentation. + * + * @param processedFiles The set of Java source files files that have already been processed + * in order to avoid reprocessing the same file. + * @param ruleClassFiles Map of rule name to the source file it was extracted from. + * @param ruleDocEntries Map of rule name to rule documentation. + * @param blackList The set of blacklisted rules whose documentation should not be extracted. + * @param attributeDocEntries Multimap of rule attribute name to attribute documentation. + * @param inputPath The File representing the file or directory to read. + * @throws BuildEncyclopediaDocException + * @throws IOException */ public void collectDocs( Set<File> processedFiles, @@ -216,8 +271,7 @@ public class BuildDocCollector { if (inputPath.isFile()) { if (DocgenConsts.JAVA_SOURCE_FILE_SUFFIX.apply(inputPath.getName())) { - SourceFileReader sfr = new SourceFileReader( - ruleClassProvider, inputPath.getAbsolutePath()); + SourceFileReader sfr = new SourceFileReader(ruleClassProvider, inputPath.getAbsolutePath()); sfr.readDocsFromComments(); for (RuleDocumentation d : sfr.getRuleDocEntries()) { String ruleName = d.getRuleName(); diff --git a/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaGenerator.java b/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaGenerator.java index 64c0584a7d..bc38cfc7e7 100644 --- a/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaGenerator.java +++ b/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaGenerator.java @@ -15,7 +15,6 @@ package com.google.devtools.build.docgen; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.common.options.OptionsParser; - import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collections; @@ -28,7 +27,7 @@ public class BuildEncyclopediaGenerator { private static void printUsage(OptionsParser parser) { System.err.println( "Usage: docgen_bin -p rule_class_provider (-i input_dir)+\n" - + " [-o outputdir] [-b blacklist] [-h]\n\n" + + " [-o outputdir] [-b blacklist] [-1] [-h]\n\n" + "Generates the Build Encyclopedia from embedded native rule documentation.\n" + "The rule class provider (-p) and at least one input_dir (-i) must be specified.\n"); System.err.println( @@ -69,8 +68,14 @@ public class BuildEncyclopediaGenerator { } try { - BuildEncyclopediaProcessor processor = new BuildEncyclopediaProcessor( - createRuleClassProvider(options.provider)); + BuildEncyclopediaProcessor processor = null; + if (options.singlePage) { + processor = new SinglePageBuildEncyclopediaProcessor( + createRuleClassProvider(options.provider)); + } else { + processor = new MultiPageBuildEncyclopediaProcessor( + createRuleClassProvider(options.provider)); + } processor.generateDocumentation( options.inputDirs, options.outputDir, options.blacklist); } catch (BuildEncyclopediaDocException e) { diff --git a/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaOptions.java b/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaOptions.java index f75dc6a82b..92e51a219f 100644 --- a/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaOptions.java +++ b/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaOptions.java @@ -15,7 +15,6 @@ package com.google.devtools.build.docgen; import com.google.devtools.common.options.Option; import com.google.devtools.common.options.OptionsBase; - import java.util.List; /** @@ -56,6 +55,14 @@ public class BuildEncyclopediaOptions extends OptionsBase { public String blacklist; @Option( + name = "single_page", + abbrev = '1', + defaultValue = "false", + help = "Whether to generate the BE as a single HTML page or one page per rule family." + ) + public boolean singlePage; + + @Option( name = "help", abbrev = 'h', defaultValue = "false", diff --git a/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaProcessor.java b/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaProcessor.java index c6bf396441..7abe7f12c1 100644 --- a/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaProcessor.java +++ b/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaProcessor.java @@ -21,11 +21,9 @@ import com.google.common.collect.Iterables; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.ListMultimap; import com.google.common.collect.Ordering; -import com.google.common.collect.Sets; import com.google.devtools.build.docgen.DocgenConsts.RuleType; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.packages.RuleClass; - import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -33,22 +31,21 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.TreeMap; import java.util.TreeSet; /** * A class to assemble documentation for the Build Encyclopedia. This class uses * {@link BuildDocCollector} to extract documentation fragments from rule classes. */ -public class BuildEncyclopediaProcessor { - private static final Predicate<String> RULE_WORTH_DOCUMENTING = new Predicate<String>() { +public abstract class BuildEncyclopediaProcessor { + protected static final Predicate<String> RULE_WORTH_DOCUMENTING = new Predicate<String>() { @Override public boolean apply(String name) { return !name.contains("$"); } }; - private ConfiguredRuleClassProvider ruleClassProvider; + protected ConfiguredRuleClassProvider ruleClassProvider; /** * Creates the BuildEncyclopediaProcessor instance. The ruleClassProvider parameter @@ -67,49 +64,27 @@ public class BuildEncyclopediaProcessor { * @param outputRootDir output directory where to write the build encyclopedia * @param blackList optional path to a file listing rules to not document */ - public void generateDocumentation(List<String> inputDirs, String outputDir, String blackList) - throws BuildEncyclopediaDocException, IOException { - writeStaticPage(outputDir, "make-variables"); - writeStaticPage(outputDir, "predefined-python-variables"); - writeStaticPage(outputDir, "functions"); - writeCommonDefinitionsPage(outputDir); - - BuildDocCollector collector = new BuildDocCollector(ruleClassProvider, false); - Map<String, RuleDocumentation> ruleDocEntries = collector.collect(inputDirs, blackList); - warnAboutUndocumentedRules( - Sets.difference(ruleClassProvider.getRuleClassMap().keySet(), ruleDocEntries.keySet())); - - writeRuleDocs(outputDir, ruleDocEntries.values()); - } - - private void writeStaticPage(String outputDir, String name) throws IOException { - File file = new File(outputDir + "/" + name + ".html"); - Page page = TemplateEngine.newPage( - "com/google/devtools/build/docgen/templates/be/" + name + ".vm"); - page.write(file); - } + public abstract void generateDocumentation(List<String> inputDirs, String outputDir, + String blackList) throws BuildEncyclopediaDocException, IOException; - private void writeCommonDefinitionsPage(String outputDir) throws IOException { - File file = new File(outputDir + "/common-definitions.html"); - Page page = TemplateEngine.newPage(DocgenConsts.COMMON_DEFINITIONS_TEMPLATE); - page.add("commonAttributes", PredefinedAttributes.COMMON_ATTRIBUTES); - page.add("testAttributes", PredefinedAttributes.TEST_ATTRIBUTES); - page.add("binaryAttributes", PredefinedAttributes.BINARY_ATTRIBUTES); - page.write(file); - } - - private List<RuleFamily> assembleRuleFamilies( - Map<String, ListMultimap<RuleType, RuleDocumentation>> ruleMapping, - Set<String> ruleFamilyNames) { - List<RuleFamily> ruleFamilies = new ArrayList<>(ruleFamilyNames.size()); - for (String name : ruleFamilyNames) { - ListMultimap<RuleType, RuleDocumentation> ruleTypeMap = ruleMapping.get(name); - ruleFamilies.add(new RuleFamily(ruleTypeMap, name)); + /** + * POD class for containing lists of rule families separated into language-specific and generic as + * returned by {@link #assembleRuleFamilies(Iterable<RuleDocumentation>) assembleRuleFamilies}. + */ + protected static class RuleFamilies { + public List<RuleFamily> langSpecific; + public List<RuleFamily> generic; + public List<RuleFamily> all; + + public RuleFamilies(List<RuleFamily> langSpecific, List<RuleFamily> generic, + List<RuleFamily> all) { + this.langSpecific = langSpecific; + this.generic = generic; + this.all = all; } - return ruleFamilies; } - private void writeRuleDocs(String outputDir, Iterable<RuleDocumentation> docEntries) + protected RuleFamilies assembleRuleFamilies(Iterable<RuleDocumentation> docEntries) throws BuildEncyclopediaDocException, IOException { // Separate rule families into language-specific and generic ones. Set<String> langSpecificRuleFamilyNames = new TreeSet<>(); @@ -125,46 +100,23 @@ public class BuildEncyclopediaProcessor { // the Overview page while the list containing all rule families will be used to // generate all other documentation. List<RuleFamily> langSpecificRuleFamilies = - assembleRuleFamilies(ruleMapping, langSpecificRuleFamilyNames); + filterRuleFamilies(ruleMapping, langSpecificRuleFamilyNames); List<RuleFamily> genericRuleFamilies = - assembleRuleFamilies(ruleMapping, genericRuleFamilyNames); + filterRuleFamilies(ruleMapping, genericRuleFamilyNames); List<RuleFamily> allRuleFamilies = new ArrayList<>(langSpecificRuleFamilies); allRuleFamilies.addAll(genericRuleFamilies); - - // Generate documentation. - writeOverviewPage(outputDir, langSpecificRuleFamilies, genericRuleFamilies); - writeBeNav(outputDir, allRuleFamilies); - for (RuleFamily ruleFamily : allRuleFamilies) { - if (ruleFamily.size() > 0) { - writeRuleDoc(outputDir, ruleFamily); - } - } - } - - private void writeOverviewPage(String outputDir, - List<RuleFamily> langSpecificRuleFamilies, - List<RuleFamily> genericRuleFamilies) - throws BuildEncyclopediaDocException, IOException { - File file = new File(outputDir + "/overview.html"); - Page page = TemplateEngine.newPage(DocgenConsts.OVERVIEW_TEMPLATE); - page.add("langSpecificRuleFamilies", langSpecificRuleFamilies); - page.add("genericRuleFamilies", genericRuleFamilies); - page.write(file); - } - - private void writeRuleDoc(String outputDir, RuleFamily ruleFamily) - throws BuildEncyclopediaDocException, IOException { - File file = new File(outputDir + "/" + ruleFamily.getId() + ".html"); - Page page = TemplateEngine.newPage(DocgenConsts.RULES_TEMPLATE); - page.add("ruleFamily", ruleFamily); - page.write(file); + return new RuleFamilies(langSpecificRuleFamilies, genericRuleFamilies, allRuleFamilies); } - private void writeBeNav(String outputDir, List<RuleFamily> ruleFamilies) throws IOException { - File file = new File(outputDir + "/be-nav.html"); - Page page = TemplateEngine.newPage(DocgenConsts.BE_NAV_TEMPLATE); - page.add("ruleFamilies", ruleFamilies); - page.write(file); + private List<RuleFamily> filterRuleFamilies( + Map<String, ListMultimap<RuleType, RuleDocumentation>> ruleMapping, + Set<String> ruleFamilyNames) { + List<RuleFamily> ruleFamilies = new ArrayList<>(ruleFamilyNames.size()); + for (String name : ruleFamilyNames) { + ListMultimap<RuleType, RuleDocumentation> ruleTypeMap = ruleMapping.get(name); + ruleFamilies.add(new RuleFamily(ruleTypeMap, name)); + } + return ruleFamilies; } /** @@ -212,10 +164,50 @@ public class BuildEncyclopediaProcessor { } } - private static void warnAboutUndocumentedRules(Iterable<String> rulesWithoutDocumentation) { + /** + * Helper method for displaying an warning message about undocumented rules. + * + * @param rulesWithoutDocumentation Undocumented rules to list in the warning message. + */ + protected static void warnAboutUndocumentedRules(Iterable<String> rulesWithoutDocumentation) { Iterable<String> undocumentedRules = Iterables.filter(rulesWithoutDocumentation, RULE_WORTH_DOCUMENTING); System.err.printf("WARNING: The following rules are undocumented: [%s]\n", Joiner.on(", ").join(Ordering.<String>natural().immutableSortedCopy(undocumentedRules))); } + + /** + * Sets the {@link RuleLinkExpander} for the provided {@link RuleDocumentationAttributes}. + * + * <p>This method is used to set the {@link RuleLinkExpander} for common attributes, such as + * those defined in {@link PredefinedAttributes}, so that rule references in the docs for those + * attributes can be expanded. + * + * @param attributes The map containing the RuleDocumentationAttributes, keyed by attribute name. + * @param expander The RuleLinkExpander to set in each of the RuleDocumentationAttributes. + * @return A map of name to RuleDocumentationAttribute with the RuleLinkExpander set for each + * attribute. + */ + protected static Map<String, RuleDocumentationAttribute> expandCommonAttributes( + Map<String, RuleDocumentationAttribute> attributes, RuleLinkExpander expander) { + Map<String, RuleDocumentationAttribute> expanded = new HashMap<>(attributes.size()); + for (Map.Entry<String, RuleDocumentationAttribute> entry : attributes.entrySet()) { + RuleDocumentationAttribute attribute = entry.getValue(); + attribute.setRuleLinkExpander(expander); + expanded.put(entry.getKey(), attribute); + } + return expanded; + } + + /** + * Writes the {@link Page} using the provided file name in the specified output directory. + * + * @param page The page to write. + * @param outputDir The output directory to write the file. + * @param fileName The name of the file to write the page to. + * @throws IOException + */ + protected static void writePage(Page page, String outputDir, String fileName) throws IOException { + page.write(new File(outputDir + "/" + fileName)); + } } diff --git a/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java b/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java index 610c15c6dd..5209d4f35b 100644 --- a/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java +++ b/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java @@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.util.FileTypeSet; - import java.util.Map; import java.util.regex.Pattern; @@ -29,14 +28,14 @@ public class DocgenConsts { public static final String LS = "\n"; + public static final String BE_TEMPLATE_DIR = + "com/google/devtools/build/docgen/templates/be"; + public static final String SINGLE_BE_TEMPLATE = BE_TEMPLATE_DIR + "/single-page.vm"; public static final String COMMON_DEFINITIONS_TEMPLATE = - "com/google/devtools/build/docgen/templates/be/common-definitions.vm"; - public static final String OVERVIEW_TEMPLATE = - "com/google/devtools/build/docgen/templates/be/overview.vm"; - public static final String RULES_TEMPLATE = - "com/google/devtools/build/docgen/templates/be/rules.vm"; - public static final String BE_NAV_TEMPLATE = - "com/google/devtools/build/docgen/templates/be/be-nav.vm"; + BE_TEMPLATE_DIR + "/common-definitions.vm"; + public static final String OVERVIEW_TEMPLATE = BE_TEMPLATE_DIR + "/overview.vm"; + public static final String RULES_TEMPLATE = BE_TEMPLATE_DIR + "/rules.vm"; + public static final String BE_NAV_TEMPLATE = BE_TEMPLATE_DIR + "/be-nav.vm"; public static final String SKYLARK_LIBRARY_TEMPLATE = "com/google/devtools/build/docgen/templates/skylark-library.vm"; diff --git a/src/main/java/com/google/devtools/build/docgen/MultiPageBuildEncyclopediaProcessor.java b/src/main/java/com/google/devtools/build/docgen/MultiPageBuildEncyclopediaProcessor.java new file mode 100644 index 0000000000..9c3a95153f --- /dev/null +++ b/src/main/java/com/google/devtools/build/docgen/MultiPageBuildEncyclopediaProcessor.java @@ -0,0 +1,118 @@ +// Copyright 2014 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.docgen; + +import com.google.common.collect.Sets; +import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * Assembles the multi-page version of the Build Encyclopedia with one page per rule family. + */ +public class MultiPageBuildEncyclopediaProcessor extends BuildEncyclopediaProcessor { + public MultiPageBuildEncyclopediaProcessor(ConfiguredRuleClassProvider ruleClassProvider) { + super(ruleClassProvider); + } + + /** + * Collects and processes all the rule and attribute documentation in inputDirs and + * generates the Build Encyclopedia into the outputDir. + * + * @param inputDirs list of directory to scan for document in the source code + * @param outputDir output directory where to write the build encyclopedia + * @param blackList optional path to a file listing rules to not document + */ + @Override + public void generateDocumentation(List<String> inputDirs, String outputDir, String blackList) + throws BuildEncyclopediaDocException, IOException { + BuildDocCollector collector = new BuildDocCollector(ruleClassProvider, false); + RuleLinkExpander expander = new RuleLinkExpander(false); + Map<String, RuleDocumentation> ruleDocEntries = collector.collect( + inputDirs, blackList, expander); + warnAboutUndocumentedRules( + Sets.difference(ruleClassProvider.getRuleClassMap().keySet(), ruleDocEntries.keySet())); + + writeStaticDoc(outputDir, expander, "make-variables"); + writeStaticDoc(outputDir, expander, "predefined-python-variables"); + writeStaticDoc(outputDir, expander, "functions"); + writeCommonDefinitionsPage(outputDir, expander); + + writeRuleDocs(outputDir, expander, ruleDocEntries.values()); + } + + private void writeStaticDoc(String outputDir, RuleLinkExpander expander, String name) + throws IOException { + // TODO(dzc): Consider splitting out the call to writePage so that this method only creates the + // Page object and adding docgen tests that test the state of Page objects constructed by + // this method, and similar methods in this class. + Page page = TemplateEngine.newPage(DocgenConsts.BE_TEMPLATE_DIR + "/" + name + ".vm"); + page.add("expander", expander); + writePage(page, outputDir, name + ".html"); + } + + private void writeCommonDefinitionsPage(String outputDir, RuleLinkExpander expander) + throws IOException { + Page page = TemplateEngine.newPage(DocgenConsts.COMMON_DEFINITIONS_TEMPLATE); + page.add("expander", expander); + page.add("commonAttributes", + expandCommonAttributes(PredefinedAttributes.COMMON_ATTRIBUTES, expander)); + page.add("testAttributes", + expandCommonAttributes(PredefinedAttributes.TEST_ATTRIBUTES, expander)); + page.add("binaryAttributes", + expandCommonAttributes(PredefinedAttributes.BINARY_ATTRIBUTES, expander)); + writePage(page, outputDir, "common-definitions.html"); + } + + private void writeRuleDocs(String outputDir, RuleLinkExpander expander, + Iterable<RuleDocumentation> docEntries) throws BuildEncyclopediaDocException, IOException { + RuleFamilies ruleFamilies = assembleRuleFamilies(docEntries); + + // Generate documentation. + writeOverviewPage(outputDir, expander, ruleFamilies.langSpecific, ruleFamilies.generic); + writeBeNav(outputDir, ruleFamilies.all); + for (RuleFamily ruleFamily : ruleFamilies.all) { + if (ruleFamily.size() > 0) { + writeRuleDoc(outputDir, ruleFamily); + } + } + } + + private void writeOverviewPage(String outputDir, + RuleLinkExpander expander, + List<RuleFamily> langSpecificRuleFamilies, + List<RuleFamily> genericRuleFamilies) + throws BuildEncyclopediaDocException, IOException { + Page page = TemplateEngine.newPage(DocgenConsts.OVERVIEW_TEMPLATE); + page.add("expander", expander); + page.add("langSpecificRuleFamilies", langSpecificRuleFamilies); + page.add("genericRuleFamilies", genericRuleFamilies); + writePage(page, outputDir, "overview.html"); + } + + private void writeRuleDoc(String outputDir, RuleFamily ruleFamily) + throws BuildEncyclopediaDocException, IOException { + Page page = TemplateEngine.newPage(DocgenConsts.RULES_TEMPLATE); + page.add("ruleFamily", ruleFamily); + writePage(page, outputDir, ruleFamily.getId() + ".html"); + } + + private void writeBeNav(String outputDir, List<RuleFamily> ruleFamilies) throws IOException { + Page page = TemplateEngine.newPage(DocgenConsts.BE_NAV_TEMPLATE); + page.add("ruleFamilies", ruleFamilies); + writePage(page, outputDir, "be-nav.html"); + } +} diff --git a/src/main/java/com/google/devtools/build/docgen/RuleLinkExpander.java b/src/main/java/com/google/devtools/build/docgen/RuleLinkExpander.java index d73bf5305e..4f74054fe1 100644 --- a/src/main/java/com/google/devtools/build/docgen/RuleLinkExpander.java +++ b/src/main/java/com/google/devtools/build/docgen/RuleLinkExpander.java @@ -15,7 +15,6 @@ package com.google.devtools.build.docgen; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; - import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -27,7 +26,7 @@ import java.util.regex.Matcher; * <p>See {@link com.google.devtools.build.docgen.DocgenConsts.BLAZE_RULE_LINK} for the regex used * to match link references. */ -class RuleLinkExpander { +public class RuleLinkExpander { private static final String EXAMPLES_SUFFIX = "_examples"; private static final String ARGS_SUFFIX = "_args"; private static final String IMPLICIT_OUTPUTS_SUFFIX = "_implicit_outputs"; @@ -53,15 +52,28 @@ class RuleLinkExpander { .build(); private final Map<String, String> ruleIndex = new HashMap<>(); + private final boolean singlePage; - RuleLinkExpander(Map<String, String> ruleIndex) { + RuleLinkExpander(Map<String, String> ruleIndex, boolean singlePage) { this.ruleIndex.putAll(ruleIndex); this.ruleIndex.putAll(FUNCTIONS); + this.singlePage = singlePage; + } + + RuleLinkExpander(boolean singlePage) { + this.ruleIndex.putAll(FUNCTIONS); + this.singlePage = singlePage; + } + + public void addIndex(Map<String, String> ruleIndex) { + this.ruleIndex.putAll(ruleIndex); } private void appendRuleLink(Matcher matcher, StringBuffer sb, String ruleName, String ref) { String ruleFamily = ruleIndex.get(ruleName); - String link = ruleFamily + ".html#" + ref; + String link = singlePage + ? "#" + ref + : ruleFamily + ".html#" + ref; matcher.appendReplacement(sb, Matcher.quoteReplacement(link)); } @@ -109,7 +121,9 @@ class RuleLinkExpander { // The name is not the name of a rule but is the name of a static page, such as // common-definitions. Generate a link to that page. if (STATIC_PAGES.contains(name)) { - String link = name + ".html"; + String link = singlePage + ? "#" + name + : name + ".html"; // For referencing headings on a static page, use the following syntax: // ${link static_page_name#heading_name}, example: ${link make-variables#gendir} String pageHeading = matcher.group(4); @@ -150,7 +164,9 @@ class RuleLinkExpander { // this include custom <a name="heading"> tags in the description or examples for the rule. if (ruleIndex.containsKey(name)) { String ruleFamily = ruleIndex.get(name); - String link = ruleFamily + ".html#" + heading; + String link = singlePage + ? "#" + heading + : ruleFamily + ".html#" + heading; matcher.appendReplacement(sb, Matcher.quoteReplacement(link)); continue; } @@ -159,7 +175,9 @@ class RuleLinkExpander { // append the page heading. For example, ${link common-definitions#label-expansion} expands to // common-definitions.html#label-expansion. if (STATIC_PAGES.contains(name)) { - String link = name + ".html#" + heading; + String link = singlePage + ? "#" + heading + : name + ".html#" + heading; matcher.appendReplacement(sb, Matcher.quoteReplacement(link)); continue; } @@ -183,4 +201,16 @@ class RuleLinkExpander { String expanded = expandRuleLinks(htmlDoc); return expandRuleHeadingLinks(expanded); } + + /** + * Expands the rule reference. + * + * <p>This method is used to expand references in the BE velocity templates. + * + * @param ref The rule reference to expand. + * @return The expanded rule reference. + */ + public String expandRef(String ref) throws IllegalArgumentException { + return expand("${link " + ref + "}"); + } } diff --git a/src/main/java/com/google/devtools/build/docgen/SinglePageBuildEncyclopediaProcessor.java b/src/main/java/com/google/devtools/build/docgen/SinglePageBuildEncyclopediaProcessor.java new file mode 100644 index 0000000000..ccacd2fbc0 --- /dev/null +++ b/src/main/java/com/google/devtools/build/docgen/SinglePageBuildEncyclopediaProcessor.java @@ -0,0 +1,73 @@ +// Copyright 2014 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.docgen; + +import com.google.common.collect.Sets; +import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * Assembles the single-page version of the Build Encyclopedia. + */ +public class SinglePageBuildEncyclopediaProcessor extends BuildEncyclopediaProcessor { + public SinglePageBuildEncyclopediaProcessor(ConfiguredRuleClassProvider ruleClassProvider) { + super(ruleClassProvider); + } + + /** + * Collects and processes all the rule and attribute documentation in inputDirs and + * generates the Build Encyclopedia into the outputDir. + * + * @param inputDirs list of directory to scan for document in the source code + * @param outputDir output directory where to write the build encyclopedia + * @param blackList optional path to a file listing rules to not document + */ + @Override + public void generateDocumentation(List<String> inputDirs, String outputDir, String blackList) + throws BuildEncyclopediaDocException, IOException { + BuildDocCollector collector = new BuildDocCollector(ruleClassProvider, false); + RuleLinkExpander expander = new RuleLinkExpander(true); + Map<String, RuleDocumentation> ruleDocEntries = collector.collect( + inputDirs, blackList, expander); + warnAboutUndocumentedRules( + Sets.difference(ruleClassProvider.getRuleClassMap().keySet(), ruleDocEntries.keySet())); + RuleFamilies ruleFamilies = assembleRuleFamilies(ruleDocEntries.values()); + + Page page = TemplateEngine.newPage(DocgenConsts.SINGLE_BE_TEMPLATE); + + // Add the rule link expander. + page.add("expander", expander); + + // Populate variables for Common Definitions section. + page.add("commonAttributes", + expandCommonAttributes(PredefinedAttributes.COMMON_ATTRIBUTES, expander)); + page.add("testAttributes", + expandCommonAttributes(PredefinedAttributes.TEST_ATTRIBUTES, expander)); + page.add("binaryAttributes", + expandCommonAttributes(PredefinedAttributes.BINARY_ATTRIBUTES, expander)); + + // Popualte variables for Overview section. + page.add("langSpecificRuleFamilies", ruleFamilies.langSpecific); + page.add("genericRuleFamilies", ruleFamilies.generic); + + // Populate variables for Rules section. + page.add("ruleFamilies", ruleFamilies.all); + page.add("singlePage", true); + + writePage(page, outputDir, "build-encyclopedia.html"); + } +} diff --git a/src/main/java/com/google/devtools/build/docgen/templates/be/be-nav.vm b/src/main/java/com/google/devtools/build/docgen/templates/be/be-nav.vm index c8951e6c3c..3ac6e5c25d 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/be/be-nav.vm +++ b/src/main/java/com/google/devtools/build/docgen/templates/be/be-nav.vm @@ -2,6 +2,7 @@ #set ($bazelbuildGithub = "https://github.com/bazelbuild") <h3>Build Encyclopedia</h3> + <ul class="sidebar-nav"> <li><a href="${path}/overview.html">Overview</a></li> <li> diff --git a/src/main/java/com/google/devtools/build/docgen/templates/be/common-definitions.vm b/src/main/java/com/google/devtools/build/docgen/templates/be/common-definitions.vm index ff9e2a5875..94f5ac80a1 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/be/common-definitions.vm +++ b/src/main/java/com/google/devtools/build/docgen/templates/be/common-definitions.vm @@ -1,15 +1,20 @@ +#if (!$singlePage) --- layout: documentation title: Common Definitions --- +#end +#if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/header.vm") +#end -<h1>Common definitions</h1> +<h1 id="common-definitions">Common definitions</h1> <p>This section defines various terms and concepts that are common to many functions or build rules below. </p> +#if (!$singlePage) <div class="toc"> <h1>Contents</h1> <ul> @@ -22,6 +27,7 @@ many functions or build rules below. <li><a href="#implicit-outputs">Implicit output targets</a></li> </ul> </div> +#end <h2 id='sh-tokenization'>Bourne shell tokenization</h2> <p> Certain string attributes of some rules are split into multiple @@ -147,8 +153,8 @@ config_setting( <p> See the definitions of - <a href="functions.html#select">select</a> and - <a href="general.html#config_setting">config_setting</a> for more details. + <a href="$expander.expandRef("select")">select</a> and + <a href="$expander.expandRef("config_setting")">config_setting</a> for more details. Attributes marked <code>nonconfigurable</code> in their documentation cannot use this feature (usually because Bazel has to know their values before flags have been parsed). @@ -204,4 +210,6 @@ config_setting( the <a href="../build-ref.html">BUILD Concept Reference</a>. </p> +#if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/footer.vm") +#end diff --git a/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm b/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm index 8a87358ef8..4b7ddfa3f3 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm +++ b/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm @@ -1,11 +1,16 @@ +#if (!$singlePage) --- layout: documentation title: Functions --- +#end +#if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/header.vm") +#end <h1>Functions</h1> +#if (!$singlePage) <div class="toc"> <h1>Contents</h1> <ul> @@ -19,6 +24,7 @@ title: Functions <li><a href="#workspace">workspace</a></li> </ul> </div> +#end <!-- ================================================================= load() ================================================================= @@ -692,4 +698,6 @@ sh_binary( <code>workspace(name = "foo.bar")</code>. </p> +#if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/footer.vm") +#end diff --git a/src/main/java/com/google/devtools/build/docgen/templates/be/make-variables.vm b/src/main/java/com/google/devtools/build/docgen/templates/be/make-variables.vm index 2f5b9075e9..35448ed4a9 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/be/make-variables.vm +++ b/src/main/java/com/google/devtools/build/docgen/templates/be/make-variables.vm @@ -1,15 +1,20 @@ +#if (!$singlePage) --- layout: documentation title: Make Variables --- +#end +#if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/header.vm") +#end <!-- ============================================ variables ============================================ --> -<h1>"Make" Variables</h1> +<h1 id="make-variables">"Make" Variables</h1> +#if (!$singlePage) <div class="toc"> <ul> <li><a href="#make-var-substitution">"Make" variable subsitution</a></li> @@ -17,6 +22,7 @@ title: Make Variables <li><a href="#location">"$(location)" substitution</a></li> </ul> </div> +#end <p> This section describes how to use a special class of built-in string variables that are called the "Make" environment. @@ -33,7 +39,7 @@ title: Make Variables </p> <p>Build rules can introduce additional rule specific variables. One example is - the <a href="general.html#genrule.cmd"><code>cmd</code> attribute of a genrule</a>. + the <a href="$expander.expandRef("genrule.cmd")"><code>cmd</code> attribute of a genrule</a>. </p> <h2 id='make-var-substitution'>"Make" variable substitution</h2> @@ -142,7 +148,7 @@ in your genrule's cmd attribute. <p id="predefined_variables.genrule.cmd"> <strong> - Other Variables available to <a href="general.html#genrule.cmd">the cmd + Other Variables available to <a href="$expander.expandRef("genrule.cmd")">the cmd attribute of a genrule</a> </strong> </p> @@ -197,4 +203,6 @@ in your genrule's cmd attribute. <code>*_test</code> or <code>*_binary</code> rule. </p> +#if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/footer.vm") +#end diff --git a/src/main/java/com/google/devtools/build/docgen/templates/be/overview.vm b/src/main/java/com/google/devtools/build/docgen/templates/be/overview.vm index a6c0e50af2..b1c299fb80 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/be/overview.vm +++ b/src/main/java/com/google/devtools/build/docgen/templates/be/overview.vm @@ -1,8 +1,12 @@ +#if (!$singlePage) --- layout: documentation title: Build Encyclopedia --- +#end +#if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/header.vm") +#end <h1>Bazel BUILD Encyclopedia of Functions</h1> <h2>Contents</h2> @@ -11,47 +15,51 @@ title: Build Encyclopedia <ul> <li> - <a href="common-definitions.html">Common definitions</a> + <a href="$expander.expandRef("common-definitions")">Common definitions</a> <ul> - <li><a href="common-definitions.html#sh-tokenization">Bourne shell tokenization</a></li> - <li><a href="common-definitions.html#label-expansion">Label expansion</a></li> - <li><a href="common-definitions.html#common-attributes">Common attributes</a></li> - <li><a href="common-definitions.html#common-attributes-tests">Common attributes for tests</a></li> - <li><a href="common-definitions.html#common-attributes-binaries">Common attributes for binaries</a></li> - <li><a href="common-definitions.html#configurable-attributes">Configurable attributes</a></li> - <li><a href="common-definitions.html#implicit-outputs">Implicit output targets</a></li> + <li><a href="$expander.expandRef("common-definitions#sh-tokenization")">Bourne shell tokenization</a></li> + <li><a href="$expander.expandRef("common-definitions#label-expansion")">Label expansion</a></li> + <li><a href="$expander.expandRef("common-definitions#common-attributes")">Common attributes</a></li> + <li><a href="$expander.expandRef("common-definitions#common-attributes-tests")">Common attributes for tests</a></li> + <li><a href="$expander.expandRef("common-definitions#common-attributes-binaries")">Common attributes for binaries</a></li> + <li><a href="$expander.expandRef("common-definitions#configurable-attributes")">Configurable attributes</a></li> + <li><a href="$expander.expandRef("common-definitions#implicit-outputs")">Implicit output targets</a></li> </ul> </li> <li> - <a href="make-variables.html">"Make" variables</a> + <a href="$expander.expandRef("make-variables")">"Make" variables</a> <ul class="be-toc"> - <li><a href="make-variables.html#make-var-substitution">"Make" variable substitution</a></li> - <li><a href="make-variables.html#predefined_variables">Predefined variables</a></li> + <li><a href="$expander.expandRef("make-variables#make-var-substitution")">"Make" variable substitution</a></li> + <li><a href="$expander.expandRef("make-variables#predefined_variables")">Predefined variables</a></li> </ul> </li> - <li><a href="predefined-python-variables.html">Predefined Python Variables</a></li> + <li><a href="$expander.expandRef("predefined-python-variables")">Predefined Python Variables</a></li> </ul> <h3>Functions</h3> <ul class="be-toc"> - <li><a href="functions.html#load">load</a></li> + <li><a href="$expander.expandRef("load")">load</a></li> - <li><a href="functions.html#package">package</a></li> - <li><a href="functions.html#package_group">package_group</a></li> + <li><a href="$expander.expandRef("package")">package</a></li> + <li><a href="$expander.expandRef("package_group")">package_group</a></li> - <li><a href="functions.html#licenses">licenses</a></li> - <li><a href="functions.html#exports_files">exports_files</a></li> - <li><a href="functions.html#glob">glob</a></li> - <li><a href="functions.html#select">select</a></li> - <li><a href="functions.html#workspace">workspace</a></li> + <li><a href="$expander.expandRef("licenses")">licenses</a></li> + <li><a href="$expander.expandRef("exports_files")">exports_files</a></li> + <li><a href="$expander.expandRef("glob")">glob</a></li> + <li><a href="$expander.expandRef("select")">select</a></li> + <li><a href="$expander.expandRef("workspace")">workspace</a></li> </ul> <h3>Rules</h3> <h4>Language-specific Rules</h4> +#macro(summaryLink $page $heading) + #if ($singlePage)#${heading}#else${page}.html#${heading}#end +#end + #macro(summaryTable $ruleFamilies) <tbody> #foreach($ruleFamily in $ruleFamilies) @@ -60,7 +68,7 @@ title: Build Encyclopedia <td class="lang">${ruleFamily.name}</td> <td> #foreach($ruleDoc in $ruleFamily.binaryRules) - <a href="${ruleFamily.id}.html#${ruleDoc.ruleName}"#if($ruleDoc.isDeprecated()) class="deprecated"#end> + <a href="#summaryLink(${ruleFamily.id}, ${ruleDoc.ruleName})"#if($ruleDoc.isDeprecated()) class="deprecated"#end> ${ruleDoc.ruleName} </a> <br /> @@ -68,7 +76,7 @@ title: Build Encyclopedia </td> <td> #foreach($ruleDoc in $ruleFamily.libraryRules) - <a href="${ruleFamily.id}.html#${ruleDoc.ruleName}"#if($ruleDoc.isDeprecated()) class="deprecated"#end> + <a href="#summaryLink(${ruleFamily.id}, ${ruleDoc.ruleName})"#if($ruleDoc.isDeprecated()) class="deprecated"#end> ${ruleDoc.ruleName} </a> <br /> @@ -76,7 +84,7 @@ title: Build Encyclopedia </td> <td> #foreach($ruleDoc in $ruleFamily.testRules) - <a href="${ruleFamily.id}.html#${ruleDoc.ruleName}"#if($ruleDoc.isDeprecated()) class="deprecated"#end> + <a href="#summaryLink(${ruleFamily.id}, ${ruleDoc.ruleName})"#if($ruleDoc.isDeprecated()) class="deprecated"#end> ${ruleDoc.ruleName} </a> <br /> @@ -84,7 +92,7 @@ title: Build Encyclopedia </td> <td> #foreach($ruleDoc in $ruleFamily.otherRules1) - <a href="${ruleFamily.id}.html#${ruleDoc.ruleName}"#if($ruleDoc.isDeprecated()) class="deprecated"#end> + <a href="#summaryLink(${ruleFamily.id}, ${ruleDoc.ruleName})"#if($ruleDoc.isDeprecated()) class="deprecated"#end> ${ruleDoc.ruleName} </a> <br /> @@ -92,7 +100,7 @@ title: Build Encyclopedia </td> <td> #foreach($ruleDoc in $ruleFamily.otherRules2) - <a href="${ruleFamily.id}.html#${ruleDoc.ruleName}"#if($ruleDoc.isDeprecated()) class="deprecated"#end> + <a href="#summaryLink(${ruleFamily.id}, ${ruleDoc.ruleName})"#if($ruleDoc.isDeprecated()) class="deprecated"#end> ${ruleDoc.ruleName} </a> <br /> @@ -126,4 +134,6 @@ title: Build Encyclopedia #summaryTable($genericRuleFamilies) </table> +#if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/footer.vm") +#end diff --git a/src/main/java/com/google/devtools/build/docgen/templates/be/predefined-python-variables.vm b/src/main/java/com/google/devtools/build/docgen/templates/be/predefined-python-variables.vm index c50fb8a2ba..bc285fec50 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/be/predefined-python-variables.vm +++ b/src/main/java/com/google/devtools/build/docgen/templates/be/predefined-python-variables.vm @@ -1,17 +1,23 @@ +#if (!$singlePage) --- layout: documentation title: Predefined Python Variables --- +#end +#if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/header.vm") +#end <h2 id="predefined-python-variables">Predefined Python Variables</h2> +#if (!$singlePage) <div class="toc"> <h1>Contents</h1> <ul> <li><a href="#packagename">packagename</a></li> </ul> </div> +#end <h3 id="packagename">PACKAGE_NAME</h3> <p> This is a string variable with the name diff --git a/src/main/java/com/google/devtools/build/docgen/templates/be/rules.vm b/src/main/java/com/google/devtools/build/docgen/templates/be/rules.vm index 9e9345cf62..9958a6f2f9 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/be/rules.vm +++ b/src/main/java/com/google/devtools/build/docgen/templates/be/rules.vm @@ -1,8 +1,12 @@ +#if (!$singlePage) --- layout: documentation title: ${ruleFamily.name} Rules --- +#end +#if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/header.vm") +#end <h1>${ruleFamily.name} Rules</h1> @@ -70,4 +74,6 @@ title: ${ruleFamily.name} Rules #end #end +#if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/footer.vm") +#end diff --git a/src/main/java/com/google/devtools/build/docgen/templates/be/single-page.vm b/src/main/java/com/google/devtools/build/docgen/templates/be/single-page.vm new file mode 100644 index 0000000000..23cb684b00 --- /dev/null +++ b/src/main/java/com/google/devtools/build/docgen/templates/be/single-page.vm @@ -0,0 +1,28 @@ +#parse("com/google/devtools/build/docgen/templates/be/header.vm") + +#parse("com/google/devtools/build/docgen/templates/be/overview.vm") + +<hr> + +#parse("com/google/devtools/build/docgen/templates/be/common-definitions.vm") + +<hr> + +#parse("com/google/devtools/build/docgen/templates/be/make-variables.vm") + +<hr> + +#parse("com/google/devtools/build/docgen/templates/be/predefined-python-variables.vm") + +<hr> + +#parse("com/google/devtools/build/docgen/templates/be/functions.vm") + +#foreach ($ruleFamily in $ruleFamilies) +<hr> + +#parse("com/google/devtools/build/docgen/templates/be/rules.vm") + +#end + +#parse("com/google/devtools/build/docgen/templates/be/footer.vm") |