diff --git a/asset/css/doc.css b/asset/css/doc.css index d46af508cd..045afd32eb 100644 --- a/asset/css/doc.css +++ b/asset/css/doc.css @@ -1,3 +1,5 @@ +[x-cloak] { display: none !important; } + div.odoc { max-width: 56rem /* 896px */; position: relative; @@ -186,7 +188,7 @@ div.odoc span.at-tag { font-weight: bold; } -div.odoc a { +div.odoc a:not(.source_code a) { font-weight: bold; color: #cc4e0c; } @@ -314,6 +316,24 @@ div.odoc .comment-delim { border-color: rgb(32, 68, 165); } +.navmap-tag.page-tag::after { + content: "P"; +} +.page-tag{ + color: rgb(32, 68, 165); + background-color: rgb(32, 68, 165); + border-color: rgb(32, 68, 165); +} + +.navmap-tag.source-tag::after { + content: "S"; +} +.source-tag{ + color: rgb(97, 8, 138); + background-color: rgb(97, 8, 138); + border-color: rgb(97, 8, 138); +} + span.icon-expand > .navmap-tag, span.no-expand > .navmap-tag { color: white; @@ -344,10 +364,12 @@ span.arrow-expand.open { } span.sign-expand::before { - content: " \002B"; + content: "\002B"; display: flex; + justify-content: center; align-items: center; font-size: 1.25rem; + width: 1.25rem; margin-top: -0.25rem; } @@ -359,3 +381,257 @@ span.sign-expand.open::before { /* Lists of modules */ .modules { list-style-type: none; padding-left:0; } + +/* Source links float inside preformated text or headings. */ +a.source_link { + float: right; + color: var(--source-link-color); + font-family: "Fira Sans", sans-serif; + font-size: initial; +} + + +.source_container { + display: flex; +} + +.source_line_column { + padding-right: 0.5em; + text-align: right; + color: var(--source-line-column); + background: var(--source-line-column-bg); +} + +.source_line { + padding: 0 1em; +} + +.source_code { + flex-grow: 1; + background: var(--code-background); + padding: 0 0.3em; + color: var(--code-color); +} + +/* Taken from odoc's css sheet */ + +:root, +.light:root { + + /* light gruvbox theme colors */ + --bg_h: #f9f5d7; + --bg: #f6f8fa; /*#fbf1c7;*/ + --bg_s: #f2e5bc; + --bg1: #ebdbb2; + --bg2: #d5c4a1; + --bg3: #bdae93; + --bg4: #a89984; + + --fg: #282828; + --fg1: #3c3836; + --fg2: #504945; + --fg3: #665c54; + --fg4: #7c6f64; + + --red: #9d0006; + --green: #79740e; + --yellow: #b57614; + --blue: #076678; + --purple: #8f3f71; + --aqua: #427b58; + --orange: #af3a03; + --gray: #928374; + + --red-dim: #cc2412; + --green-dim: #98971a; + --yellow-dim: #d79921; + --blue-dim: #458598; + --purple-dim: #b16286; + --aqua-dim: #689d6a; + --orange-dim: #d65d0e; + --gray-dim: #7c6f64; + + /* odoc colors */ + --odoc-blue: #5c9cf5; + --odoc-bg: #FFFFFF; + --odoc-bg1: #f6f8fa; + --odoc-fg: #333333; + --odoc-fg1: #1F2D3D; + +} + +@media (prefers-color-scheme: dark) { + :root { + /* dark gruvbox theme colors */ + --bg_h: #1d2021; + --bg: #282828; + --bg_s: #32302f; + --bg1: #3c3836; + --bg2: #504945; + --bg3: #665c54; + --bg4: #7c6f64; + + --fg: #fbf1c7; + --fg1: #ebdbb2; + --fg2: #d5c4a1; + --fg3: #bdae93; + --fg4: #a89984; + + --red: #fb4934; + --green: #b8bb26; + --yellow: #fabd2f; + --blue: #83a598; + --purple: #d3869b; + --aqua: #8ec07c; + --gray: #928374; + --orange: #fe8019; + + --red-dim: #cc2412; + --green-dim: #98971a; + --yellow-dim: #d79921; + --blue-dim: #458588; + --purple-dim: #b16286; + --aqua-dim: #689d6a; + --gray-dim: #a89984; + --orange-dim: #d65d0e; + + /* odoc colors */ + --odoc-blue: #5c9cf5; + --odoc-bg: #202020; + --odoc-bg1: #252525; + --odoc-fg: #bebebe; + --odoc-fg1: #777; + } +} + +:root { + --source-link-color: var(--fg4); + --source-line-column: var(--fg3); + --source-line-column-bg: var(--bg_h); + + --source-code-comment: var(--gray); + --source-code-docstring: var(--green-dim); + --source-code-lident: var(--fg1); + --source-code-uident: var(--blue); + --source-code-literal: var(--yellow); + --source-code-keyword: var(--red); + --source-code-underscore: var(--fg3); + --source-code-operator: var(--purple); + --source-code-parens: var(--orange-dim); + --source-code-separator: var(--orange-dim); +} + + +/* Linked highlight */ +.source_code *:target { + border-radius: 1px; + border: var(--orange-dim) 2px solid !important; +} + +/* Keywords */ +.AND, .ANDOP, .AS, .ASSERT, +.BAR, .BEGIN, +.CLASS, .CONSTRAINT, +.DO, .DONE, .DOWNTO, +.ELSE, .END, .EXCEPTION, .EXTERNAL, +.FOR, .FUN, .FUNCTION, .FUNCTOR, +.IF, .IN, .INCLUDE, .INHERIT, .INITIALIZER, +.LAZY, .LESSMINUS, .LET, .LETOP, +.MATCH, .METHOD, .MINUSGREATER, .MODULE, .MUTABLE, +.NEW, .NONREC, +.OBJECT, .OF, .OPEN, +.PERCENT, .PRIVATE, +.REC, +.SEMISEMI, .SIG, .STRUCT, +.THEN, .TO, .TRY, .TYPE, +.VAL, .VIRTUAL, +.WHEN, .WITH, .WHILE +{ + color: var(--source-code-keyword);; +} + +/* Separators */ +.COMMA, .COLON, .COLONGREATER, .SEMI { + color: var(--source-code-separator); +} + +/* Parens + `begin` and `end ` are excluded because `end` is used in other, more + keyword-y contexts*/ +.BARRBRACKET, +.LBRACE, +.LBRACELESS, +.LBRACKET, +.LBRACKETAT, +.LBRACKETATAT, +.LBRACKETATATAT, +.LBRACKETBAR, +.LBRACKETGREATER, +.LBRACKETLESS, +.LBRACKETPERCENT, +.LBRACKETPERCENTPERCENT, +.LPAREN, +.RBRACE, +.RBRACKET, +.RPAREN +{ + color: var(--source-code-parens); +} + +/* Prefix operators */ +.ASSERT, .BANG, .PREFIXOP, +/* Infix operators. + A choice had to be made for equal `=` which is both a keyword and an operator. + It looked better having it as an operator, because when it is a keyword, + there are already loads of keyword around. + It would look even nicer if there was a way to distinguish between these + two cases.*/ +.INFIXOP0, .INFIXOP1, .INFIXOP2, .INFIXOP3, .INFIXOP4, +.BARBAR, .PLUS, .STAR, .AMPERAMPER, .AMPERAND, .COLONEQUAL, .GREATER, .LESS, +.MINUS, .MINUSDOT, .MINUSGREATER, .OR, .PLUSDOT, .PLUSEQ, .EQUAL +{ + color: var(--source-code-operator); +} + +/* Upper case ident + `true` and `false` are considered uident here, because you can bind them in a + constructor defintion : + ```ocaml + type my_bool = + | true of string + | false + | Other of int + ``` +*/ +.UIDENT, .COLONCOLON, .TRUE, .FALSE { + color: var(--source-code-uident); + +} + +/* Lower case idents. + Quotes are here because of `type 'a t = 'a list`, + and question mark and tildes because of + ```ocaml + let f ~a ?b () = Option.map a b + ``` +*/ +.LIDENT, .QUESTION, .QUOTE, .TILDE { + color: var(--source-code-lident); +} + +/* Litterals */ + .STRING, .CHAR, .INT, .FLOAT, .QUOTED_STRING_EXPR, .QUOTED_STRING_ITEM { + color: var(--source-code-literal); +} + +.UNDERSCORE { + color: var(--source-code-underscore); +} + +.DOCSTRING { + color: var(--source-code-docstring); +} + +.COMMENT { + color: var(--source-code-comment); +} diff --git a/dune-project b/dune-project index 15fb213ca5..a2e1b951c3 100644 --- a/dune-project +++ b/dune-project @@ -75,6 +75,7 @@ ezjsonm lambdasoup ptime + ppx_deriving_yojson (cmdliner (>= 1.1.0)) xmlm diff --git a/ocamlorg.opam b/ocamlorg.opam index 837e74a55d..319be24612 100644 --- a/ocamlorg.opam +++ b/ocamlorg.opam @@ -50,6 +50,7 @@ depends: [ "ezjsonm" "lambdasoup" "ptime" + "ppx_deriving_yojson" "cmdliner" {>= "1.1.0"} "xmlm" "uri" diff --git a/src/ocamlorg_frontend/components/navmap.eml b/src/ocamlorg_frontend/components/navmap.eml index cf56383fa8..365d249ffa 100644 --- a/src/ocamlorg_frontend/components/navmap.eml +++ b/src/ocamlorg_frontend/components/navmap.eml @@ -8,6 +8,7 @@ type kind = | Class | Class_type | File + | Source type toc = { title : string; @@ -26,19 +27,22 @@ let kind_title = function | Parameter -> "Parameter" | Class -> "Class" | Class_type -> "Class type" + | Source -> "Source" | _ -> "?" -let title_style = "flex-1 flex-nowrap py-1 md:py-0.5 pr-1 text-title dark:text-dark-title" +let title_style = "flex-1 flex-nowrap py-1 md:py-0.5 pr-1 text-title dark:text-dark-title truncate" -let htmx_attributes = "hx-boost=\"true\" hx-ext=\"multi-swap\" hx-swap=\"multi:#htmx-head,#htmx-sidebar,#htmx-content,#htmx-right-sidebar,#htmx-breadcrumbs\" hx-push-url=\"true\"" +let htmx_attributes = "hx-boost=\"true\" hx-ext=\"multi-swap\" hx-swap=\"multi:#htmx-head,#htmx-content,#htmx-right-sidebar,#htmx-breadcrumbs\" hx-push-url=\"true\"" let icon_style = function + | Page -> "navmap-tag page-tag" | Library -> "navmap-tag library-tag" | Module -> "navmap-tag module-tag" | Module_type -> "navmap-tag module-type-tag" | Parameter -> "navmap-tag parameter-tag" | Class -> "navmap-tag class-tag" | Class_type -> "navmap-tag class-type-tag" + | Source -> "navmap-tag source-tag" | _ -> "navmap-tag" let rec nested_render ~path (item : toc) = @@ -56,10 +60,10 @@ let rec nested_render ~path (item : toc) = <%s icon_style item.kind %>"> <%s! item.title %> <% | Some href -> %> - class="flex"> + class="flex"> <%s icon_style item.kind %>"> - class="<%s title_style %> overflow-hidden truncate text-title dark:text-dark-title transition-colors hover:text-primary"> + class="<%s title_style %> overflow-hidden truncate text-title dark:text-dark-title transition-colors hover:text-primary"> <%s! item.title %> <% ); %> @@ -75,20 +79,20 @@ let rec nested_render ~path (item : toc) = let active_style = if item.title = fragment then (if List.length path = 0 then "bg-gray-200 dark:bg-dark-tertiary_bt_hover font-medium dark:font-semibold" else "border-transparent bg-gray-100 dark:bg-dark-tertiary_bt_hover font-medium dark:font-semibold") else "border-transparent" in
}">
-
"> +
"> <%s icon_style item.kind %>"> <% (match item.href with | None -> %> "> <%s! item.title %> - <%s! Icons.chevron_down "h-5 w-5" %> + <%s! Icons.chevron_down "h-5 w-5" %> <% | Some href -> %> - class="<%s title_style %> overflow-hidden truncate text-title dark:text-dark-title transition-colors hover:text-primary"> + class="<%s title_style %> overflow-hidden truncate text-title dark:text-dark-title transition-colors hover:text-primary"> <%s! item.title %> - + <% ); %>
@@ -108,7 +112,7 @@ let render (maptoc : t) = let version = Package.url_version package in -