Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Api docs #239

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build/
gh-pages/
miTLS/
.bundle/

output/
Suave.v11.suo
Suave.sln.DotSettings.user
*.userprefs
Expand Down
3 changes: 0 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,3 @@ PLATFORMS

DEPENDENCIES
albacore (~> 2.3)

BUNDLED WITH
1.10.6
8 changes: 7 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,14 @@ namespace :docs do
end

desc 'build documentation'
task :compile => :clean do
task :build => [:clean, :restore_paket] do
Dir.chdir 'docs/tools' do
system '../../tools/paket.exe', 'restore', clr_command: true
system "#{Albacore.windows? ? 'fsi' : 'fsharpi'} generate.fsx" # pricken över i
end
system 'git clone https://github.com/SuaveIO/suave.git -b gh-pages gh-pages' unless Dir.exists? 'gh-pages'
system 'rm -fr gh-pages/*'
system 'cp -pr docs/output/* gh-pages/'
Dir.chdir 'gh-pages' do
Bundler.with_clean_env do
system 'bundle'
Expand Down
2 changes: 2 additions & 0 deletions docs/files/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
_/site
_site/
1 change: 1 addition & 0 deletions docs/files/CNAME
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
suave.io
5 changes: 5 additions & 0 deletions docs/files/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
source 'https://rubygems.org'
gem 'rake'
gem 'albacore', '~> 2.0.0.rc.6'
gem 'github-pages'

16 changes: 16 additions & 0 deletions docs/files/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require 'bundler/setup'
require 'albacore'

desc 'build documentation'
task :build do
system 'bundle exec jekyll build'
end

desc 'build and push docs'
task :push => :build do
FileList['_site/{Gemfile,Gemfile.lock,Rakefile,.gitignore}'].each { |f| FileUtils.rm f }
system "/usr/bin/sshpass -p #{ENV['SUAVE_SERVER_PASS']} scp -P #{ENV['SUAVE_SERVER_PORT']} -r _site/* [email protected]:/home/suave/site", silent: true
end

task :default => :build

7 changes: 7 additions & 0 deletions docs/files/_fs_formatting/docpage.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@{
Layout = "template";
Title = Properties["page-title"];
Description = Properties["project-summary"];
}
@Properties["document"]
@Properties["tooltips"]
107 changes: 107 additions & 0 deletions docs/files/_fs_formatting/reference/module.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
@using FSharp.MetadataFormat
@{
Layout = "template";
Title = Model.Module.Name + " - " + Properties["project-name"];
}

@{
// Get all the members & comment for the type
var members = (IEnumerable<Member>)Model.Module.AllMembers;
var comment = (Comment)Model.Module.Comment;

// Group all members by their category which is an inline annotation
// that can be added to members using special XML comment:
//
// /// [category:Something]
//
// ...and can be used to categorize members in large modules or types
// (but if this is not used, then all members end up in just one category)
var byCategory = members
.GroupBy(m => m.Category)
.OrderBy(g => String.IsNullOrEmpty(g.Key) ? "ZZZ" : g.Key)
.Select((g, n) => new {
Index = n,
GroupKey = g.Key,
Members = g.OrderBy(m => m.Name),
Name = String.IsNullOrEmpty(g.Key) ? "Other module members" : g.Key
});

// Get nested modules and nested types as statically typed collections
var nestModules = (IEnumerable<Module>)Model.Module.NestedModules;
var nestTypes = (IEnumerable<FSharp.MetadataFormat.Type>)Model.Module.NestedTypes;
}

<h1>@Model.Module.Name</h1>
<div class="xmldoc">
@foreach (var sec in comment.Sections) {
// XML comment for the type has multiple sections that can be labelled
// with categories (to give comment for an individual category). Here,
// we print only those that belong to the <default> section.
if (!byCategory.Any(g => g.GroupKey == sec.Key))
{
if (sec.Key != "<default>") {
<h2>@sec.Key</h2>
}
@sec.Value
}
}
</div>
@if (byCategory.Count() > 1)
{
<!-- If there is more than 1 category in the type, generate TOC -->
<h2>Table of contents</h2>
<ul>
@foreach (var g in byCategory)
{
<li><a href="@("#section" + g.Index.ToString())">@g.Name</a></li>
}
</ul>
}

