From 0b95814c8368ad17d9ca1e26bd924e3f17d383e6 Mon Sep 17 00:00:00 2001 From: krymtkts Date: Sun, 30 Jul 2023 17:16:02 +0900 Subject: [PATCH 1/5] Refine. --- src/App.fs | 22 ++++----- src/Generator.fs | 120 ++++++++++++++++++++++++++--------------------- 2 files changed, 75 insertions(+), 67 deletions(-) diff --git a/src/App.fs b/src/App.fs index 213fea8..01e73ca 100644 --- a/src/App.fs +++ b/src/App.fs @@ -15,21 +15,17 @@ render src = "contents" dst = "docs" - postsRoot = "/posts" - postsTitle = "Posts" - pagesRoot = "/pages" - paesTitle = "Pages" - tagsRoot = "/tags" - tagsTitle = "Tags" - archivesRoot = "/archives" - archivesTitle = "Archives" + posts = { root = "/posts"; title = "Posts" } + pages = { root = "/pages"; title = "Pages" } + tags = { root = "/tags"; title = "Tags" } + archives = + { root = "/archives" + title = "Archives" } - feed = "feed" + feedName = "feed" additionalNavs = - [ Link - { text = "About Me" - path = "/pages/about.html" - sitemap = No } ] + [ { text = "About Me" + path = "/pages/about.html" } ] } diff --git a/src/Generator.fs b/src/Generator.fs index 1fb48d6..f9d7eb0 100644 --- a/src/Generator.fs +++ b/src/Generator.fs @@ -525,6 +525,10 @@ type Mode = | Development | Production +type Content = { root: string; title: string } + +type AdditionalNav = { text: string; path: string } + type RnderOptions = { stage: Mode siteName: string @@ -538,51 +542,60 @@ type RnderOptions = src: string dst: string - postsRoot: string - postsTitle: string - pagesRoot: string - paesTitle: string - tagsRoot: string - tagsTitle: string - archivesRoot: string - archivesTitle: string + posts: Content + pages: Content + tags: Content + archives: Content - additionalNavs: Nav list + additionalNavs: AdditionalNav list - feed: string + feedName: string } +let private buildNavList opts = + let index = "/index.html" + let feed = $"/{opts.feedName}.xml" + + index, + feed, + List.concat [ [ Title + { text = opts.siteName + path = index + sitemap = Yes "1.0" } + Link + { text = opts.archives.title + path = $"{opts.archives.root}.html" + sitemap = Yes "0.9" } + Link + { text = opts.tags.title + path = $"{opts.tags.root}.html" + sitemap = Yes "0.9" } ] + List.map + (fun n -> + Link + { text = n.text + path = n.path + sitemap = No }) + opts.additionalNavs + [ Link + { text = "RSS" + path = feed + sitemap = No } ] ] + +let private buildDevScript opts = + match opts.stage with + | Development -> Some("/js/dev.js"), [ ("src/Dev.fs.js", $"{opts.dst}{opts.pathRoot}/js/dev.js") ] + | Production -> None, [] + let render (opts: RnderOptions) = promise { - let index = "/index.html" - let feed = $"/{opts.feed}.xml" - - let navs = - [ Title - { text = opts.siteName - path = index - sitemap = Yes "1.0" } - Link - { text = opts.archivesTitle - path = $"{opts.archivesRoot}.html" - sitemap = Yes "0.9" } - Link - { text = opts.tagsTitle - path = $"{opts.tagsRoot}.html" - sitemap = Yes "0.9" } ] - @ opts.additionalNavs - @ [ Link - { text = "RSS" - path = feed - sitemap = No } ] - - let navbar, navSitemap = generateNavbar opts.pathRoot navs - - let devInjection, devScript = - match opts.stage with - | Development -> Some("/js/dev.js"), [ ("src/Dev.fs.js", $"{opts.dst}{opts.pathRoot}/js/dev.js") ] - | Production -> None, [] + let index, feed, navs = buildNavList opts + + let (navbar: Fable.React.ReactElement), navSitemap = + generateNavbar opts.pathRoot navs + + let devInjection, devScript = buildDevScript opts let site: FixedSiteContent = { lang = opts.lang @@ -591,39 +604,39 @@ let render (opts: RnderOptions) = title = opts.siteName description = opts.description url = opts.siteUrl - pathRoot = opts.pathRoot + pathRoot = opts.pathRoot // TODO: remove pathRoot from here and add to new created path type that includes src, dst and pathRoot. copyright = opts.copyright favicon = opts.favicon devInjection = devInjection } - let renderPostAndPages = renderMarkdowns site opts.tagsRoot - let! metaPosts = renderPostAndPages $"{opts.src}{opts.postsRoot}" $"{opts.dst}{opts.pathRoot}{opts.postsRoot}" - let! metaPages = renderPostAndPages $"{opts.src}{opts.pagesRoot}" $"{opts.dst}{opts.pathRoot}{opts.pagesRoot}" + let renderPostAndPages = renderMarkdowns site opts.tags.root + let! metaPosts = renderPostAndPages $"{opts.src}{opts.posts.root}" $"{opts.dst}{opts.pathRoot}{opts.posts.root}" + let! metaPages = renderPostAndPages $"{opts.src}{opts.pages.root}" $"{opts.dst}{opts.pathRoot}{opts.pages.root}" - do! renderIndex site opts.tagsRoot metaPosts $"{opts.dst}{opts.pathRoot}{index}" + do! renderIndex site opts.tags.root metaPosts $"{opts.dst}{opts.pathRoot}{index}" let archiveDefs = [ Posts - { title = opts.postsTitle + { title = opts.posts.title metas = metaPosts - root = opts.postsRoot + root = opts.posts.root priority = "0.8" } Pages - { title = opts.paesTitle + { title = opts.pages.title metas = metaPages - root = opts.pagesRoot + root = opts.pages.root priority = "0.8" } ] - let! archiveLocs = renderArchives site archiveDefs $"{opts.dst}{site.pathRoot}{opts.archivesRoot}.html" + let! archiveLocs = renderArchives site archiveDefs $"{opts.dst}{site.pathRoot}{opts.archives.root}.html" let tagDef = - { title = opts.tagsTitle + { title = opts.tags.title metas = Seq.concat [ metaPosts; metaPages ] - tagRoot = opts.tagsRoot - postRoot = opts.postsRoot + tagRoot = opts.tags.root + postRoot = opts.posts.root priority = "0.9" } - let! tagLocs = renderTags site tagDef $"{opts.dst}{site.pathRoot}{opts.tagsRoot}.html" + let! tagLocs = renderTags site tagDef $"{opts.dst}{site.pathRoot}{opts.tags.root}.html" do! render404 site $"{opts.dst}{opts.pathRoot}/404.html" do! @@ -634,14 +647,13 @@ let render (opts: RnderOptions) = tagLocs archiveLocs ]) - do! renderFeed { title = opts.siteName description = opts.description link = $"{opts.siteUrl}{opts.pathRoot}" feed = feed - postRoot = opts.postsRoot + postRoot = opts.posts.root posts = metaPosts } $"{opts.dst}{opts.pathRoot}{feed}" From 23307da7bdd0bc0c4e2e07a7a7d7e3264953667f Mon Sep 17 00:00:00 2001 From: krymtkts Date: Sat, 5 Aug 2023 11:43:44 +0900 Subject: [PATCH 2/5] Avoid to use dot notation for string and datetime. --- src/Common.fs | 15 +++++++++------ src/Generator.fs | 10 +++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Common.fs b/src/Common.fs index ea109ff..e55e8eb 100644 --- a/src/Common.fs +++ b/src/Common.fs @@ -29,7 +29,7 @@ module private Util = let heading = fun (text: string) (level: int) -> let escapedText = Regex.Replace(string text, @"[^\w]+", "-") - let l = level.ToString() + let l = string level $"""{text}""" @@ -311,6 +311,10 @@ module Misc = | x -> x) ) +module String = + + let inline format pattern x = + (^a: (member ToString: string -> string) (x, pattern)) module DateTime = open System @@ -331,7 +335,7 @@ module DateTime = let formatter: obj = Intl.DateTimeFormat "en-US" options let zonePattern = new Regex(@"GMT([+-])(\d+)") - let toRFC822DateTime (d: DateTime) = + let toRFC822DateTimeString (d: DateTime) = let parts: obj [] = formatter?formatToParts (d) let p: string [] = parts |> Array.map (fun x -> x?value) let d = $"{p.[0]}{p.[1]}{p.[4]} {p.[2]} {p.[6]}" @@ -350,8 +354,7 @@ module DateTime = $"{d} {t} {z}" -module String = - open System + let parseToRFC822DateTimeString (s: string) = + DateTime.Parse(s) |> toRFC822DateTimeString - let toRFC822DateTime (s: string) = - DateTime.Parse(s) |> DateTime.toRFC822DateTime + let toRFC3339Date (d: DateTime) = d |> String.format "yyyy-MM-dd" diff --git a/src/Generator.fs b/src/Generator.fs index f9d7eb0..ac9bf77 100644 --- a/src/Generator.fs +++ b/src/Generator.fs @@ -135,7 +135,7 @@ module Generation = |> Map.toList |> Seq.map (fun (tag, _) -> { loc = sourceToSitemap $"{pathRoot}{def.tagRoot}" $"{tag}.html" - lastmod = now.ToString("yyyy-MM-dd") + lastmod = now |> DateTime.toRFC3339Date priority = def.priority }) tagsContent, tagPageContens, locs @@ -163,7 +163,7 @@ module Generation = | Yes n -> Some { loc = $"{pathRoot}{navi.path}" - lastmod = now.ToString("yyyy-MM-dd") + lastmod = now |> DateTime.toRFC3339Date priority = n } | No -> None @@ -281,7 +281,7 @@ module Generation = | Some d -> d | None -> meta.date | None -> meta.date - |> String.toRFC822DateTime + |> DateTime.parseToRFC822DateTimeString { guid = link link = link @@ -299,7 +299,7 @@ module Generation = description = conf.description link = conf.link xml = conf.feed - lastBuildDate = now |> DateTime.toRFC822DateTime + lastBuildDate = now |> DateTime.toRFC822DateTimeString generator = generatorName } items @@ -364,7 +364,7 @@ module Rndering = let date = match layout with | Post d -> chooseDate fm d - | Page -> chooseDate fm <| now.ToString("yyyy-MM-dd") + | Page -> chooseDate fm <| DateTime.toRFC3339Date now return { frontMatter = fm From ab5317675b704bd254d340236d9cf14622331691 Mon Sep 17 00:00:00 2001 From: krymtkts Date: Sat, 5 Aug 2023 15:36:28 +0900 Subject: [PATCH 3/5] Avoid to use dot notation for regular expression. --- src/Common.fs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Common.fs b/src/Common.fs index e55e8eb..ea4624d 100644 --- a/src/Common.fs +++ b/src/Common.fs @@ -108,16 +108,21 @@ module Parser = abstract tags: string array option abstract date: string option - let private pattern = - Regex(@"^---\s*\n(?[\s\S]*?)\n?---\s*\n?(?[\s\S]*)") + let private matchFrontMatter s = + Regex.Match(s, @"^---\s*\n(?[\s\S]*?)\n?---\s*\n?(?[\s\S]*)") + + let (|Empty|Matched|) (xs: Match) = + match xs.Success with + | false -> Empty + | _ -> Matched xs let private extractFrontMatter (str: string) = - match pattern.IsMatch str with - | true -> - let matches = pattern.Match str - let f: FrontMatter = Yaml.parse matches.Groups.["frontMatter"].Value - Some(f), matches.Groups.["content"].Value - | _ -> None, str + matchFrontMatter str + |> function + | Empty -> None, str + | Matched matches -> + let f: FrontMatter = Yaml.parse matches.Groups.["frontMatter"].Value + Some(f), matches.Groups.["content"].Value /// Parses a markdown string let parseMarkdown str = Util.parseMarkdown str @@ -333,7 +338,6 @@ module DateTime = // TODO: write binding. let formatter: obj = Intl.DateTimeFormat "en-US" options - let zonePattern = new Regex(@"GMT([+-])(\d+)") let toRFC822DateTimeString (d: DateTime) = let parts: obj [] = formatter?formatToParts (d) @@ -345,7 +349,7 @@ module DateTime = match p.[14] with | "UTC" -> "+0000" | z -> - let item = zonePattern.Matches(z) + let item = Regex.Matches(z, @"GMT([+-])(\d+)") let group = item.Item 0 let op = (group.Groups.Item 1).Value let offset = int (group.Groups.Item 2).Value From 53d3019c3c6237994b4c51f0d7ed25b093a2740e Mon Sep 17 00:00:00 2001 From: krymtkts Date: Sat, 5 Aug 2023 15:46:01 +0900 Subject: [PATCH 4/5] Refine bindings. --- src/bindings/HighlightJs.fs | 13 +++++-------- src/bindings/Marked.fs | 4 ++-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/bindings/HighlightJs.fs b/src/bindings/HighlightJs.fs index 1a3f6a1..d48985e 100644 --- a/src/bindings/HighlightJs.fs +++ b/src/bindings/HighlightJs.fs @@ -1,11 +1,8 @@ // ts2fable 0.7.1 module rec HighlightJs -open System open Fable.Core -open Fable.Core.JsInterop - -type RegExp = System.Text.RegularExpressions.Regex +open System.Text.RegularExpressions [] let hljs: Hljs.IExports = jsNative @@ -27,7 +24,7 @@ module Hljs = abstract listLanguages: unit -> ResizeArray abstract getLanguage: name: string -> IMode abstract ``inherit``: parent: obj * obj: obj -> obj - abstract COMMENT: ``begin``: U2 * ``end``: U2 * inherits: IModeBase -> IMode + abstract COMMENT: ``begin``: U2 * ``end``: U2 * inherits: IModeBase -> IMode abstract IDENT_RE: string abstract UNDERSCORE_IDENT_RE: string abstract NUMBER_RE: string @@ -98,8 +95,8 @@ module Hljs = type IModeBase = abstract className: string option with get, set abstract aliases: ResizeArray option with get, set - abstract ``begin``: U2 option with get, set - abstract ``end``: U2 option with get, set + abstract ``begin``: U2 option with get, set + abstract ``end``: U2 option with get, set abstract case_insensitive: bool option with get, set abstract beginKeyword: string option with get, set abstract endsWithParent: bool option with get, set @@ -127,7 +124,7 @@ module Hljs = abstract compiled: bool with get, set abstract contains: ResizeArray option with get, set abstract keywords: obj option with get, set - abstract terminators: RegExp with get, set + abstract terminators: Regex with get, set abstract terminator_end: string option with get, set [] diff --git a/src/bindings/Marked.fs b/src/bindings/Marked.fs index 5555701..7c92611 100644 --- a/src/bindings/Marked.fs +++ b/src/bindings/Marked.fs @@ -2,11 +2,11 @@ module rec Marked open System +open System.Text.RegularExpressions open Fable.Core open Fable.Core.JS type Array<'T> = System.Collections.Generic.IList<'T> -type RegExp = System.Text.RegularExpressions.Regex [] let marked: Marked.IExports = jsNative @@ -349,7 +349,7 @@ module Marked = [] type Rules = [] - abstract Item: ruleName: string -> U2 with get, set + abstract Item: ruleName: string -> U2 with get, set [] type TokensList = From b713c8e97d04d7af33cd35b243f1fcf0be0df70d Mon Sep 17 00:00:00 2001 From: krymtkts Date: Sat, 5 Aug 2023 15:55:51 +0900 Subject: [PATCH 5/5] Reorder the modules. --- src/Common.fs | 13 ++++++------- src/bindings/HighlightJs.fs | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Common.fs b/src/Common.fs index ea4624d..e8ae628 100644 --- a/src/Common.fs +++ b/src/Common.fs @@ -1,13 +1,10 @@ module Common open System.Text.RegularExpressions -open Fable.Core.JsInterop open Fable.Core +open Fable.Core.JsInterop open Feliz open Node -open Marked -open HighlightJs -open Yaml module IO = let resolve (path: string) = File.absolutePath path @@ -19,6 +16,8 @@ module IO = let parent = Directory.dirname module private Util = + open HighlightJs + open Marked let mdToHtml s = Regex.Replace(s, @"\.md\b", ".html") @@ -103,6 +102,8 @@ module Component = liA ref <| Text title module Parser = + open Yaml + type FrontMatter = abstract title: string abstract tags: string array option @@ -173,9 +174,7 @@ module Misc = match leaf.Split '-' |> List.ofArray with | year :: month :: day :: _ -> - match [ year; month; day ] - |> List.map System.Int32.TryParse - with + match [ year; month; day ] |> List.map Int32.TryParse with | [ (true, year); (true, month); (true, day) ] -> let date = $"%04d{year}-%02d{month}-%02d{day}" Post(date) diff --git a/src/bindings/HighlightJs.fs b/src/bindings/HighlightJs.fs index d48985e..aa95c7c 100644 --- a/src/bindings/HighlightJs.fs +++ b/src/bindings/HighlightJs.fs @@ -1,8 +1,8 @@ // ts2fable 0.7.1 module rec HighlightJs -open Fable.Core open System.Text.RegularExpressions +open Fable.Core [] let hljs: Hljs.IExports = jsNative