Skip to content

Commit 405da9c

Browse files
author
Elad Ben-Israel
authored
feat(sphinx): allow readme file to define sphinx header and reorganize topic (#229)
* Fix #228: allow readme file to define sphinx topic header * Fix #185: move multi-language tabs after readme * Update README
1 parent 845cc48 commit 405da9c

File tree

9 files changed

+189
-94
lines changed

9 files changed

+189
-94
lines changed

README.md

+102-59
Original file line numberDiff line numberDiff line change
@@ -232,23 +232,73 @@ under `sphinx`, etc.
232232

233233
That's it. You are ready to rock!
234234

235-
## Configuration
235+
## Features
236+
237+
### Language features
238+
239+
* Classes
240+
* Inheritance
241+
* Constructors
242+
* Methods
243+
* Properties
244+
* Abstract Members
245+
* Virtual Overrides
246+
* Async Methods
247+
* Variadic Arguments
248+
* Static Methods and Properties
249+
* Static Constants
250+
* Abstract Classes
251+
* Interfaces
252+
* Enums
253+
* Primitive Types: string, number, boolean, date, json, any
254+
* Collection Types: arrays, maps
255+
* Union Types (limited support)
256+
* Module Dependencies
257+
* Data Interfaces
258+
259+
### Source Languages
236260

237-
jsii configuration is read from the module's `package.json` and includes the following options:
261+
* TypeScript
262+
263+
### Target Languages
264+
265+
* __Java__ - generates a ready-to-publish Maven package.
266+
* __.NET__ - generates a ready-to-publish NuGet package.
267+
* __Sphinx__ - generates a Sphinx reStructuredText document for the module with README and reference docs.
268+
* __Python__ (work in progress) - generates a ready-to-publish PyPI package.
269+
* __Ruby__ (work in progress) - generates a ready-to-publish RubyGem.
270+
271+
272+
## Targets
273+
274+
jsii configuration is read from the `jsii` section in the module's
275+
`package.json` and includes the following options:
238276

239277
* `targets` - the list of target languages this module will be packaged for. For each
240278
target, you would need to specify some naming information such as namespaces, package manager
241279
coordinates, etc. See [supported targets](#targets) for details.
242280
* `outdir` - the default output directory (relative to package root) for
243-
__jsii-pacmak__. This is where target artifacts are emitted during packaging. Each artifact
244-
will be emitted under `<outdir>/<target>` (e.g. `dist/java`, `dist/js`, etc).
281+
__jsii-pacmak__. This is where target artifacts are emitted during packaging.
282+
Each artifact will be emitted under `<outdir>/<target>` (e.g. `dist/java`,
283+
`dist/js`, etc). Conventionally we use `"dist"` for outdir.
245284

246-
### Targets
285+
### Java
247286

248-
The following targets are currently supported:
287+
The `java` target will produce a ready-to-deploy Maven package for your jsii module.
249288

250-
* `js` - implicit - every module will always have a "js" target (dah!).
251-
* `java` - packages the module as in Java/Maven package. Requires the following config:
289+
The `$outdir/java` directory will include the contents of a staged offline Maven
290+
repository. javadocs and sources are included automatically in the Maven package
291+
292+
This repository can be published to [Maven Central](https://search.maven.org/)
293+
via the `deploy-staged-repository` command of the
294+
[nexus-staging-maven-plugin](https://mvnrepository.com/artifact/org.sonatype.plugins/nexus-staging-maven-plugin).
295+
See [Sonatype
296+
documentation](https://mvnrepository.com/artifact/org.sonatype.plugins/nexus-staging-maven-plugin)
297+
and [this gist](https://gist.github.com/eladb/9caa04253b268e8a8f3d658184202806)
298+
as a reference.
299+
300+
To package your jsii module for Java, add the following configuration to the `jsii`
301+
section in `package.json`:
252302

253303
```json
254304
{
@@ -262,77 +312,70 @@ The following targets are currently supported:
262312
}
263313
```
264314

265-
* `dotnet` - packages the module as a .NET/NuGet package. Requires the following config:
315+
### .NET
316+
317+
The `dotnet` target will produce a ready-to-publish NuGet package for your module.
318+
319+
The `$outdir/dotnet` directory will include `.nupkg` files, which can
320+
be [published to NuGet](https://docs.microsoft.com/en-us/nuget/create-packages/publish-a-package).
321+
322+
To package your jsii module as for .NET, add this configuration to the `jsii`
323+
section in `package.json`:
266324

267325
```js
268326
{
269327
"dotnet": {
270-
/* Required. */
271-
"namespace": "Acme.HelloNamespace",
328+
"namespace": "Acme.HelloNamespace", // required
329+
"packageId": "Acme.HelloPackage", // required
330+
"title": "ACME Hello", // optional (default: packageId)
331+
"iconUrl": "path/to/icon.svg", // optional (default: no icon)
332+
333+
// strong-name signing
334+
"signAssembly": true, // optional (default: false)
335+
"assemblyOriginatorKeyFile": "path/to/key.snk" // optional
336+
}
337+
}
338+
```
272339

273-
/* Required. */
274-
"packageId": "Acme.HelloPackage",
340+
### Sphinx
275341

276-
/* Optional. Default: Value of packageId. */
277-
"title": "ACME Hello",
342+
The sphinx target emits a [Sphinx](http://www.sphinx-doc.org/en/master/)
343+
documentation topic for the module, that can be used to build a Sphinx
344+
documentation website. It's not a complete website.
278345

279-
/* Optional. Default: null (no icon). */
280-
"iconUrl": "path/to/icon.svg",
281346

282-
/* Optional. Used in conjunction with assemblyOriginatorKeyFile. Default: false. */
283-
"signAssembly": true,
347+
The `$outdir/sphinx` directory will include two files:
284348

285-
/* Optional. Used in conjunction with signAssembly. Default: null. */
286-
"assemblyOriginatorKeyFile": "path/to/key.snk"
287-
}
288-
}
289-
```
349+
* `<module-name>.rst` - the Sphinx topic entry point
350+
* `<module-name>.README.md` (optional) - the module's README.md file (if exists)
290351

291-
* `sphinx` - produces sphinx documentation for the module. No config is required, but an empty
292-
entry will be needed in order to package this target:
352+
The `.rst` file will use [m2r](https://github.com/miyakogi/m2r) to
353+
[`mdinclude`](https://miyakogi.github.io/m2r/example.html#include-markdown-file)
354+
the README.md file into the topic.
355+
356+
NOTE: if the first line of your `README.md` file starts with `# ` (an H1
357+
header), the contents of this line will be used as the first header of the
358+
topic. Otherwise, the module's name will be used.
359+
360+
You will need to build a Sphinx documentation website with this `.rst` included.
361+
362+
To package your jsii module as a Sphinx topic, add an empty object to the
363+
`jsii` section in `package.json` under the `sphinx` key:
293364

294365
```json
295366
{
296367
"sphinx": { }
297368
}
298369
```
299370

371+
### JavaScript
300372

301-
## Features
302-
303-
### Language features
304-
305-
* Classes
306-
* Inheritance
307-
* Constructors
308-
* Methods
309-
* Properties
310-
* Abstract Members
311-
* Virtual Overrides
312-
* Async Methods
313-
* Variadic Arguments
314-
* Static Methods and Properties
315-
* Static Constants
316-
* Abstract Classes
317-
* Interfaces
318-
* Enums
319-
* Primitive Types: string, number, boolean, date, json, any
320-
* Collection Types: arrays, maps
321-
* Union Types (limited support)
322-
* Module Dependencies
323-
* Data Interfaces
324-
325-
### Source Languages
326-
327-
* TypeScript
373+
An implicit JavaScript target will always be created. No configuration is needed.
328374

329-
### Target Languages
375+
The `$outdir/js` directory will include that npm tarball of the module (created
376+
with [`npm pack`](https://docs.npmjs.com/cli/pack)).
330377

331-
* __Java__ - generates a ready-to-publish Maven package.
332-
* __.NET__ - generates a ready-to-publish NuGet package.
333-
* __Sphinx__ - generates a Sphinx reStructuredText document for the module with README and reference docs.
334-
* __Python__ (work in progress) - generates a ready-to-publish PyPI package.
335-
* __Ruby__ (work in progress) - generates a ready-to-publish RubyGem.
378+
Tarballs can be published to npmjs.org using [`npm publish`](https://docs.npmjs.com/cli/publish)
336379

337380
## What kind of sorcery is this?
338381

packages/jsii-calc/README.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1-
## JSII Calculator
1+
# jsii Calculator
22

33
This library is used to demonstrate and test the features of JSII
4+
5+
## Sphinx
6+
7+
This file will be incorporated into the sphinx documentation.
8+
9+
If this file starts with an "H1" line (in our case `# jsii Calculator`), this
10+
heading will be used as the Sphinx topic name. Otherwise, the name of the module
11+
(`jsii-calc`) will be used instead.
12+
13+
14+
15+

packages/jsii-calc/test/assembly.jsii

+2-2
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@
141141
"license": "Apache-2.0",
142142
"name": "jsii-calc",
143143
"readme": {
144-
"markdown": "## JSII Calculator\n\nThis library is used to demonstrate and test the features of JSII\n"
144+
"markdown": "# jsii Calculator\n\nThis library is used to demonstrate and test the features of JSII\n\n## Sphinx\n\nThis file will be incorporated into the sphinx documentation.\n\nIf this file starts with an \"H1\" line (in our case `# jsii Calculator`), this\nheading will be used as the Sphinx topic name. Otherwise, the name of the module\n(`jsii-calc`) will be used instead.\n\n\n\n\n"
145145
},
146146
"repository": {
147147
"type": "git",
@@ -3070,5 +3070,5 @@
30703070
}
30713071
},
30723072
"version": "0.7.5",
3073-
"fingerprint": "ySCSItPu9fqfNNEpdYkxXDfM/reHpBffHLSNsUPp2nI="
3073+
"fingerprint": "XrmsNUcNdYiHEC6BRVT5XoeVmYQZzjYgiu6MyibgOwk="
30743074
}

packages/jsii-pacmak/lib/targets/sphinx.ts

+45-16
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ const HMARKS = ['=', '-', '^', '~', '"', '#'];
2828

2929
class SphinxDocsGenerator extends Generator {
3030
private assemblyName?: string;
31-
private readmeFile?: string;
3231
private namespaceStack = new Array<NamespaceStackEntry>();
3332
private tocPath = new Array<string>();
3433
private targets: { [name: string]: TargetConstructor } = {};
@@ -75,12 +74,8 @@ class SphinxDocsGenerator extends Generator {
7574

7675
protected onBeginAssembly(assm: spec.Assembly, fingerprint: boolean) {
7776
this.tocPath = new Array<string>(); // As a safety measure, in case previous assembly somehow didn't get it back to 0.
78-
if (assm.readme) {
79-
this.readmeFile = `_${fsSafeName(assm.name)}.README.md`;
80-
this.code.openFile(this.readmeFile);
81-
this.code.line(assm.readme.markdown);
82-
this.code.closeFile(this.readmeFile);
83-
}
77+
78+
const { readmeFile, readmeHeader } = this.emitReadme(assm);
8479

8580
this.code.openFile(`${fsSafeName(assm.name)}.rst`);
8681

@@ -89,8 +84,17 @@ class SphinxDocsGenerator extends Generator {
8984
this.code.line();
9085
}
9186

92-
this.openSection(assm.name);
87+
// use the readme header if defined or the assembly name otherwise
88+
this.openSection(readmeHeader || assm.name);
89+
this.code.line();
90+
91+
if (readmeFile) {
92+
this.code.line(`.. mdinclude:: ./${readmeFile}`);
93+
this.code.line();
94+
}
95+
this.openSection('Reference');
9396
this.code.line();
97+
9498
if (assm.targets) {
9599
this.code.openBlock('.. tabs::');
96100
this.code.line();
@@ -136,7 +140,6 @@ class SphinxDocsGenerator extends Generator {
136140
this.closeSection();
137141
this.code.closeFile(`${fsSafeName(assm.name)}.rst`);
138142

139-
delete this.readmeFile;
140143
delete this.assemblyName;
141144
}
142145

@@ -158,14 +161,8 @@ class SphinxDocsGenerator extends Generator {
158161
this.code.line();
159162
this.openSection(conciseName);
160163
}
161-
} else {
162-
if (this.readmeFile) {
163-
this.code.line(`.. mdinclude:: ./${this.readmeFile}`);
164-
this.code.line();
165-
}
166-
this.openSection('Reference');
167-
this.code.line();
168164
}
165+
169166
this.code.line(`.. py:module:: ${nativeName}`);
170167
this.code.line();
171168
}
@@ -597,6 +594,38 @@ class SphinxDocsGenerator extends Generator {
597594
}
598595
this.code.closeBlock();
599596
}
597+
598+
/**
599+
* Emits the README markdown file, while stripping off the first H1 header (if exists).
600+
* @returns readme: the name of the file (or undefined)
601+
* @returns header: the contents of the header (or undefined)
602+
*/
603+
private emitReadme(assm: spec.Assembly): { readmeFile?: string, readmeHeader?: string } {
604+
if (!assm.readme) {
605+
return {
606+
readmeFile: undefined,
607+
readmeHeader: undefined
608+
};
609+
}
610+
611+
let lines = assm.readme.markdown.split('\n');
612+
let readmeHeader;
613+
614+
if (lines[0].startsWith('# ')) {
615+
readmeHeader = lines[0].substr(2);
616+
lines = lines.slice(1);
617+
}
618+
619+
const readmeFile = `_${fsSafeName(assm.name)}.README.md`;
620+
this.code.openFile(readmeFile);
621+
this.code.line(lines.join('\n'));
622+
this.code.closeFile(readmeFile);
623+
624+
return {
625+
readmeFile,
626+
readmeHeader
627+
};
628+
}
600629
}
601630

602631
function dup(char: string, times: number) {

packages/jsii-pacmak/test/expected.jsii-calc-base/sphinx/_scope_jsii-calc-base.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
@scope/jsii-calc-base
22
=====================
33

4+
Reference
5+
---------
6+
47
.. tabs::
58

69
.. group-tab:: C#
@@ -118,9 +121,6 @@
118121
119122
120123
121-
Reference
122-
---------
123-
124124
.. py:module:: @scope/jsii-calc-base
125125
126126
Base

packages/jsii-pacmak/test/expected.jsii-calc-lib/sphinx/_scope_jsii-calc-lib.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
@scope/jsii-calc-lib
22
====================
33

4+
Reference
5+
---------
6+
47
.. tabs::
58

69
.. group-tab:: C#
@@ -118,9 +121,6 @@
118121
119122
120123
121-
Reference
122-
---------
123-
124124
.. py:module:: @scope/jsii-calc-lib
125125
126126
EnumFromScopedModule (enum)

packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii

+2-2
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@
141141
"license": "Apache-2.0",
142142
"name": "jsii-calc",
143143
"readme": {
144-
"markdown": "## JSII Calculator\n\nThis library is used to demonstrate and test the features of JSII\n"
144+
"markdown": "# jsii Calculator\n\nThis library is used to demonstrate and test the features of JSII\n\n## Sphinx\n\nThis file will be incorporated into the sphinx documentation.\n\nIf this file starts with an \"H1\" line (in our case `# jsii Calculator`), this\nheading will be used as the Sphinx topic name. Otherwise, the name of the module\n(`jsii-calc`) will be used instead.\n\n\n\n\n"
145145
},
146146
"repository": {
147147
"type": "git",
@@ -3070,5 +3070,5 @@
30703070
}
30713071
},
30723072
"version": "0.7.5",
3073-
"fingerprint": "ySCSItPu9fqfNNEpdYkxXDfM/reHpBffHLSNsUPp2nI="
3073+
"fingerprint": "XrmsNUcNdYiHEC6BRVT5XoeVmYQZzjYgiu6MyibgOwk="
30743074
}

0 commit comments

Comments
 (0)