<!-- Render nested types and modules, if there are any -->
@if (nestTypes.Count() + nestModules.Count() > 0)
{
<h2>Nested types and modules</h2>
<div>
@RenderPart("part-nested", new {
Types = nestTypes,
Modules = nestModules
})
</div>
}

@foreach (var g in byCategory)
{
// Iterate over all the categories and print members. If there are more than one
// categories, print the category heading (as <h2>) and add XML comment from the type
// that is related to this specific category.
if (byCategory.Count() > 1)
{
<h2>@g.Name<a name="@("section" + g.Index.ToString())">&#160;</a></h2>
var info = comment.Sections.FirstOrDefault(kvp => kvp.Key == g.GroupKey);
if (info.Key != null)
{
<div class="xmldoc">
@info.Value
</div>
}
}

@RenderPart("part-members", new {
Header = "Functions and values",
TableHeader = "Function or value",
Members = g.Members.Where(m => m.Kind == MemberKind.ValueOrFunction)
})

@RenderPart("part-members", new {
Header = "Type extensions",
TableHeader = "Type extension",
Members = g.Members.Where(m => m.Kind == MemberKind.TypeExtension)
})

@RenderPart("part-members", new {
Header = "Active patterns",
TableHeader = "Active pattern",
Members = g.Members.Where(m => m.Kind == MemberKind.ActivePattern)
})
}
19 changes: 19 additions & 0 deletions docs/files/_fs_formatting/reference/namespaces.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@{
Layout = "template";
Title = "Namespaces - " + Properties["project-name"];
}

@foreach (var ns in Model.Namespaces)
{
if (ns.Types.Length + ns.Modules.Length > 0)
{
<h2>@ns.Name Namespace</h2>
<div>
@RenderPart("part-nested", new {
Types = ns.Types,
Modules = ns.Modules
})
</div>
}
}

40 changes: 40 additions & 0 deletions docs/files/_fs_formatting/reference/part-members.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@if (Enumerable.Count(Model.Members) > 0) {
<h3>@Model.Header</h3>
<table class="table table-bordered member-list">
<thead>
<tr><td>@Model.TableHeader</td><td>Description</td></tr>
</thead>
<tbody>
@foreach (var it in Model.Members)
{
<tr>
<td class="member-name">
@{ var id = Html.UniqueID().ToString(); }
<code onmouseout="hideTip(event, '@id', @id)" onmouseover="showTip(event, '@id', @id)">
@Html.Encode(it.Details.FormatUsage(40))
</code>
<div class="tip" id="@id">
<strong>Signature:</strong> @Html.Encode(it.Details.Signature)<br />
@if (!it.Details.Modifiers.IsEmpty) {
<strong>Modifiers:</strong> @it.Details.FormatModifiers<br />
}
@if (!it.Details.TypeArguments.IsEmpty) {
<strong>Type parameters:</strong> @it.Details.FormatTypeArguments
}
</div>
</td>
<td class="xmldoc">
@if (!String.IsNullOrEmpty(it.Details.FormatSourceLocation))
{
<a href="@it.Details.FormatSourceLocation" class="github-link">
<img src="../content/img/github.png" class="normal" />
<img src="../content/img/github-blue.png" class="hover" />
</a>
}
@it.Comment.FullText
</td>
</tr>
}
</tbody>
</table>
}
36 changes: 36 additions & 0 deletions docs/files/_fs_formatting/reference/part-nested.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@if (Enumerable.Count(Model.Types) > 0) {
<table class="table table-bordered type-list">
<thead>
<tr><td>Type</td><td>Description</td></tr>
</thead>
<tbody>
@foreach (var it in Model.Types)
{
<tr>
<td class="type-name">
<a href="@(it.UrlName).html">@it.Name</a>
</td>
<td class="xmldoc">@it.Comment.Blurb</td>
</tr>
}
</tbody>
</table>
}
@if (Enumerable.Count(Model.Modules) > 0) {
<table class="table table-bordered module-list">
<thead>
<tr><td>Module</td><td>Description</td></tr>
</thead>
<tbody>
@foreach (var it in Model.Modules)
{
<tr>
<td class="module-name">
<a href="@(it.UrlName).html">@it.Name</a>
</td>
<td class="xmldoc">@it.Comment.Blurb</td>
</tr>
}
</tbody>
</table>
}
105 changes: 105 additions & 0 deletions docs/files/_fs_formatting/reference/type.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
@using FSharp.MetadataFormat
@{
Layout = "template";
Title = Model.Type.Name + " - " + Properties["project-name"];
}

