Skip to content

Commit

Permalink
Three fixes (#601)
Browse files Browse the repository at this point in the history
* fixes to HTML generation

* fixes to HTML generation
  • Loading branch information
dsyme authored Sep 10, 2020
1 parent 9e1b267 commit b735157
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 63 deletions.
8 changes: 7 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
## 7.2.7
## 7.2.8

* [ApiDocs: examples not showing for types and modules](https://github.com/fsprojects/FSharp.Formatting/issues/599)

* Comma-separate interface list in API docs

* Remove untyped Sections from ApiDocComment since individual supported sections are now available

## 7.2.7

* [ApiDocs: cref to members are not resolving to best possible link](https://github.com/fsprojects/FSharp.Formatting/issues/598)

* [ApiDocs: namespace docs are showing in module/type summaries as well](https://github.com/fsprojects/FSharp.Formatting/issues/597)
Expand Down
59 changes: 25 additions & 34 deletions src/FSharp.Formatting.ApiDocs/GenerateHtml.fs
Original file line number Diff line number Diff line change
Expand Up @@ -206,19 +206,6 @@ type HtmlRender(model: ApiDocModel) =
p [] [yield! sourceLink e.SourceLocation
embed e.Comment.Summary; ]

match e.Comment.Remarks with
| Some r ->
p [Class "fsdocs-remarks"] [embed r]
| None -> ()

for e in e.Comment.Notes do
h5 [Class "fsdocs-note-header"] [!! "Note"]
p [Class "fsdocs-note"] [embed e]

for e in e.Comment.Examples do
h5 [Class "fsdocs-example-header"] [!! "Example"]
p [Class "fsdocs-example"] [embed e]

]
]
]
Expand All @@ -238,15 +225,14 @@ type HtmlRender(model: ApiDocModel) =
// Get all the members & comment for the type
let entity = info.Entity
let members = entity.AllMembers |> List.filter (fun e -> not e.IsObsolete)
let comment = entity.Comment

// Group all members by their category
let byCategory =
getSortedCategories members (fun m -> m.Exclude) (fun m -> m.Category) (fun m -> m.CategoryIndex)
|> List.mapi (fun i (key, elems) ->
let elems = elems |> List.sortBy (fun m -> m.Name)
let name = if String.IsNullOrEmpty(key) then "Other module members" else key
(i, key, elems, name))
(i, elems, name))

let usageName =
match info.ParentModule with
Expand Down Expand Up @@ -277,8 +263,11 @@ type HtmlRender(model: ApiDocModel) =
match entity.AllInterfaces with
| [] -> ()
| l ->
p [] [!! ("All Interfaces: ")]
ul [] [ for i in l -> li [] [embed i] ]
p [] [!! ("All Interfaces: ")
for (i, ity) in Seq.indexed l do
if i <> 0 then
!! ", "
embed ity ]

if entity.Symbol.IsValueType then
p [] [!! ("Kind: Struct")]
Expand All @@ -300,21 +289,28 @@ type HtmlRender(model: ApiDocModel) =
//if info.Entity.IsObsolete then
// obsoleteMessage entity.ObsoleteMessage

div [Class "fsdocs-xmldoc" ] [
// 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>
for sec in comment.Sections do
if not (byCategory |> List.exists (fun (_, g, _, _) -> g = sec.Key)) then
if (sec.Key <> "<default>") then
h3 [] [encode(sec.Key)]
embed sec.Value
]
// Show the summary (and sectioned docs without any members)
div [Class "fsdocs-xmldoc" ] [ embed entity.Comment.Summary ]

// Show the remarks etc.
match entity.Comment.Remarks with
| Some r ->
p [Class "fsdocs-remarks"] [embed r]
| None -> ()

for note in entity.Comment.Notes do
h5 [Class "fsdocs-note-header"] [!! "Note"]
p [Class "fsdocs-note"] [embed note]

for example in entity.Comment.Examples do
h5 [Class "fsdocs-example-header"] [!! "Example"]
p [Class "fsdocs-example"] [embed example]

if (byCategory.Length > 1) then
// If there is more than 1 category in the type, generate TOC
h3 [] [!!"Table of contents"]
ul [] [
for (index, _, _, name) in byCategory do
for (index, _, name) in byCategory do
li [] [ a [Href (sprintf "#section%d" index)] [!! name ] ]
]

Expand All @@ -332,18 +328,13 @@ type HtmlRender(model: ApiDocModel) =
yield! renderEntities nestedEntities
]

for (index, key, ms, name) in byCategory do
for (index, ms, name) in byCategory do
// 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.Length > 1) then
h2 [Id (sprintf "section%d" index)] [!! name]
//<a name="@(" section" + g.Index.ToString())">&#160;</a></h2>
let info = comment.Sections |> Seq.tryFind(fun kvp -> kvp.Key = key)
match info with
| None -> ()
| Some key ->
div [Class "fsdocs-xmldoc"] [ embed key.Value ]
div [] (renderMembers "Functions and values" "Function or value" (ms |> List.filter (fun m -> m.Kind = ApiDocMemberKind.ValueOrFunction)))
div [] (renderMembers "Type extensions" "Type extension" (ms |> List.filter (fun m -> m.Kind = ApiDocMemberKind.TypeExtension)))
div [] (renderMembers "Active patterns" "Active pattern" (ms |> List.filter (fun m -> m.Kind = ApiDocMemberKind.ActivePattern)))
Expand Down
45 changes: 17 additions & 28 deletions src/FSharp.Formatting.ApiDocs/GenerateModel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -80,52 +80,49 @@ module internal Utils =
type ApiDocHtml(html: string) =

