Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: basic api page output for .NET
  • Loading branch information
yufeih committed Oct 19, 2023
commit 43cec1d7246c8c26eebdf5dfe02cecbf47f4dabf
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ dotnet_diagnostic.IDE0110.severity = suggestion # IDE0110: Remove unnecessary di
dotnet_diagnostic.IDE0240.severity = suggestion # IDE0240: Nullable directive is redundant
dotnet_diagnostic.IDE0241.severity = suggestion # IDE0241: Nullable directive is unnecessary

dotnet_diagnostic.CS8509.severity = suggestion # The switch expression does not handle all possible values of its input type

csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion # IDE0058: Remove unnecessary expression value
csharp_style_unused_value_assignment_preference = discard_variable:suggestion # IDE0059: Remove unnecessary value assignment
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<ContinuousIntegrationBuild Condition="'$(GITHUB_ACTIONS)' == 'true'">true</ContinuousIntegrationBuild>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(ContinuousIntegrationBuild)' == 'true' ">$(TargetFrameworks);net8.0</TargetFrameworks>
<LangVersion>Latest</LangVersion>
<LangVersion>Preview</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
Expand Down
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.7.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="OneOf" Version="3.0.263" />
<PackageVersion Include="OneOf.SourceGenerator" Version="3.0.263" />
<PackageVersion Include="PdfPig" Version="0.1.8" />
<PackageVersion Include="Spectre.Console.Cli" Version="0.47.0" />
<PackageVersion Include="Stubble.Core" Version="1.10.8" />
Expand Down
23 changes: 23 additions & 0 deletions samples/seed/docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,35 @@
"enumSortOrder": "declaringOrder",
"outputFormat": "markdown",
"output": "obj/md"
},
{
"src": [
{
"files": [
"assembly/bin/**/*.dll",
"project/**/*.csproj",
"solution/**/*.sln",
"csharp/**/*.cs",
"vb/**/*.vb"
],
"exclude": [
"project/Project.Core/**"
],
"src": "dotnet"
}
],
"namespaceLayout": "nested",
"enumSortOrder": "declaringOrder",
"outputFormat": "apiPage",
"output": "obj/apipage"
}
],
"build": {
"content": [
{ "files": [ "**/*.yml" ], "src": "obj/api", "dest": "api" },
{ "files": [ "**/*.yml" ], "src": "obj/apipage", "dest": "apipage" },
{ "files": [ "**" ], "src": "obj/md", "dest": "md" },
{ "files": [ "**" ], "src": "obj/apipage", "dest": "apipage" },
{ "files": [ "articles/**/*.{md,yml}", "*.md", "toc.yml", "restapi/**", "md/**", "md2/**" ] }
],
"resource": [
Expand Down
2 changes: 2 additions & 0 deletions samples/seed/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@
href: obj/api/
- name: .NET API (markdown)
href: obj/md/
- name: .NET API (apipage)
href: obj/apipage/
- name: REST API
href: restapi/
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

/**
* This file is used to generate the API page JSON schema. To generate the schema:
* 1. run `npx typescript-json-schema ApiPage.schema.d.ts ApiPage --required --strictNullChecks --out ApiPage.schema.json`
* 2. manually mark properties as markdown
*/

/** Define the markdown content type */
type markdown = string;

/** Represents an inline composed of text or links */
type Inline = string | (string | { text: string; url?: string })[];
type Span = string | { text: string; url?: string };
type Inline = Span | Span[];

/** Represents a markdown block */
type Markdown = {
Expand Down Expand Up @@ -44,7 +39,7 @@ type Api = (
/** API source URL */
src?: string;

/** Opaque metadata about the API as HTML data-* attributes */
/** Opaque metadata about the API as HTML data-{key} attributes */
metadata?: { [key: string]: string };
};

Expand All @@ -71,31 +66,33 @@ type Code = {
/** Code text */
code: string;

/** Code [langauge identifier](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers) */
/** Code [language identifier](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers) */
languageId?: string;
};

/** Represents a set of parameters */
type Params = {
parameters: {
/** Parameter name */
name?: string;
type Param = {
/** Parameter name */
name?: string;

/** Parameter type */
type?: Inline;

/** Parameter type */
type?: Inline;
/** Parameter default value */
default?: string;

/** Parameter default value */
default?: string;
/** Parameter description in markdown format */
description?: markdown;

/** Parameter description in markdown format */
description?: markdown;
/** Is this parameter deprecated, or the deprecation reason */
deprecated?: boolean | string;

/** Is this parameter deprecated, or the deprecation reason */
deprecated?: boolean | string;
/** Is this parameter optional? */
optional?: boolean;
}

/** Is this parameter optional? */
optional?: boolean;
}[];
/** Represents a set of parameters */
type Params = {
parameters: Param[];
};

/** Represents block level elements */
Expand All @@ -114,7 +111,7 @@ type ApiPage = {
/** Page title */
title: string;

/** Opaque metadata about the page as HTML <meta> tags */
/** Opaque metadata about the page as HTML \<meta> tags */
metadata?: { [key: string]: string | string[] };

/** Default code [language identifier](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers) */
Expand Down
162 changes: 162 additions & 0 deletions src/Docfx.Build/ApiPage/ApiPage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#if NET7_0_OR_GREATER

using System.Text.Json;
using System.Text.Json.Serialization;
using OneOf;

#nullable enable

namespace Docfx.Build.ApiPage;

struct LinkSpan
{
public required string text { get; init; }
public string? url { get; init; }
}

[GenerateOneOf]
partial class Span : OneOfBase<string, LinkSpan> { }

[GenerateOneOf]
partial class Inline : OneOfBase<Span, Span[]> { }

struct Markdown
{
public required string markdown { get; init; }
}

struct H1
{
public required string h1 { get; init; }
public string? id { get; init; }
}

struct H2
{
public required string h2 { get; init; }
public string? id { get; init; }
}

struct H3
{
public required string h3 { get; init; }
public string? id { get; init; }
}

struct H4
{
public required string h4 { get; init; }
public string? id { get; init; }
}

struct H5
{
public required string h5 { get; init; }
public string? id { get; init; }
}

struct H6
{
public required string h6 { get; init; }
public string? id { get; init; }
}

[GenerateOneOf]
partial class Heading : OneOfBase<H1, H2, H3, H4, H5, H6> { }

abstract class ApiBase
{
public string? id { get; init; }
public OneOf<bool, string>? deprecated { get; init; }
public string? src { get; init; }
public Dictionary<string, string>? metadata { get; init; }
}

class Api1 : ApiBase
{
public required string api1 { get; init; }
}

class Api2 : ApiBase
{
public required string api2 { get; init; }
}

class Api3 : ApiBase
{
public required string api3 { get; init; }
}

class Api4 : ApiBase
{
public required string api4 { get; init; }
}


[GenerateOneOf]
partial class Api : OneOfBase<Api1, Api2, Api3, Api4> { }

record struct Fact(string name, Inline value);

struct Facts
{
public required Fact[] facts { get; init; }
}

struct List
{
public required Inline[] list { get; init; }
}

struct Inheritance
{
public required Inline[] inheritance { get; init; }
}

struct Code
{
public required string code { get; init; }
public string? languageId { get; init; }
}

class Parameter
{
public string? name { get; init; }
public Inline? type { get; init; }
public string? @default { get; init; }
public string? description { get; init; }
public OneOf<bool, string>? deprecated { get; init; }
public bool? optional { get; init; }
}

struct Parameters
{
public required Parameter[] parameters { get; init; }
}

[GenerateOneOf]
partial class Block : OneOfBase<Heading, Api, Markdown, Facts, Parameters, List, Inheritance, Code> { }

record ApiPage
{
public static JsonSerializerOptions JsonSerializerOptions { get; } = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull | JsonIgnoreCondition.WhenWritingDefault,
};

static ApiPage()
{
JsonSerializerOptions.Converters.Add(new OneOfJsonConverterFactory());
}

public required string title { get; init; }
public required Block[] body { get; init; }

public string? languageId { get; init; }
public Dictionary<string, OneOf<string, string[]>>? metadata { get; init; }
}

#endif
Loading