@{
// Get all the members & comment for the type
var members = (IEnumerable<Member>)Model.Type.AllMembers;
var comment = (Comment)Model.Type.Comment;

// Group all members by their category which is an inline annotation
// that can be added to members using special XML comment:
//
// /// [category:Something]
//
// ...and can be used to categorize members in large modules or types
// (but if this is not used, then all members end up in just one category)
var byCategory = members
.GroupBy(m => m.Category)
.OrderBy(g => String.IsNullOrEmpty(g.Key) ? "ZZZ" : g.Key)
.Select((g, n) => new {
Index = n,
GroupKey = g.Key,
Members = g.OrderBy(m => m.Kind == MemberKind.StaticParameter ? "" : m.Name),
Name = String.IsNullOrEmpty(g.Key) ? "Other type members" : g.Key
});
}

<h1>@Model.Type.Name</h1>
<div class="xmldoc">
@foreach (var sec in comment.Sections) {
// XML comment for the type has multiple sections that can be labelled
// with categories (to give comment for an individual category). Here,
// we print only those that belong to the <default> section.
if (!byCategory.Any(g => g.GroupKey == sec.Key)) {
if (sec.Key != "<default>") {
<h2>@sec.Key</h2>
}
@sec.Value
}
}
</div>
@if (byCategory.Count() > 1)
{
<!-- If there is more than 1 category in the type, generate TOC -->
<h2>Table of contents</h2>
<ul>
@foreach (var g in byCategory)
{
<li><a href="@("#section" + g.Index.ToString())">@g.Name</a></li>
}
</ul>
}
@foreach (var g in byCategory) {
// Iterate over all the categories and print members. If there are more than one
// categories, print the category heading (as <h2>) and add XML comment from the type
// that is related to this specific category.
if (byCategory.Count() > 1) {
<h2>@g.Name<a name="@("section" + g.Index.ToString())">&#160;</a></h2>
var info = comment.Sections.FirstOrDefault(kvp => kvp.Key == g.GroupKey);
if (info.Key != null) {
<div class="xmldoc">
@info.Value
</div>
}
}

@RenderPart("part-members", new {
Header = "Union Cases",
TableHeader = "Union Case",
Members = g.Members.Where(m => m.Kind == MemberKind.UnionCase)
})

@RenderPart("part-members", new {
Header = "Record Fields",
TableHeader = "Record Field",
Members = g.Members.Where(m => m.Kind == MemberKind.RecordField)
})

@RenderPart("part-members", new {
Header = "Static parameters",
TableHeader = "Static parameters",
Members = g.Members.Where(m => m.Kind == MemberKind.StaticParameter)
})

@RenderPart("part-members", new {
Header = "Constructors",
TableHeader = "Constructor",
Members = g.Members.Where(m => m.Kind == MemberKind.Constructor)
})

@RenderPart("part-members", new {
Header = "Instance members",
TableHeader = "Instance member",
Members = g.Members.Where(m => m.Kind == MemberKind.InstanceMember)
})

@RenderPart("part-members", new {
Header = "Static members",
TableHeader = "Static member",
Members = g.Members.Where(m => m.Kind == MemberKind.StaticMember)
})
}

Loading