/// Get the HTML text of the HTML section
member x.HtmlText = html
member _.HtmlText = html

/// Represents a documentation comment attached to source code
type ApiDocComment(summary, remarks, parameters, returns, examples, notes, exceptions, sections, rawData) =
type ApiDocComment(summary, remarks, parameters, returns, examples, notes, exceptions, rawData) =
/// The summary for the comment
member x.Summary : ApiDocHtml = summary
member _.Summary : ApiDocHtml = summary

/// The remarks html for comment
member x.Remarks : ApiDocHtml option = remarks
member _.Remarks : ApiDocHtml option = remarks

/// The param sections of the comment
member x.Parameters : (string * ApiDocHtml) list = parameters
member _.Parameters : (string * ApiDocHtml) list = parameters

/// The examples sections of the comment
member x.Examples : ApiDocHtml list = examples
member _.Examples : ApiDocHtml list = examples

/// The notes sections of the comment
member x.Notes : ApiDocHtml list = notes
member _.Notes : ApiDocHtml list = notes

/// The return sections of the comment
member x.Returns : ApiDocHtml option = returns
member _.Returns : ApiDocHtml option = returns

/// The notes sections of the comment
member x.Exceptions : (string * string option * ApiDocHtml) list = exceptions

/// The parsed sections of the comment
member x.Sections : KeyValuePair<string, ApiDocHtml> list = sections
member _.Exceptions : (string * string option * ApiDocHtml) list = exceptions

/// The raw data of the comment
member x.RawData: KeyValuePair<string, string> list = rawData
member _.RawData: KeyValuePair<string, string> list = rawData

static member internal Empty = ApiDocComment(ApiDocHtml(""), None, [], None, [], [], [], [], [])
static member internal Empty = ApiDocComment(ApiDocHtml(""), None, [], None, [], [], [], [])

/// Represents a custom attribute attached to source code
type ApiDocAttribute(name, fullName, constructorArguments, namedConstructorArguments) =
/// The name of the attribute
member x.Name : string = name
member _.Name : string = name

/// The qualified name of the attribute
member x.FullName : string = fullName
member _.FullName : string = fullName

/// The arguments to the constructor for the attribute
member x.ConstructorArguments : obj list = constructorArguments
member _.ConstructorArguments : obj list = constructorArguments

/// The named arguments for the attribute
member x.NamedConstructorArguments : (string*obj) list = namedConstructorArguments
member _.NamedConstructorArguments : (string*obj) list = namedConstructorArguments

/// Gets a value indicating whether this attribute is System.ObsoleteAttribute
member x.IsObsoleteAttribute =
Expand Down Expand Up @@ -1359,14 +1356,8 @@ module internal SymbolReader =
let examples = [ for e in examples -> ApiDocHtml(Literate.ToHtml(doc.With(paragraphs=e))) ]
let returns = if returns.IsEmpty then None else Some (ApiDocHtml(Literate.ToHtml(doc.With(paragraphs=returns))))

let sections =
[ for (k, v) in groups ->
let body = if k = "<default>" then List.rev v else List.tail (List.rev v)
let html = ApiDocHtml(Literate.ToHtml(doc.With(body)))
KeyValuePair(k, html) ]

ApiDocComment(summary=summary, remarks=remarks, parameters=[], returns=returns, examples=examples, notes=notes,
exceptions=[], sections=sections, rawData=raw)
exceptions=[], rawData=raw)

let findCommand cmd =
match cmd with
Expand Down Expand Up @@ -1568,11 +1559,10 @@ module internal SymbolReader =
lst |> Seq.iteri (fun id el ->
rawData.[n + "-" + string id] <- el.Value))

let sections = [KeyValuePair("<default>", summary)]
let rawData = rawData |> Seq.toList
let comment =
ApiDocComment(summary=summary, remarks=remarks, parameters=parameters, returns=returns,
examples=examples, notes=notes, exceptions=exceptions, sections=sections, rawData=rawData)
examples=examples, notes=notes, exceptions=exceptions, rawData=rawData)
comment, nsels

let combineHtml (h1: ApiDocHtml) (h2: ApiDocHtml) =
Expand All @@ -1593,7 +1583,6 @@ module internal SymbolReader =
returns = combineHtmlOptions c1.Returns c2.Returns,
notes = c1.Notes @ c2.Notes,
exceptions = c1.Exceptions @ c2.Exceptions,
sections = c1.Sections @ c2.Sections,
rawData = c1.RawData @ c2.RawData)

let combineNamespaceDocs nspDocs =
Expand Down

0 comments on commit b735157

Please sign in to comment.