Commit c196720
Changed files (14)
cmd
gitmal
internal
cmd/gitmal/main.go
@@ -107,6 +107,10 @@ func main() {
generator.Echo(fmt.Sprintf("> %s: %d branches, %d tags, %d commits", params.Name, len(branches), len(tags), len(commits)))
+ if err := generator.GenerateCSS(params); err != nil {
+ panic(err)
+ }
+
if err := generator.GenerateBranches(branches, defaultBranch, params); err != nil {
panic(err)
}
internal/generator/blob.go
@@ -34,7 +34,6 @@ func GenerateBlobs(files []git.Blob, params Params) error {
html.WithCSSComments(false),
}
- css := cssSyntax(formatterOptions)
dirsSet := links.BuildDirSet(files)
filesSet := links.BuildFileSet(files)
@@ -92,12 +91,12 @@ func GenerateBlobs(files []git.Blob, params Params) error {
return templates.MarkdownTemplate.ExecuteTemplate(f, "layout.gohtml", templates.MarkdownParams{
LayoutParams: templates.LayoutParams{
- Title: fmt.Sprintf("%s/%s at %s", params.Name, blob.Path, params.Ref),
- CSSMarkdown: cssMarkdown(),
- Name: params.Name,
- RootHref: rootHref,
- CurrentRefDir: params.Ref.DirName(),
- Selected: "code",
+ Title: fmt.Sprintf("%s/%s at %s", params.Name, blob.Path, params.Ref),
+ Name: params.Name,
+ RootHref: rootHref,
+ CurrentRefDir: params.Ref.DirName(),
+ Selected: "code",
+ NeedsMarkdownCSS: true,
},
HeaderParams: templates.HeaderParams{
Ref: params.Ref,
@@ -145,17 +144,17 @@ func GenerateBlobs(files []git.Blob, params Params) error {
return templates.BlobTemplate.ExecuteTemplate(f, "layout.gohtml", templates.BlobParams{
LayoutParams: templates.LayoutParams{
- Title: fmt.Sprintf("%s/%s at %s", params.Name, blob.Path, params.Ref),
- Name: params.Name,
- RootHref: rootHref,
- CurrentRefDir: params.Ref.DirName(),
- Selected: "code",
+ Title: fmt.Sprintf("%s/%s at %s", params.Name, blob.Path, params.Ref),
+ Name: params.Name,
+ RootHref: rootHref,
+ CurrentRefDir: params.Ref.DirName(),
+ Selected: "code",
+ NeedsSyntaxCSS: !isBin,
},
HeaderParams: templates.HeaderParams{
Ref: params.Ref,
Breadcrumbs: breadcrumbs(params.Name, blob.Path, true),
},
- CSS: css,
Blob: blob,
IsBinary: isBin,
IsImage: isImg,
@@ -165,21 +164,3 @@ func GenerateBlobs(files []git.Blob, params Params) error {
)
}
-func cssSyntax(opts []html.Option) template.CSS {
- formatter := html.New(opts...)
- lightStyle := styles.Get("github")
- darkStyle := styles.Get("github-dark")
-
- var light, dark strings.Builder
- _ = formatter.WriteCSS(&light, lightStyle)
- _ = formatter.WriteCSS(&dark, darkStyle)
-
- return template.CSS(
- "@media (prefers-color-scheme: light) {\n" +
- light.String() +
- "\n}\n" +
- "@media (prefers-color-scheme: dark) {\n" +
- dark.String() +
- "\n}",
- )
-}
internal/generator/commit.go
@@ -9,7 +9,6 @@ import (
"sort"
"strings"
- "github.com/alecthomas/chroma/v2"
"github.com/alecthomas/chroma/v2/formatters/html"
"github.com/alecthomas/chroma/v2/lexers"
"github.com/alecthomas/chroma/v2/styles"
@@ -50,26 +49,9 @@ func generateCommitPage(commit git.Commit, params Params) error {
formatter := html.New(
html.WithClasses(true),
html.WithCSSComments(false),
- html.WithCustomCSS(map[chroma.TokenType]string{
- chroma.GenericInserted: "display: block;",
- chroma.GenericDeleted: "display: block;",
- }),
)
lightStyle := styles.Get("github")
- darkStyle := styles.Get("github-dark")
-
- var lightCSS, darkCSS bytes.Buffer
- _ = formatter.WriteCSS(&lightCSS, lightStyle)
- _ = formatter.WriteCSS(&darkCSS, darkStyle)
-
- diffCSS := "@media (prefers-color-scheme: light) {\n" +
- lightCSS.String() +
- "\n}\n" +
- "@media (prefers-color-scheme: dark) {\n" +
- darkCSS.String() +
- "\n}"
-
lexer := lexers.Get("diff")
if lexer == nil {
return fmt.Errorf("failed to get lexer for diff")
@@ -171,14 +153,14 @@ func generateCommitPage(commit git.Commit, params Params) error {
err = templates.CommitTemplate.ExecuteTemplate(f, "layout.gohtml", templates.CommitParams{
LayoutParams: templates.LayoutParams{
- Title: fmt.Sprintf("%s %s %s@%s", commit.Subject, Dot, params.Name, commit.ShortHash),
- Name: params.Name,
- RootHref: rootHref,
- CurrentRefDir: currentRef.DirName(),
- Selected: "commits",
+ Title: fmt.Sprintf("%s %s %s@%s", commit.Subject, Dot, params.Name, commit.ShortHash),
+ Name: params.Name,
+ RootHref: rootHref,
+ CurrentRefDir: currentRef.DirName(),
+ Selected: "commits",
+ NeedsSyntaxCSS: true,
},
Commit: commit,
- DiffCSS: template.CSS(diffCSS),
FileTree: fileTree,
FileViews: filesViews,
})
internal/generator/css.go
@@ -0,0 +1,86 @@
+package generator
+
+import (
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/alecthomas/chroma/v2"
+ "github.com/alecthomas/chroma/v2/formatters/html"
+ "github.com/alecthomas/chroma/v2/styles"
+
+ "mokhan.ca/antonmedv/gitmal/internal/templates"
+)
+
+func GenerateCSS(params Params) error {
+ cssDir := filepath.Join(params.OutputDir, "css")
+ if err := os.MkdirAll(cssDir, 0o755); err != nil {
+ return err
+ }
+
+ if err := writeLayoutCSS(cssDir); err != nil {
+ return err
+ }
+ if err := writeMarkdownCSS(cssDir); err != nil {
+ return err
+ }
+ if err := writeSyntaxCSS(cssDir); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func writeLayoutCSS(cssDir string) error {
+ return os.WriteFile(filepath.Join(cssDir, "layout.css"), []byte(templates.LayoutCSS), 0o644)
+}
+
+func writeMarkdownCSS(cssDir string) error {
+ css := "@media (prefers-color-scheme: light) {\n" +
+ templates.CSSMarkdownLight +
+ "\n}\n" +
+ "@media (prefers-color-scheme: dark) {\n" +
+ templates.CSSMarkdownDark +
+ "\n}"
+ return os.WriteFile(filepath.Join(cssDir, "markdown.css"), []byte(css), 0o644)
+}
+
+func writeSyntaxCSS(cssDir string) error {
+ formatterOptions := []html.Option{
+ html.WithLineNumbers(true),
+ html.WithLinkableLineNumbers(true, "L"),
+ html.WithClasses(true),
+ html.WithCSSComments(false),
+ }
+
+ formatter := html.New(formatterOptions...)
+ lightStyle := styles.Get("github")
+ darkStyle := styles.Get("github-dark")
+
+ var light, dark strings.Builder
+ _ = formatter.WriteCSS(&light, lightStyle)
+ _ = formatter.WriteCSS(&dark, darkStyle)
+
+ diffFormatter := html.New(
+ html.WithClasses(true),
+ html.WithCSSComments(false),
+ html.WithCustomCSS(map[chroma.TokenType]string{
+ chroma.GenericInserted: "display: block;",
+ chroma.GenericDeleted: "display: block;",
+ }),
+ )
+ var diffLight, diffDark strings.Builder
+ _ = diffFormatter.WriteCSS(&diffLight, lightStyle)
+ _ = diffFormatter.WriteCSS(&diffDark, darkStyle)
+
+ css := "@media (prefers-color-scheme: light) {\n" +
+ light.String() +
+ diffLight.String() +
+ "\n}\n" +
+ "@media (prefers-color-scheme: dark) {\n" +
+ dark.String() +
+ diffDark.String() +
+ "\n}"
+
+ return os.WriteFile(filepath.Join(cssDir, "syntax.css"), []byte(css), 0o644)
+}
internal/generator/index.go
@@ -100,12 +100,12 @@ func GenerateIndex(files []git.Blob, params Params) error {
err = templates.ListTemplate.ExecuteTemplate(f, "layout.gohtml", templates.ListParams{
LayoutParams: templates.LayoutParams{
- Title: title,
- Name: params.Name,
- CSSMarkdown: cssMarkdown(),
- RootHref: rootHref,
- CurrentRefDir: params.Ref.DirName(),
- Selected: "code",
+ Title: title,
+ Name: params.Name,
+ RootHref: rootHref,
+ CurrentRefDir: params.Ref.DirName(),
+ Selected: "code",
+ NeedsMarkdownCSS: readmeHTML != "",
},
HeaderParams: templates.HeaderParams{
Ref: params.Ref,
internal/generator/list.go
@@ -2,7 +2,6 @@ package generator
import (
"fmt"
- "html/template"
"os"
"path/filepath"
"sort"
@@ -127,19 +126,15 @@ func GenerateLists(files []git.Blob, params Params) error {
rootHref := strings.Repeat("../", depth+2)
readmeHTML := readme(di.files, dirsSet, filesSet, params, rootHref)
- var CSSMarkdown template.CSS
- if readmeHTML != "" {
- CSSMarkdown = cssMarkdown()
- }
return templates.ListTemplate.ExecuteTemplate(f, "layout.gohtml", templates.ListParams{
LayoutParams: templates.LayoutParams{
- Title: title,
- Name: params.Name,
- CSSMarkdown: CSSMarkdown,
- RootHref: rootHref,
- CurrentRefDir: params.Ref.DirName(),
- Selected: "code",
+ Title: title,
+ Name: params.Name,
+ RootHref: rootHref,
+ CurrentRefDir: params.Ref.DirName(),
+ Selected: "code",
+ NeedsMarkdownCSS: readmeHTML != "",
},
HeaderParams: templates.HeaderParams{
Ref: params.Ref,
internal/generator/markdown.go
@@ -1,15 +1,11 @@
package generator
import (
- "html/template"
-
"github.com/yuin/goldmark"
highlighting "github.com/yuin/goldmark-highlighting/v2"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
gmhtml "github.com/yuin/goldmark/renderer/html"
-
- "mokhan.ca/antonmedv/gitmal/internal/templates"
)
func createMarkdown() goldmark.Markdown {
@@ -29,14 +25,3 @@ func createMarkdown() goldmark.Markdown {
),
)
}
-
-func cssMarkdown() template.CSS {
- return template.CSS(
- "@media (prefers-color-scheme: light) {\n" +
- templates.CSSMarkdownLight +
- "\n}\n" +
- "@media (prefers-color-scheme: dark) {\n" +
- templates.CSSMarkdownDark +
- "\n}",
- )
-}
internal/templates/css/layout.css
@@ -0,0 +1,257 @@
+:root {
+ --c-indigo-1: #3451b2;
+ --c-indigo-2: #3a5ccc;
+ --c-indigo-3: #5672cd;
+ --c-green: #1a7f37;
+ --c-red: #c53030;
+ --c-yellow: #9a6700;
+ --c-dir: #54aeff;
+ --c-gray-soft: rgba(142, 150, 170, .14);
+ --c-bg: #ffffff;
+ --c-bg-alt: #f6f6f7;
+ --c-bg-elv: #ffffff;
+ --c-text-1: rgba(60, 60, 67);
+ --c-text-2: rgba(60, 60, 67, .78);
+ --c-text-3: rgba(60, 60, 67, .56);
+ --c-border: #c2c2c4;
+ --c-divider: #e2e2e3;
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --c-indigo-1: #a8b1ff;
+ --c-indigo-2: #5c73e7;
+ --c-indigo-3: #3e63dd;
+ --c-green: #57ab5a;
+ --c-red: #e5534b;
+ --c-yellow: #c69026;
+ --c-dir: #9198a1;
+ --c-gray-soft: rgba(101, 117, 133, .16);
+ --c-bg: #1b1b1f;
+ --c-bg-alt: #161618;
+ --c-bg-elv: #202127;
+ --c-text-1: rgba(255, 255, 245, .86);
+ --c-text-2: rgba(235, 235, 245, .6);
+ --c-text-3: rgba(235, 235, 245, .38);
+ --c-border: #3c3f44;
+ --c-divider: #2e2e32;
+ }
+}
+
+:root {
+ --c-brand-1: var(--c-indigo-1);
+ --c-brand-2: var(--c-indigo-2);
+ --c-brand-3: var(--c-indigo-3);
+ --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+ --font-family-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+ --code-line-height: 20px;
+ --code-font-size: 12px;
+ --code-color: var(--c-brand-1);
+ --code-bg: var(--c-gray-soft);
+ --code-block-bg: var(--c-bg-alt);
+ --code-block-color: var(--c-text-1);
+ --header-height: 46px;
+ --border-radius: 6px;
+ --max-content-width: 1470px;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ font-family: var(--font-family), sans-serif;
+ font-size: 14px;
+ line-height: 1;
+ color: var(--c-text-1);
+ background-color: var(--c-bg);
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -moz-text-size-adjust: none;
+ -webkit-text-size-adjust: none;
+ text-size-adjust: none;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+.nowrap {
+ white-space: nowrap;
+}
+
+h1 {
+ margin-inline: 0;
+ margin-block: 16px;
+ font-size: 20px;
+ font-weight: 600;
+}
+
+a {
+ color: var(--c-brand-1);
+ font-weight: 500;
+ text-decoration: underline;
+ text-underline-offset: 2px;
+ text-decoration: inherit;
+ touch-action: manipulation;
+}
+
+a:hover {
+ color: var(--c-brand-2);
+ text-decoration: underline;
+}
+
+.menu {
+ background-color: var(--c-bg-alt);
+ border-bottom: 1px solid var(--c-divider);
+ overflow-x: auto;
+}
+
+.menu-content {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 16px;
+ padding-inline: 16px;
+ max-width: var(--max-content-width);
+ margin-inline: auto;
+}
+
+.menu-item {
+ display: flex;
+ align-items: center;
+ border-bottom: 2px solid transparent;
+ height: 56px;
+ padding-inline: 8px;
+}
+
+.menu-item a {
+ display: flex;
+ flex-direction: row;
+ gap: 8px;
+ align-items: center;
+ color: var(--c-text-1);
+ padding: 8px 10px;
+ border-radius: 4px;
+}
+
+.menu-item a:hover {
+ background-color: var(--c-bg-elv);
+ text-decoration: none;
+}
+
+.menu-item.selected {
+ border-bottom-color: var(--c-brand-1);
+}
+
+.project-name {
+ font-weight: 600;
+ font-size: 16px;
+ margin-inline: 16px;
+ color: var(--c-text-1);
+ text-decoration: none;
+}
+
+main {
+ flex-grow: 1;
+ width: 100%;
+ max-width: var(--max-content-width);
+ margin: 16px auto;
+}
+
+.main-content {
+ padding-inline: 16px;
+}
+
+footer {
+ padding: 12px 16px;
+ background-color: var(--c-bg-alt);
+ border-top: 1px solid var(--c-divider);
+ color: var(--c-text-3);
+ font-size: 12px;
+ text-align: center;
+}
+
+.header-container {
+ container-type: scroll-state;
+ position: sticky;
+ top: 0;
+}
+
+.header-container {
+ @container scroll-state(stuck: top) {
+ header {
+ border-top: none;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+
+ .goto-top {
+ display: flex;
+ }
+ }
+}
+
+header {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ min-height: var(--header-height);
+ padding-inline: 16px;
+ background: var(--c-bg-alt);
+ border: 1px solid var(--c-border);
+ border-top-left-radius: var(--border-radius);
+ border-top-right-radius: var(--border-radius);
+}
+
+header h1 {
+ word-break: break-all;
+ font-weight: 600;
+ font-size: 16px;
+ margin: 0;
+ padding: 0;
+}
+
+.header-ref {
+ color: var(--c-text-2);
+ border: 1px solid var(--c-border);
+ border-radius: 6px;
+ padding: 6px 10px;
+ margin-right: 10px;
+ margin-left: -6px;
+}
+
+header .path {
+ font-size: 16px;
+}
+
+.breadcrumbs {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ gap: 6px;
+ font-size: 16px;
+}
+
+.breadcrumbs a {
+ word-break: break-all;
+}
+
+.goto-top {
+ display: none;
+ margin-left: auto;
+ padding: 6px 10px;
+ background: none;
+ border: none;
+ border-radius: 6px;
+ gap: 4px;
+ align-items: center;
+ color: var(--c-text-1);
+ cursor: pointer;
+}
+
+.goto-top:hover {
+ background: var(--c-bg-elv);
+}
internal/templates/blob.gohtml
@@ -1,8 +1,6 @@
{{- /*gotype: mokhan.ca/antonmedv/gitmal/pkg/templates.BlobParams */ -}}
{{ define "head" }}
<style>
- {{ .CSS }}
-
[id] {
scroll-margin-top: var(--header-height);
}
internal/templates/commit.gohtml
@@ -214,8 +214,6 @@
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
}
-
- {{ .DiffCSS }}
</style>
{{ end }}
internal/templates/layout.gohtml
@@ -5,265 +5,9 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ .Title }}</title>
- <style>
- :root {
- --c-indigo-1: #3451b2;
- --c-indigo-2: #3a5ccc;
- --c-indigo-3: #5672cd;
- --c-green: #1a7f37;
- --c-red: #c53030;
- --c-yellow: #9a6700;
- --c-dir: #54aeff;
- --c-gray-soft: rgba(142, 150, 170, .14);
- --c-bg: #ffffff;
- --c-bg-alt: #f6f6f7;
- --c-bg-elv: #ffffff;
- --c-text-1: rgba(60, 60, 67);
- --c-text-2: rgba(60, 60, 67, .78);
- --c-text-3: rgba(60, 60, 67, .56);
- --c-border: #c2c2c4;
- --c-divider: #e2e2e3;
- }
-
- @media (prefers-color-scheme: dark) {
- :root {
- --c-indigo-1: #a8b1ff;
- --c-indigo-2: #5c73e7;
- --c-indigo-3: #3e63dd;
- --c-green: #57ab5a;
- --c-red: #e5534b;
- --c-yellow: #c69026;
- --c-dir: #9198a1;
- --c-gray-soft: rgba(101, 117, 133, .16);
- --c-bg: #1b1b1f;
- --c-bg-alt: #161618;
- --c-bg-elv: #202127;
- --c-text-1: rgba(255, 255, 245, .86);
- --c-text-2: rgba(235, 235, 245, .6);
- --c-text-3: rgba(235, 235, 245, .38);
- --c-border: #3c3f44;
- --c-divider: #2e2e32;
- }
- }
-
- :root {
- --c-brand-1: var(--c-indigo-1);
- --c-brand-2: var(--c-indigo-2);
- --c-brand-3: var(--c-indigo-3);
- --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
- --font-family-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- --code-line-height: 20px;
- --code-font-size: 12px;
- --code-color: var(--c-brand-1);
- --code-bg: var(--c-gray-soft);
- --code-block-bg: var(--c-bg-alt);
- --code-block-color: var(--c-text-1);
- --header-height: 46px;
- --border-radius: 6px;
- --max-content-width: 1470px;
- }
-
- * {
- box-sizing: border-box;
- }
-
- body {
- margin: 0;
- padding: 0;
- font-family: var(--font-family), sans-serif;
- font-size: 14px;
- line-height: 1;
- color: var(--c-text-1);
- background-color: var(--c-bg);
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- -moz-text-size-adjust: none;
- -webkit-text-size-adjust: none;
- text-size-adjust: none;
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- }
-
- .nowrap {
- white-space: nowrap;
- }
-
- h1 {
- margin-inline: 0;
- margin-block: 16px;
- font-size: 20px;
- font-weight: 600;
- }
-
- a {
- color: var(--c-brand-1);
- font-weight: 500;
- text-decoration: underline;
- text-underline-offset: 2px;
- text-decoration: inherit;
- touch-action: manipulation;
- }
-
- a:hover {
- color: var(--c-brand-2);
- text-decoration: underline;
- }
-
- .menu {
- background-color: var(--c-bg-alt);
- border-bottom: 1px solid var(--c-divider);
- overflow-x: auto;
- }
-
- .menu-content {
- display: flex;
- flex-direction: row;
- align-items: center;
- gap: 16px;
- padding-inline: 16px;
- max-width: var(--max-content-width);
- margin-inline: auto;
- }
-
- .menu-item {
- display: flex;
- align-items: center;
- border-bottom: 2px solid transparent;
- height: 56px;
- padding-inline: 8px;
- }
-
- .menu-item a {
- display: flex;
- flex-direction: row;
- gap: 8px;
- align-items: center;
- color: var(--c-text-1);
- padding: 8px 10px;
- border-radius: 4px;
- }
-
- .menu-item a:hover {
- background-color: var(--c-bg-elv);
- text-decoration: none;
- }
-
- .menu-item.selected {
- border-bottom-color: var(--c-brand-1);
- }
-
- .project-name {
- font-weight: 600;
- font-size: 16px;
- margin-inline: 16px;
- color: var(--c-text-1);
- text-decoration: none;
- }
-
- main {
- flex-grow: 1;
- width: 100%;
- max-width: var(--max-content-width);
- margin: 16px auto;
- }
-
- .main-content {
- padding-inline: 16px;
- }
-
- footer {
- padding: 12px 16px;
- background-color: var(--c-bg-alt);
- border-top: 1px solid var(--c-divider);
- color: var(--c-text-3);
- font-size: 12px;
- text-align: center;
- }
-
- .header-container {
- container-type: scroll-state;
- position: sticky;
- top: 0;
- }
-
- .header-container {
- @container scroll-state(stuck: top) {
- header {
- border-top: none;
- border-top-left-radius: 0;
- border-top-right-radius: 0;
- }
-
- .goto-top {
- display: flex;
- }
- }
- }
-
- header {
- display: flex;
- flex-direction: row;
- align-items: center;
- min-height: var(--header-height);
- padding-inline: 16px;
- background: var(--c-bg-alt);
- border: 1px solid var(--c-border);
- border-top-left-radius: var(--border-radius);
- border-top-right-radius: var(--border-radius);
- }
-
- header h1 {
- word-break: break-all;
- font-weight: 600;
- font-size: 16px;
- margin: 0;
- padding: 0;
- }
-
- .header-ref {
- color: var(--c-text-2);
- border: 1px solid var(--c-border);
- border-radius: 6px;
- padding: 6px 10px;
- margin-right: 10px;
- margin-left: -6px;
- }
-
- header .path {
- font-size: 16px;
- }
-
- .breadcrumbs {
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- gap: 6px;
- font-size: 16px;
- }
-
- .breadcrumbs a {
- word-break: break-all;
- }
-
- .goto-top {
- display: none;
- margin-left: auto;
- padding: 6px 10px;
- background: none;
- border: none;
- border-radius: 6px;
- gap: 4px;
- align-items: center;
- color: var(--c-text-1);
- cursor: pointer;
- }
-
- .goto-top:hover {
- background: var(--c-bg-elv);
- }
- </style>
+ <link rel="stylesheet" href="{{ .RootHref }}css/layout.css">
+ {{- if .NeedsMarkdownCSS }}<link rel="stylesheet" href="{{ .RootHref }}css/markdown.css">{{ end }}
+ {{- if .NeedsSyntaxCSS }}<link rel="stylesheet" href="{{ .RootHref }}css/syntax.css">{{ end }}
{{ template "head" . }}
</head>
<body>
internal/templates/markdown.gohtml
@@ -29,8 +29,6 @@
padding: 16px;
}
}
-
- {{.CSSMarkdown}}
</style>
{{ end }}
internal/templates/svg.gohtml
@@ -1,50 +1,38 @@
{{ define "svg" }}
- <svg style="display: none" aria-hidden="true" focusable="false">
- <symbol id="dir" viewBox="0 0 16 16">
- <path fill="currentColor"
- d="M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z"/>
- </symbol>
- <symbol id="file" viewBox="0 0 16 16">
- <path fill="currentColor"
- d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"/>
- </symbol>
- <symbol id="file-added" viewBox="0 0 16 16">
- <path fill="currentColor"
- d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073Zm4.48 3.758a.75.75 0 0 1 .755.745l.01 1.497h1.497a.75.75 0 0 1 0 1.5H9v1.507a.75.75 0 0 1-1.5 0V9.005l-1.502.01a.75.75 0 0 1-.01-1.5l1.507-.01-.01-1.492a.75.75 0 0 1 .745-.755Z"/>
- </symbol>
- <symbol id="file-modified" viewBox="0 0 16 16">
- <path fill="currentColor"
- d="M1 1.75C1 .784 1.784 0 2.75 0h7.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073ZM8 3.25a.75.75 0 0 1 .75.75v1.5h1.5a.75.75 0 0 1 0 1.5h-1.5v1.5a.75.75 0 0 1-1.5 0V7h-1.5a.75.75 0 0 1 0-1.5h1.5V4A.75.75 0 0 1 8 3.25Zm-3 8a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Z"/>
- </symbol>
- <symbol id="file-deleted" viewBox="0 0 16 16">
- <path fill="currentColor"
- d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073Zm4.5 6h2.242a.75.75 0 0 1 0 1.5h-2.24l-2.254.015a.75.75 0 0 1-.01-1.5Z"/>
- </symbol>
- <symbol id="file-renamed" viewBox="0 0 16 16">
- <path fill="currentColor"
- d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-3.5a.75.75 0 0 1 0-1.5h3.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073H3.75a.25.25 0 0 0-.25.25v6.5a.75.75 0 0 1-1.5 0v-6.5Z"/>
- <path fill="currentColor"
- d="m5.427 15.573 3.146-3.146a.25.25 0 0 0 0-.354L5.427 8.927A.25.25 0 0 0 5 9.104V11.5H.75a.75.75 0 0 0 0 1.5H5v2.396c0 .223.27.335.427.177Z"/>
- </symbol>
- <symbol id="arrow-top" viewBox="0 0 16 16">
- <path fill="currentColor"
- d="M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z"></path>
- </symbol>
- <symbol id="commit" viewBox="0 0 16 16">
- <path fill="currentColor"
- d="M11.93 8.5a4.002 4.002 0 0 1-7.86 0H.75a.75.75 0 0 1 0-1.5h3.32a4.002 4.002 0 0 1 7.86 0h3.32a.75.75 0 0 1 0 1.5Zm-1.43-.75a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z"></path>
- </symbol>
- <symbol id="branch" viewBox="0 0 16 16">
- <path fill="currentColor"
- d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path>
- </symbol>
- <symbol id="tag" viewBox="0 0 16 16">
- <path fill="currentColor"
- d="M1 7.775V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.752 1.752 0 0 1 1 7.775Zm1.5 0c0 .066.026.13.073.177l6.25 6.25a.25.25 0 0 0 .354 0l5.025-5.025a.25.25 0 0 0 0-.354l-6.25-6.25a.25.25 0 0 0-.177-.073H2.75a.25.25 0 0 0-.25.25ZM6 5a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"></path>
- </symbol>
- <symbol id="code" viewBox="0 0 16 16">
- <path fill="currentColor"
- d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path>
- </symbol>
- </svg>
+<svg style="display: none" aria-hidden="true" focusable="false">
+ <symbol id="dir" viewBox="0 0 16 16">
+ <path fill="currentColor" d="M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z"/>
+ </symbol>
+ <symbol id="file" viewBox="0 0 16 16">
+ <path fill="currentColor" d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"/>
+ </symbol>
+ <symbol id="file-added" viewBox="0 0 16 16">
+ <path fill="currentColor" d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073Zm4.48 3.758a.75.75 0 0 1 .755.745l.01 1.497h1.497a.75.75 0 0 1 0 1.5H9v1.507a.75.75 0 0 1-1.5 0V9.005l-1.502.01a.75.75 0 0 1-.01-1.5l1.507-.01-.01-1.492a.75.75 0 0 1 .745-.755Z"/>
+ </symbol>
+ <symbol id="file-modified" viewBox="0 0 16 16">
+ <path fill="currentColor" d="M1 1.75C1 .784 1.784 0 2.75 0h7.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073ZM8 3.25a.75.75 0 0 1 .75.75v1.5h1.5a.75.75 0 0 1 0 1.5h-1.5v1.5a.75.75 0 0 1-1.5 0V7h-1.5a.75.75 0 0 1 0-1.5h1.5V4A.75.75 0 0 1 8 3.25Zm-3 8a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Z"/>
+ </symbol>
+ <symbol id="file-deleted" viewBox="0 0 16 16">
+ <path fill="currentColor" d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073Zm4.5 6h2.242a.75.75 0 0 1 0 1.5h-2.24l-2.254.015a.75.75 0 0 1-.01-1.5Z"/>
+ </symbol>
+ <symbol id="file-renamed" viewBox="0 0 16 16">
+ <path fill="currentColor" d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-3.5a.75.75 0 0 1 0-1.5h3.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073H3.75a.25.25 0 0 0-.25.25v6.5a.75.75 0 0 1-1.5 0v-6.5Z"/>
+ <path fill="currentColor" d="m5.427 15.573 3.146-3.146a.25.25 0 0 0 0-.354L5.427 8.927A.25.25 0 0 0 5 9.104V11.5H.75a.75.75 0 0 0 0 1.5H5v2.396c0 .223.27.335.427.177Z"/>
+ </symbol>
+ <symbol id="arrow-top" viewBox="0 0 16 16">
+ <path fill="currentColor" d="M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z"></path>
+ </symbol>
+ <symbol id="commit" viewBox="0 0 16 16">
+ <path fill="currentColor" d="M11.93 8.5a4.002 4.002 0 0 1-7.86 0H.75a.75.75 0 0 1 0-1.5h3.32a4.002 4.002 0 0 1 7.86 0h3.32a.75.75 0 0 1 0 1.5Zm-1.43-.75a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z"></path>
+ </symbol>
+ <symbol id="branch" viewBox="0 0 16 16">
+ <path fill="currentColor" d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path>
+ </symbol>
+ <symbol id="tag" viewBox="0 0 16 16">
+ <path fill="currentColor" d="M1 7.775V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.752 1.752 0 0 1 1 7.775Zm1.5 0c0 .066.026.13.073.177l6.25 6.25a.25.25 0 0 0 .354 0l5.025-5.025a.25.25 0 0 0 0-.354l-6.25-6.25a.25.25 0 0 0-.177-.073H2.75a.25.25 0 0 0-.25.25ZM6 5a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"></path>
+ </symbol>
+ <symbol id="code" viewBox="0 0 16 16">
+ <path fill="currentColor" d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path>
+ </symbol>
+</svg>
{{ end }}
internal/templates/templates.go
@@ -23,6 +23,9 @@ var funcs = FuncMap{
},
}
+//go:embed css/layout.css
+var LayoutCSS string
+
//go:embed css/markdown_light.css
var CSSMarkdownLight string
@@ -62,12 +65,13 @@ var commitContent string
var CommitTemplate = Must(Must(layout.Clone()).Parse(commitContent))
type LayoutParams struct {
- Title string
- Name string
- CSSMarkdown CSS
- RootHref string
- CurrentRefDir string
- Selected string
+ Title string
+ Name string
+ RootHref string
+ CurrentRefDir string
+ Selected string
+ NeedsMarkdownCSS bool
+ NeedsSyntaxCSS bool
}
type HeaderParams struct {
@@ -85,7 +89,6 @@ type Breadcrumb struct {
type BlobParams struct {
LayoutParams
HeaderParams
- CSS CSS
Blob git.Blob
IsImage bool
IsBinary bool
@@ -154,7 +157,6 @@ type CommitsListParams struct {
type CommitParams struct {
LayoutParams
Commit git.Commit
- DiffCSS CSS
FileTree []*FileTree
FileViews []FileView
}