Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## [Unreleased]

### Added
* Add `fsdocs init` command to scaffold a minimal `docs/index.md` (and optionally `_template.html`) for new projects. [#872](https://github.com/fsprojects/FSharp.Formatting/issues/872)
* Add `<FsDocsAllowExecutableProject>true</FsDocsAllowExecutableProject>` project file setting to include executable projects (OutputType=Exe/WinExe) in API documentation generation. [#918](https://github.com/fsprojects/FSharp.Formatting/issues/918)
* Add `{{fsdocs-logo-alt}}` substitution (configurable via `<FsDocsLogoAlt>` MSBuild property, defaults to `Logo`) for accessible alt text on the header logo image. [#626](https://github.com/fsprojects/FSharp.Formatting/issues/626)

Expand Down
79 changes: 79 additions & 0 deletions src/fsdocs-tool/InitCommand.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
namespace fsdocs

open CommandLine
open System
open System.IO
open System.Reflection

/// The fsdocs init command: scaffold a minimal docs folder for a new project.
[<Verb("init", HelpText = "initialize a docs folder with a default index.md and optionally a _template.html")>]
type InitCommand() =

[<Option("input", Required = false, Default = "docs", HelpText = "The directory to initialize (default: docs).")>]
member val input = "docs" with get, set

[<Option("force", Required = false, Default = false, HelpText = "Overwrite existing files (default: false).")>]
member val force = false with get, set

[<Option("with-template",
Required = false,
Default = false,
HelpText = "Also scaffold a _template.html file in the docs directory.")>]
member val withTemplate = false with get, set

member this.Execute() =
let docsDir =
if Path.IsPathRooted(this.input) then
this.input
else
Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, this.input))

if not (Directory.Exists(docsDir)) then
printfn "Creating directory: %s" docsDir
Directory.CreateDirectory(docsDir) |> ignore

let indexPath = Path.Combine(docsDir, "index.md")

let writeIfNeeded path content =
if File.Exists(path) && not this.force then
printfn "Skipping %s (already exists; use --force to overwrite)" path
else
printfn "Writing %s" path
File.WriteAllText(path, (content: string))

let indexContent =
"""---
title: Documentation
category: Documentation
categoryindex: 1
index: 1
---

# Your Project Name

Welcome to the documentation for **Your Project Name**.

## Getting Started

Add your documentation here. You can use Markdown, F# scripts (`.fsx`) or Jupyter notebooks (`.ipynb`).

Run `dotnet fsdocs watch` to preview the site locally.
"""

writeIfNeeded indexPath indexContent

if this.withTemplate then
let templatePath = Path.Combine(docsDir, "_template.html")

let templateContent =
let asm = Assembly.GetExecutingAssembly()

use stream = asm.GetManifestResourceStream("fsdocs._template.html")
use reader = new StreamReader(stream)
reader.ReadToEnd()

writeIfNeeded templatePath templateContent

printfn ""
printfn "Done! Run 'dotnet fsdocs watch --input %s' to preview your documentation." this.input
0
3 changes: 2 additions & 1 deletion src/fsdocs-tool/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ do ()
[<EntryPoint>]
let main argv =
CommandLine.Parser.Default
.ParseArguments<BuildCommand, WatchCommand>(argv)
.ParseArguments<BuildCommand, WatchCommand, InitCommand>(argv)
.MapResult(
(fun (opts: BuildCommand) -> opts.Execute()),
(fun (opts: WatchCommand) -> opts.Execute()),
(fun (opts: InitCommand) -> opts.Execute()),
(fun _ -> 1)
)
5 changes: 5 additions & 0 deletions src/fsdocs-tool/fsdocs-tool.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@
<Compile Include="Options.fs" />
<Compile Include="ProjectCracker.fs" />
<Compile Include="BuildCommand.fs" />
<Compile Include="InitCommand.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="..\..\docs\_template.html" LogicalName="fsdocs._template.html" />
</ItemGroup>

<ItemGroup>
<!-- NuGet package content -->
<Content Include="..\..\docs\_template.html" PackagePath="templates" />
Expand Down