diff --git a/common/App.re b/common/App.re index cc3645978..c1297c56c 100644 --- a/common/App.re +++ b/common/App.re @@ -18,6 +18,7 @@ let res = require('../plugins/res-syntax-highlightjs'); let bash = require('highlight.js/lib/languages/bash'); let json = require('highlight.js/lib/languages/json'); + let html = require('highlight.js/lib/languages/xml'); let ts = require('highlight.js/lib/languages/typescript'); let text = require('highlight.js/lib/languages/plaintext'); let diff = require('highlight.js/lib/languages/diff'); @@ -30,6 +31,7 @@ hljs.registerLanguage('sh', bash); hljs.registerLanguage('json', json); hljs.registerLanguage('text', text); + hljs.registerLanguage('html', html); hljs.registerLanguage('diff', diff); |}; @@ -123,12 +125,17 @@ let default = (props: props): React.element => { // to keep the frontmatter parsing etc in one place content | _ => + let title = + switch (url) { + | {base: [|"docs"|]} => Some("Overview | ReScript Documentation") + | _ => None + }; - +
content
-
+ ; } }; }; diff --git a/common/HighlightJs.re b/common/HighlightJs.re index 37ae3b407..a5716cd8e 100644 --- a/common/HighlightJs.re +++ b/common/HighlightJs.re @@ -25,9 +25,12 @@ let renderHLJS = Js.String2.split(highlighted, "\n") ->Belt.Array.mapWithIndex((i, line) => if (Js.Array2.find(highlightedLines, lnum => lnum === i + 1) !== None) { - "" ++ line ++ ""; + let content = line === "" ? " " : line; + "" ++ content ++ ""; } else { - line; + "" + ++ line + ++ ""; } ) ->Js.Array2.joinWith("\n"); @@ -37,15 +40,8 @@ let renderHLJS = let dark = darkmode ? "dark" : ""; - ReactDOMRe.createElementVariadic( - "code", - ~props= - ReactDOMRe.objToDOMProps({ - "className": "hljs lang-" ++ lang ++ " " ++ dark, - "dangerouslySetInnerHTML": { - "__html": highlighted, - }, - }), - [||], - ); + ; }; diff --git a/layouts/CommunityLayout.re b/layouts/CommunityLayout.re index 9f9a6591c..8d384a22c 100644 --- a/layouts/CommunityLayout.re +++ b/layouts/CommunityLayout.re @@ -61,7 +61,7 @@ let make = (~components=Markdown.default, ~children) => { let title = "Community"; - + children ; }; diff --git a/layouts/DocsLayout.re b/layouts/DocsLayout.re index c9c14d9c8..4758c8da1 100644 --- a/layouts/DocsLayout.re +++ b/layouts/DocsLayout.re @@ -11,7 +11,6 @@ module Category = Sidebar.Category; let makeBreadcrumbsFromPaths = (~basePath: string, paths: array(string)): list(Url.breadcrumb) => { - Js.log(paths); let (_, rest) = Belt.Array.reduce( paths, @@ -21,8 +20,7 @@ let makeBreadcrumbsFromPaths = let href = baseHref ++ "/" ++ path; - Js.Array2.push(ret, Url.{name: prettyString(path), href}) - ->ignore; + Js.Array2.push(ret, Url.{name: prettyString(path), href})->ignore; (href, ret); }, ); @@ -42,8 +40,7 @@ let makeBreadcrumbs = let href = baseHref ++ "/" ++ path; - Js.Array2.push(ret,Url.{name: prettyString(path), href}) - ->ignore; + Js.Array2.push(ret, Url.{name: prettyString(path), href})->ignore; (href, ret); }, ); @@ -55,6 +52,7 @@ let make = ( ~breadcrumbs: option(list(Url.breadcrumb))=?, ~title: string, + ~metaTitleCategory: option(string)=?, // e.g. Introduction | My Meta Title Category ~frontmatter: option(Js.Json.t)=?, ~version: option(string)=?, ~availableVersions: option(array(string))=?, @@ -139,7 +137,12 @@ let make = route />; - let metaTitle = title ++ " | ReScript Documentation"; + let metaTitle = + switch (metaTitleCategory) { + | Some(titleCategory) => + titleCategory ++ " | " ++ "ReScript Documentation" + | None => title + }; let metaElement = switch (frontmatter) { @@ -148,7 +151,11 @@ let make = | Ok(fm) => let canonical = Js.Null.toOption(fm.canonical); let description = Js.Null.toOption(fm.description); - let title = fm.title ++ " | ReScript Language Manual"; + let title = + switch (metaTitleCategory) { + | Some(titleCategory) => fm.title ++ " | " ++ titleCategory + | None => title + }; ; | Error(_) => React.null } @@ -166,3 +173,92 @@ let make = children ; }; + +module type StaticContent = { + /*let categories: array(SidebarLayout.Sidebar.Category.t);*/ + let tocData: SidebarLayout.Toc.raw; +}; + +module Make = (Content: StaticContent) => { + [@react.component] + let make = + ( + ~breadcrumbs: option(list(Url.breadcrumb))=?, + ~title: string, + ~metaTitleCategory: option(string)=?, + ~frontmatter: option(Js.Json.t)=?, + ~version: option(string)=?, + ~availableVersions: option(array(string))=?, + ~latestVersionLabel: option(string)=?, + /*~activeToc: option(SidebarLayout.Toc.t)=?,*/ + ~components: option(Mdx.Components.t)=?, + ~theme: option(ColorTheme.t)=?, + ~children: React.element, + ) => { + let router = Next.Router.useRouter(); + let route = router.route; + + let activeToc: option(SidebarLayout.Toc.t) = + Belt.Option.( + Js.Dict.get(Content.tocData, route) + ->map(data => { + open SidebarLayout.Toc; + let title = data##title; + let entries = + Belt.Array.map(data##headers, header => + {header: header##name, href: "#" ++ header##href} + ); + {title, entries}; + }) + ); + + let categories = { + let groups = + Js.Dict.entries(Content.tocData) + ->Belt.Array.reduce( + Js.Dict.empty(), + (acc, next) => { + let (_, value) = next; + switch (Js.Nullable.toOption(value##category)) { + | Some(category) => + switch (acc->Js.Dict.get(category)) { + | None => acc->Js.Dict.set(category, [|next|]) + | Some(arr) => + Js.Array2.push(arr, next)->ignore; + acc->Js.Dict.set(category, arr); + } + | None => + Js.log2("has NO category", next); + () + }; + acc; + }, + ); + Js.Dict.entries(groups) + ->Belt.Array.map(((name, values)) => { + Category.{ + name, + items: + Belt.Array.map(values, ((href, value)) => { + {NavItem.name: value##title, href} + }), + } + }); + }; + + make({ + "breadcrumbs": breadcrumbs, + "title": title, + "metaTitleCategory": metaTitleCategory, + "frontmatter": frontmatter, + "version": version, + "availableVersions": availableVersions, + "latestVersionLabel": latestVersionLabel, + "activeToc": activeToc, + "categories": categories, + "components": components, + "theme": theme, + "children": children, + }); + }; +}; diff --git a/layouts/ManualDocsLayout.re b/layouts/ManualDocsLayout.re index e3cd4e31e..694b0c063 100644 --- a/layouts/ManualDocsLayout.re +++ b/layouts/ManualDocsLayout.re @@ -200,6 +200,7 @@ module Docs = { categories version title + metaTitleCategory="ReScript Language Manual" availableVersions=allManualVersions latestVersionLabel ?frontmatter diff --git a/layouts/ManualDocsLayout8_0_0.re b/layouts/ManualDocsLayout8_0_0.re index 773db2480..0349cf11c 100644 --- a/layouts/ManualDocsLayout8_0_0.re +++ b/layouts/ManualDocsLayout8_0_0.re @@ -220,6 +220,7 @@ module Docs = { latestVersionLabel=ManualDocsLayout.latestVersionLabel ?frontmatter title + metaTitleCategory="ReScript Language Manual" ?activeToc breadcrumbs> warnBanner diff --git a/layouts/SidebarLayout.re b/layouts/SidebarLayout.re index 48314e63d..7370fb7d3 100644 --- a/layouts/SidebarLayout.re +++ b/layouts/SidebarLayout.re @@ -8,6 +8,19 @@ open Util.ReactStuff; module Link = Next.Link; module Toc = { + type raw = + Js.Dict.t({ + . + "title": string, + "category": Js.Nullable.t(string), + "headers": + array({ + . + "name": string, + "href": string, + }), + }); + type entry = { header: string, href: string, @@ -20,25 +33,16 @@ module Toc = { [@react.component] let make = (~entries: array(entry)) => { - let router = Next.Router.useRouter(); ; @@ -324,4 +328,4 @@ let make = ; -}; \ No newline at end of file +}; diff --git a/package.json b/package.json index 7be4cc7cf..166e1a372 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "react": "^16.12.0", "react-dom": "^16.12.0", "reason-promise": "^1.0.2", - "reason-react": "^0.7.0", + "reason-react": "^0.9.1", "remark-parse": "^7.0.1", "remark-slug": "^5.1.2", "remark-stringify": "^7.0.3", diff --git a/scripts/extract-tocs.js b/scripts/extract-tocs.js index 357f1bd5e..ca0516e34 100644 --- a/scripts/extract-tocs.js +++ b/scripts/extract-tocs.js @@ -11,6 +11,21 @@ const glob = require("glob"); const path = require("path"); const fs = require("fs"); +// orderArr: ["introduction", "overview",,...] +const orderFiles = (filepaths, orderArr) => { + const order = orderArr.reduce((acc, next, i) => { + acc[next] = null; + return acc; + }, {}); + + filepaths.forEach((filepath) => { + const id = path.basename(filepath, path.extname(filepath)); + order[id] = filepath; + }); + + return Object.values(order); +}; + // Used for collapsing nested inlineCodes with the actual header text const collapseHeaderChildren = (children) => { return children.reduce((acc, node) => { @@ -63,11 +78,18 @@ const processFile = filepath => { const parsedPath = path.parse(relFilepath); const filename = path.basename(filepath, path.extname(filepath)); + let title = result.data.mainHeader || data.title || filename; + const dataset = { + id: filename, headers: result.data.headers, href: path.join(parsedPath.dir, parsedPath.name), - title: result.data.mainHeader || filename + title, }; + + if(data.category != null) { + dataset.category = data.category; + } return dataset; }; @@ -76,10 +98,12 @@ const createTOC = result => { // reflected as the router pathname, as defined by the // NextJS router return result.reduce((acc, data) => { - const { title, headers } = data; + const { title, headers, category, id } = data; acc["/" + data.href] = { + id, title, - headers + headers, + category, }; return acc; @@ -119,17 +143,6 @@ const createV800ManualToc = () => { fs.writeFileSync(TARGET_FILE, JSON.stringify(toc), "utf8"); }; -const createReasonReactToc = () => { - const MD_DIR = path.join(__dirname, "../pages/docs/reason-react/latest"); - const TARGET_FILE = path.join(__dirname, "../index_data/reason_react_toc.json"); - - const files = glob.sync(`${MD_DIR}/*.md?(x)`); - const result = files.map(processFile); - const toc = createTOC(result); - - fs.writeFileSync(TARGET_FILE, JSON.stringify(toc), "utf8"); -}; - const createGenTypeToc = () => { const MD_DIR = path.join(__dirname, "../pages/docs/gentype/latest"); const TARGET_FILE = path.join(__dirname, "../index_data/gentype_toc.json"); @@ -171,6 +184,5 @@ debugToc(); createLatestManualToc(); createV800ManualToc(); createReasonCompilerToc(); -createReasonReactToc(); createGenTypeToc(); createCommunityToc(); diff --git a/styles/_hljs.css b/styles/_hljs.css index b39841336..988b72aee 100644 --- a/styles/_hljs.css +++ b/styles/_hljs.css @@ -114,10 +114,6 @@ Docco style used in http://jashkenas.github.com/docco/ converted by Simon Madine /*@apply text-code-1;*/ } -.hljs-line-highlight { - @apply w-full inline-block bg-berry-15; -} - /* DARK MODE COLORS */ .hljs.dark .hljs-comment { diff --git a/styles/_markdown.css b/styles/_markdown.css index fa8c7b80c..1dc368127 100644 --- a/styles/_markdown.css +++ b/styles/_markdown.css @@ -1,7 +1,7 @@ /* Markdown related stuff */ /* Sometimes we cannot circumvent the cascade, especially for nested lists */ -.md-ul { +.md-ul, .md-ol { @apply mb-4; } diff --git a/yarn.lock b/yarn.lock index a46dca976..050bc4672 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5809,7 +5809,7 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" -react-dom@>=16.8.1, react-dom@^16.12.0: +react-dom@^16.12.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag== @@ -5829,7 +5829,7 @@ react-refresh@0.8.3: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== -react@>=16.8.1, react@^16.12.0: +react@^16.12.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w== @@ -5893,13 +5893,10 @@ reason-promise@^1.0.2: resolved "https://registry.yarnpkg.com/reason-promise/-/reason-promise-1.1.1.tgz#966133fed21e748a50ffb8839a1da04912bcf380" integrity sha512-xMXDiyzTjn7t9pq9aQrkgu8CLB5DILU70oWQ+LI20YecshypUwsw37TKOvCxgoFR3vo30ucF0/iWe2BZ181/jw== -reason-react@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/reason-react/-/reason-react-0.7.1.tgz#e6acea88542cd44398cd980093b8a2ab2722744e" - integrity sha512-Ssx4jZYohMHW9ZiW893IfbYdZw/muSmPFKigAgL+AORUgyiaphb0PP4yRGlx9A7JAxR3EeBn294XKUaClJQhbA== - dependencies: - react ">=16.8.1" - react-dom ">=16.8.1" +reason-react@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/reason-react/-/reason-react-0.9.1.tgz#30a887158200b659aa03e2d75ff4cc54dc462bb0" + integrity sha512-nlH0O2TDy9KzOLOW+vlEQk4ExHOeciyzFdoLcsmmiit6hx6H5+CVDrwJ+8aiaLT/kqK5xFOjy4PS7PftWz4plA== reduce-css-calc@^2.1.6: version "2.1.7"