Skip to content

Commit 39163c8

Browse files
Add sphinx project generation
This adds a new format called "sphinx-markdown" that inherits from markdown and adds in sphinx syntax and project generation. This new format is the default. It also makes the file name for the service shape "index" by default because that's going to be what it is regardless of format.
1 parent 992c06d commit 39163c8

File tree

11 files changed

+245
-5
lines changed

11 files changed

+245
-5
lines changed

smithy-docgen-core/src/main/java/software/amazon/smithy/docgen/core/DocSettings.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public record DocSettings(ShapeId service, String format) {
4141
public static DocSettings from(ObjectNode pluginSettings) {
4242
return new DocSettings(
4343
pluginSettings.expectStringMember("service").expectShapeId(),
44-
pluginSettings.getStringMemberOrDefault("format", "markdown")
44+
pluginSettings.getStringMemberOrDefault("format", "sphinx-markdown")
4545
);
4646
}
4747
}

smithy-docgen-core/src/main/java/software/amazon/smithy/docgen/core/DocSymbolProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public Symbol toSymbol(Shape shape) {
124124
@Override
125125
public Symbol serviceShape(ServiceShape shape) {
126126
return getSymbolBuilder(shape)
127-
.definitionFile(getDefinitionFile(serviceShape, shape))
127+
.definitionFile(getDefinitionFile("index"))
128128
.build();
129129
}
130130

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package software.amazon.smithy.docgen.core.integrations;
7+
8+
import java.util.List;
9+
import java.util.Set;
10+
import java.util.logging.Logger;
11+
import software.amazon.smithy.docgen.core.DocFormat;
12+
import software.amazon.smithy.docgen.core.DocGenerationContext;
13+
import software.amazon.smithy.docgen.core.DocIntegration;
14+
import software.amazon.smithy.docgen.core.DocSettings;
15+
import software.amazon.smithy.docgen.core.sections.sphinx.ConfSection;
16+
import software.amazon.smithy.docgen.core.sections.sphinx.MakefileSection;
17+
import software.amazon.smithy.docgen.core.sections.sphinx.WindowsMakeSection;
18+
import software.amazon.smithy.docgen.core.writers.SphinxMarkdownWriter;
19+
import software.amazon.smithy.model.shapes.ServiceShape;
20+
import software.amazon.smithy.utils.SmithyInternalApi;
21+
22+
/**
23+
* Adds Sphinx project scaffolding for compatible formats.
24+
*/
25+
@SmithyInternalApi
26+
public final class SphinxIntegration implements DocIntegration {
27+
private static final String MARKDOWN_FORMAT = "sphinx-markdown";
28+
private static final Set<String> FORMATS = Set.of(MARKDOWN_FORMAT);
29+
private static final Logger LOGGER = Logger.getLogger(SphinxIntegration.class.getName());
30+
31+
@Override
32+
public List<DocFormat> docFormats(DocSettings settings) {
33+
return List.of(
34+
new DocFormat(MARKDOWN_FORMAT, ".md", new SphinxMarkdownWriter.Factory())
35+
);
36+
}
37+
38+
@Override
39+
public void customize(DocGenerationContext context) {
40+
if (!FORMATS.contains(context.docFormat().name())) {
41+
LOGGER.finest(String.format(
42+
"Format %s is not a Sphinx-compatible format, skipping Sphinx project setup.",
43+
context.docFormat().name()
44+
));
45+
return;
46+
}
47+
// TODO: add some way to disable project file generation
48+
LOGGER.finest("Generating Sphinx project files.");
49+
writeConf(context);
50+
writeMakefile(context);
51+
}
52+
53+
private void writeConf(DocGenerationContext context) {
54+
var service = context.model().expectShape(context.settings().service(), ServiceShape.class);
55+
var serviceSymbol = context.symbolProvider().toSymbol(service);
56+
57+
context.writerDelegator().useFileWriter("content/conf.py", writer -> {
58+
writer.pushState(new ConfSection(context));
59+
writer.write("""
60+
# Configuration file for the Sphinx documentation builder.
61+
# For the full list of built-in configuration values, see the documentation:
62+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
63+
project = $1S
64+
version = $2S
65+
release = $2S
66+
templates_path = ["_templates"]
67+
html_static_path = ["_static"]
68+
html_theme = "alabaster"
69+
""",
70+
serviceSymbol.getName(),
71+
service.getVersion());
72+
73+
if (context.docFormat().name().equals(MARKDOWN_FORMAT)) {
74+
writer.write("""
75+
extensions = ["myst_parser"]
76+
myst_enable_extensions = [
77+
# Makes bare links into actual links
78+
"linkify",
79+
80+
# Used to write directives that can be parsed by normal parsers
81+
"colon_fence",
82+
]
83+
""");
84+
85+
}
86+
writer.popState();
87+
});
88+
}
89+
90+
private void writeMakefile(DocGenerationContext context) {
91+
context.writerDelegator().useFileWriter("Makefile", writer -> {
92+
writer.pushState(new MakefileSection(context));
93+
writer.writeWithNoFormatting("""
94+
# Minimal makefile for Sphinx documentation
95+
# You can set these variables from the command line, and also
96+
# from the environment for the first two.
97+
SPHINXOPTS ?=
98+
SPHINXBUILD ?= sphinx-build
99+
SOURCEDIR = content
100+
BUILDDIR = build
101+
102+
# Put it first so that "make" without argument is like "make help".
103+
help:
104+
\t@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
105+
106+
.PHONY: help Makefile
107+
108+
# Catch-all target: route all unknown targets to Sphinx using the new
109+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
110+
%: Makefile
111+
\t@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
112+
""");
113+
writer.popState();
114+
});
115+
116+
context.writerDelegator().useFileWriter("make.bat", writer -> {
117+
writer.pushState(new WindowsMakeSection(context));
118+
writer.write("""
119+
@ECHO OFF
120+
121+
pushd %~dp0
122+
123+
REM Command file for Sphinx documentation
124+
125+
if "%SPHINXBUILD%" == "" (
126+
set SPHINXBUILD=sphinx-build
127+
)
128+
set SOURCEDIR=content
129+
set BUILDDIR=build
130+
131+
%SPHINXBUILD% >NUL 2>NUL
132+
if errorlevel 9009 (
133+
echo.
134+
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
135+
echo.installed, then set the SPHINXBUILD environment variable to point
136+
echo.to the full path of the 'sphinx-build' executable. Alternatively you
137+
echo.may add the Sphinx directory to PATH.
138+
echo.
139+
echo.If you don't have Sphinx installed, grab it from
140+
echo.https://www.sphinx-doc.org/
141+
exit /b 1
142+
)
143+
144+
if "%1" == "" goto help
145+
146+
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
147+
goto end
148+
149+
:help
150+
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
151+
152+
:end
153+
popd
154+
""");
155+
writer.popState();
156+
});
157+
}
158+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package software.amazon.smithy.docgen.core.sections.sphinx;
7+
8+
import software.amazon.smithy.docgen.core.DocGenerationContext;
9+
import software.amazon.smithy.utils.CodeSection;
10+
11+
/**
12+
* Generates the {@code conf.py} file for sphinx.
13+
* @see <a href="https://www.sphinx-doc.org/en/master/usage/configuration.html">
14+
* sphinx config docs</a>
15+
* @param context The context used to generate documentation.
16+
*/
17+
public record ConfSection(DocGenerationContext context) implements CodeSection {
18+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package software.amazon.smithy.docgen.core.sections.sphinx;
7+
8+
import software.amazon.smithy.docgen.core.DocGenerationContext;
9+
import software.amazon.smithy.utils.CodeSection;
10+
11+
/**
12+
* Generates a Makefile that wraps sphinx-build with default arguments.
13+
* @param context The context used to generate documentation.
14+
*/
15+
public record MakefileSection(DocGenerationContext context) implements CodeSection {
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package software.amazon.smithy.docgen.core.sections.sphinx;
7+
8+
import software.amazon.smithy.docgen.core.DocGenerationContext;
9+
import software.amazon.smithy.utils.CodeSection;
10+
11+
/**
12+
* Generates a batch script that wraps sphinx-build with default arguments.
13+
* @param context The context used to generate documentation.
14+
*/
15+
public record WindowsMakeSection(DocGenerationContext context) implements CodeSection {
16+
}

smithy-docgen-core/src/main/java/software/amazon/smithy/docgen/core/writers/MarkdownWriter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Writes documentation in <a href="https://spec.commonmark.org">CommonMark</a> format.
1616
*/
1717
@SmithyUnstableApi
18-
public final class MarkdownWriter extends DocWriter {
18+
public class MarkdownWriter extends DocWriter {
1919

2020
/**
2121
* Constructor.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package software.amazon.smithy.docgen.core.writers;
7+
8+
import software.amazon.smithy.codegen.core.SymbolWriter;
9+
import software.amazon.smithy.utils.SmithyUnstableApi;
10+
11+
/**
12+
* Writes documentation in <a href="https://spec.commonmark.org">CommonMark</a>-based
13+
* format for the <a href="https://www.sphinx-doc.org">Sphinx</a> doc build system.
14+
*
15+
* <p>The specific markdown parser being written for is
16+
* <a href="https://myst-parser.readthedocs.io/en/latest/index.html">MyST</a> with the
17+
* following <a href="https://myst-parser.readthedocs.io/en/latest/syntax/optional.html">
18+
* extensions</a> enabled: {@code linkify} and {@code colon_fence}
19+
*/
20+
@SmithyUnstableApi
21+
public final class SphinxMarkdownWriter extends MarkdownWriter {
22+
/**
23+
* Factory to construct {@code SphinxMarkdownWriter}s.
24+
*/
25+
public static final class Factory implements SymbolWriter.Factory<DocWriter> {
26+
@Override
27+
public DocWriter apply(String s, String s1) {
28+
return new SphinxMarkdownWriter();
29+
}
30+
}
31+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
software.amazon.smithy.docgen.core.BuiltInDocFormatsIntegration
2+
software.amazon.smithy.docgen.core.integrations.SphinxIntegration

smithy-docgen-core/src/test/java/software/amazon/smithy/docgen/core/SmithyDocPluginTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ public void assertDocumentationFiles() {
4646
}
4747

4848
private void assertServicePageContents(MockManifest manifest) {
49-
var actual = manifest.expectFileString("/content/SampleService.md");
50-
var expected = readExpectedPageContent("expected-outputs/SampleService.md");
49+
var actual = manifest.expectFileString("/content/index.md");
50+
var expected = readExpectedPageContent("expected-outputs/index.md");
5151

5252
assertEquals(expected, actual);
5353
}

0 commit comments

Comments
 (0)