Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

Commit

Permalink
Add searchbar and new sidebar support #7 #8
Browse files Browse the repository at this point in the history
  • Loading branch information
Freymaurer committed May 16, 2023
1 parent 335b961 commit 3a35af7
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 82 deletions.
16 changes: 5 additions & 11 deletions src/Nfdi4Plants.Fornax/Components.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,11 @@ type Components = class end
static member docsLayout (contentGithubUrl:string, docs: Docs) =

let publishedDate = docs.published.Value.ToString("yyyy-MM-dd")
let sidebar = [
if Array.isEmpty docs.sidebar |> not then
for sidebarEle in docs.sidebar do
yield custom "nfdi-sidebar-element" [HtmlProperties.Custom ("slot", "sidebar"); HtmlProperties.Custom ("isActive","true") ] [
div [HtmlProperties.Custom ("slot", "title")] [!! sidebarEle.Title]
!! sidebarEle.Content
]
else ()
]
custom "nfdi-body" [Class "content"; if Array.isEmpty docs.sidebar |> not then HtmlProperties.Custom("hasSidebar", "true")] [
yield! sidebar
let hasSidebar = List.isEmpty docs.sidebar |> not
custom "nfdi-body" [Class "content"; if hasSidebar then HtmlProperties.Custom("hasSidebar", "true")] [

if docs.searchbar.IsSome then docs.searchbar.Value
if hasSidebar then yield! docs.sidebar

h1 [Class "front-header"] [!! docs.title]
i [Class "help" ] [!! $"last updated at {publishedDate}" ]
Expand Down
56 changes: 56 additions & 0 deletions src/Nfdi4Plants.Fornax/CustomParsing/nfdi-sidebar-element.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
namespace Fornax.Nfdi4Plants.CustomParsing

module SidebarElement =

open Html
open Fornax.Nfdi4Plants.MarkdigExtensions

type SidebarElement = {
Title: string
Content: string
}

let read (productionBasePath: string option) (contentArr: string []) =
contentArr
|> List.ofArray
|> List.fold (fun acc line ->
// opens new sidebar element with title
// ` = '\096'
if line.Trim() = "```" then
acc
elif line.StartsWith "```" then
// get sidebar element title
let title = line.Replace("`", "").Trim()
// add to list collection with empty list.
// empty list will be used to add all related lines
(title, List.empty)::acc
elif line.Trim() <> "" then
// match with list collection to check if it is empty (should not be empty, this is error prediction)
match acc with
// if has element, add line to sidebar element
| h::t -> (fst h, line::snd h)::t
// if is empty add sidebar placeholder
| [] -> ("Sidebar", line::[])::acc
else
acc
) []
|> List.map (fun (title, lines) ->
let c = lines |> List.rev |> String.concat "\n"
{
Title = title
Content = Markdig.Markdown.ToHtml(c, Pipelines.sidebarMarkdownPipeline(productionBasePath))
}
)
|> List.rev
|> Array.ofList

let write (eleArr: SidebarElement []) =
[
for sidebarEle in eleArr do
yield custom "nfdi-sidebar-element" [HtmlProperties.Custom ("slot", "sidebar"); HtmlProperties.Custom ("isActive","true") ] [
div [HtmlProperties.Custom ("slot", "title")] [!! sidebarEle.Title]
!! sidebarEle.Content
]
]


90 changes: 21 additions & 69 deletions src/Nfdi4Plants.Fornax/Loaders.fs
Original file line number Diff line number Diff line change
@@ -1,35 +1,6 @@
namespace Fornax.Nfdi4Plants
open System.IO

module Pipelines =
open Markdig
open Fornax.Nfdi4Plants.MarkdigExtensions.NfdiCode
open Fornax.Nfdi4Plants.MarkdigExtensions.NfdiHeader
open Fornax.Nfdi4Plants.MarkdigExtensions.NfdiSidebarElementHeader

let markdownPipeline =
MarkdownPipelineBuilder()
.UseAdvancedExtensions()
.UseEmojiAndSmiley()
.UseNFDIHeader()
.UseNFDICodeBlock()
.Build()

let sidebarMarkdownPipeline(productionBasePath: string option) =
if productionBasePath.IsSome then
MarkdownPipelineBuilder()
.UseSidebarHeader(productionBasePath.Value)
.Build()
else
MarkdownPipelineBuilder()
.UseSidebarHeader()
.Build()

type SidebarElement = {
Title: string
Content: string
}

type Author = {
Name: string
// url to profile
Expand All @@ -52,7 +23,8 @@ type Docs = {
add_toc: bool
/// Bool if automated "Dataplant Support" block should be added
add_support: bool
sidebar: SidebarElement []
sidebar: HtmlElement list
searchbar: HtmlElement option
content: string
}

Expand Down Expand Up @@ -187,14 +159,15 @@ module Aux =
add_toc = addToc
add_support = addSupport
content = ""
sidebar = [||]
sidebar = []
searchbar = None
}

/// <summary>Read sidebar markdown file at `sidebarPath` to and parse it nfdi-sidebar-element's.</summary>
/// <param name="contentDir">Name of the subfolder in which the docs files are.</param>
/// <param name="sidebarPath">Relative path to sidebar file.</param>
/// <returns>Array of all sidebar elements processed to html and metadata.</returns>
let getSidebar (contentDir: string) (productionBasePath: string option) (sidebarPath: string) =
let getSidebar (contentDir: string) (productionBasePath: string option) (useOldSidebar:bool) (sidebarPath: string) =
let fileContent =
let docsPath = Path.Combine(contentDir, sidebarPath)
File.ReadAllLines(docsPath)
Expand All @@ -206,38 +179,12 @@ module Aux =
|> snd
|> Array.skip 1 // starts with ---
let sidebar =
content
|> List.ofArray
|> List.fold (fun acc line ->
// opens new sidebar element with title
// ` = '\096'
if line.Trim() = "```" then
acc
elif line.StartsWith "```" then
// get sidebar element title
let title = line.Replace("`", "").Trim()
// add to list collection with empty list.
// empty list will be used to add all related lines
(title, List.empty)::acc
elif line.Trim() <> "" then
// match with list collection to check if it is empty (should not be empty, this is error prediction)
match acc with
// if has element, add line to sidebar element
| h::t -> (fst h, line::snd h)::t
// if is empty add sidebar placeholder
| [] -> ("Sidebar", line::[])::acc
else
acc
) []
|> List.map (fun (title, lines) ->
let c = lines |> List.rev |> String.concat "\n"
{
Title = title
Content = Markdig.Markdown.ToHtml(c, Pipelines.sidebarMarkdownPipeline(productionBasePath))
}
)
|> List.rev
|> Array.ofList
if useOldSidebar then
Fornax.Nfdi4Plants.CustomParsing.SidebarElement.read productionBasePath content
|> Fornax.Nfdi4Plants.CustomParsing.SidebarElement.write
else
Fornax.Nfdi4Plants.CustomParsing.SidebarEleneo.read content
|> List.map (Fornax.Nfdi4Plants.CustomParsing.SidebarEleneo.write true)
sidebar

/// <summary>Parse markdown `fileContent` to HTML with markdig and custom nfdi-webcomponent converter.</summary>
Expand All @@ -254,7 +201,7 @@ module Aux =
|> Array.skip 1 // starts with ---
|> String.concat "\n"

Markdig.Markdown.ToHtml(content, Pipelines.markdownPipeline)
Markdig.Markdown.ToHtml(content, MarkdigExtensions.Pipelines.markdownPipeline)

open Aux

Expand All @@ -266,10 +213,11 @@ type Docs with
/// <param name="filePath">Relative path to specific `.md` file.</param>
/// <param name="productionBasePath">This path can be used if the base path in production is not `/`. This happens in some gh-pages projects.</param>
/// <returns>Returns html as string.</returns>
static member loadFile(rootDir: string, contentDir: string, filePath: string, ?productionBasePath) : Docs =
static member loadFile(rootDir: string, contentDir: string, filePath: string, ?productionBasePath, ?includeSearchbar:bool, ?useOldSidebar: bool) : Docs =
try
let text = File.ReadAllText filePath

let includeSearchbar = Option.defaultValue false includeSearchbar
let useOldSidebar = Option.defaultValue false useOldSidebar
let config = Aux.getConfig text
let docsFromConfig = Docs.createFromConfig config

Expand All @@ -280,7 +228,10 @@ type Docs with
|> Option.map (snd >> Aux.trimString >> fun x -> Path.Combine(docsPath, x.Replace('\\','/')))

let sidebar =
addSidebar |> Option.map (Aux.getSidebar contentDir productionBasePath)
addSidebar |> Option.map (Aux.getSidebar contentDir productionBasePath useOldSidebar)

let searchbar =
if includeSearchbar then SubComponents.PagefindSearchbar.create(?productionBasePath=productionBasePath) |> Some else None

let content = Aux.getContent text

Expand All @@ -301,7 +252,8 @@ type Docs with
file = file
link = link
content = content
sidebar = if sidebar.IsSome then sidebar.Value else [||]
sidebar = if sidebar.IsSome then sidebar.Value else []
searchbar = searchbar
}
with
| e -> failwith $"""[Error in file {filePath}] {e.Message}"""
Expand Down
26 changes: 26 additions & 0 deletions src/Nfdi4Plants.Fornax/MarkdigExtensions/Pipelines.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace Fornax.Nfdi4Plants.MarkdigExtensions

module Pipelines =

open Markdig
open Fornax.Nfdi4Plants.MarkdigExtensions.NfdiCode
open Fornax.Nfdi4Plants.MarkdigExtensions.NfdiHeader
open Fornax.Nfdi4Plants.MarkdigExtensions.NfdiSidebarElementHeader

let markdownPipeline =
MarkdownPipelineBuilder()
.UseAdvancedExtensions()
.UseEmojiAndSmiley()
.UseNFDIHeader()
.UseNFDICodeBlock()
.Build()

let sidebarMarkdownPipeline(productionBasePath: string option) =
if productionBasePath.IsSome then
MarkdownPipelineBuilder()
.UseSidebarHeader(productionBasePath.Value)
.Build()
else
MarkdownPipelineBuilder()
.UseSidebarHeader()
.Build()
7 changes: 5 additions & 2 deletions src/Nfdi4Plants.Fornax/Nfdi4Plants.Fornax.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="CustomParsing\nfdi-sidebar-eleneo.fs" />
<Compile Include="MarkdigExtensions/nfdi-code.fs" />
<Compile Include="MarkdigExtensions/nfdi-header.fs" />
<Compile Include="MarkdigExtensions/nfdi-sidebar-element-header.fs" />
<Compile Include="MarkdigExtensions\Pipelines.fs" />
<Compile Include="CustomParsing\nfdi-sidebar-eleneo.fs" />
<Compile Include="CustomParsing\nfdi-sidebar-element.fs" />
<Compile Include="SubComponents\PagefindSearchbar.fs" />
<Compile Include="Loaders.fs" />
<Compile Include="Components.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="FSharp.Core" Version="5.0.2" />
<PackageReference Update="FSharp.Core" Version="[6.0.7]" />
<PackageReference Include="Markdig" Version="0.30.2" />
</ItemGroup>
<ItemGroup>
Expand Down
22 changes: 22 additions & 0 deletions src/Nfdi4Plants.Fornax/SubComponents/PagefindSearchbar.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Fornax.Nfdi4Plants.SubComponents

open Html

type PagefindSearchbar = class end
with
static member create (?productionBasePath: string) =
let appendBasePath (url: string) =
let p = Option.defaultValue "" productionBasePath
p.TrimEnd([|'/'; '\\'|]) + url
div [HtmlProperties.Custom("slot","searchbar")] [
link [Href <| appendBasePath "/_pagefind/pagefind-ui.css"; Rel "stylesheet"]
script [Src <| appendBasePath "/_pagefind/pagefind-ui.js"; Type "text/javascript"] []
div [Id "search"] []
script [] [
!!"""window.addEventListener('DOMContentLoaded', (event) => {
new PagefindUI({ element: "#search" });
});"""
]
]


0 comments on commit 3a35af7

Please sign in to comment.