diff --git a/Makefile b/Makefile index 012a397..6e46424 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ install: build_frontend: @echo "Building frontend assets..." npx vite build + EMBED=1 npx postcss 'public/assets/embed-*.css' -c postcss.config.js --replace # until we can .nest { @tailwind } in Sass build_backend: @echo "Building Opengist binary..." diff --git a/internal/db/gist.go b/internal/db/gist.go index 0e3168a..120ce51 100644 --- a/internal/db/gist.go +++ b/internal/db/gist.go @@ -340,7 +340,7 @@ func (gist *Gist) File(revision string, filename string, truncate bool) (*git.Fi return nil, nil } - var size int64 + var size uint64 size, err = git.GetFileSize(gist.User.Username, gist.Uuid, revision, filename) if err != nil { @@ -349,7 +349,8 @@ func (gist *Gist) File(revision string, filename string, truncate bool) (*git.Fi return &git.File{ Filename: filename, - Size: humanize.IBytes(uint64(size)), + Size: size, + HumanSize: humanize.IBytes(size), Content: content, Truncated: truncated, }, err @@ -426,6 +427,19 @@ func (gist *Gist) UpdatePreviewAndCount() error { return gist.Update() } +func (gist *Gist) VisibilityStr() string { + switch gist.Private { + case PublicVisibility: + return "public" + case UnlistedVisibility: + return "unlisted" + case PrivateVisibility: + return "private" + default: + return "" + } +} + // -- DTO -- // type GistDTO struct { diff --git a/internal/git/commands.go b/internal/git/commands.go index bee20d1..952370e 100644 --- a/internal/git/commands.go +++ b/internal/git/commands.go @@ -149,7 +149,7 @@ func GetFileContent(user string, gist string, revision string, filename string, return content, truncated, nil } -func GetFileSize(user string, gist string, revision string, filename string) (int64, error) { +func GetFileSize(user string, gist string, revision string, filename string) (uint64, error) { repositoryPath := RepositoryPath(user, gist) cmd := exec.Command( @@ -165,7 +165,7 @@ func GetFileSize(user string, gist string, revision string, filename string) (in return 0, err } - return strconv.ParseInt(strings.TrimSuffix(string(stdout), "\n"), 10, 64) + return strconv.ParseUint(strings.TrimSuffix(string(stdout), "\n"), 10, 64) } func GetLog(user string, gist string, skip int) ([]*Commit, error) { diff --git a/internal/git/output_parser.go b/internal/git/output_parser.go index 9012631..f6a501a 100644 --- a/internal/git/output_parser.go +++ b/internal/git/output_parser.go @@ -11,13 +11,14 @@ import ( ) type File struct { - Filename string - Size string - OldFilename string - Content string - Truncated bool - IsCreated bool - IsDeleted bool + Filename string `json:"filename"` + Size uint64 `json:"size"` + HumanSize string `json:"human_size"` + OldFilename string `json:"-"` + Content string `json:"content"` + Truncated bool `json:"truncated"` + IsCreated bool `json:"-"` + IsDeleted bool `json:"-"` } type CsvFile struct { diff --git a/internal/i18n/locales/cs-CZ.yml b/internal/i18n/locales/cs-CZ.yml index dc7e838..a2fcffa 100644 --- a/internal/i18n/locales/cs-CZ.yml +++ b/internal/i18n/locales/cs-CZ.yml @@ -17,8 +17,8 @@ gist.header.clone-http: Klonovat pomocí %s gist.header.clone-http-help: Klonovat s pomocí Git pomocí základní autentizace HTTP. gist.header.clone-ssh: Klonovat pomocí SSH gist.header.clone-ssh-help: Klonovat s pomocí Git pomocí klíče SSH. -gist.header.share: Sdílet -gist.header.share-help: Zkopírovat sdílitelný odkaz na tento gist. +gist.header.embed: +gist.header.embed-help: gist.header.download-zip: Stáhnout ZIP gist.raw: Raw diff --git a/internal/i18n/locales/en-US.yml b/internal/i18n/locales/en-US.yml index c9157b9..012d161 100644 --- a/internal/i18n/locales/en-US.yml +++ b/internal/i18n/locales/en-US.yml @@ -17,8 +17,8 @@ gist.header.clone-http: Clone via %s gist.header.clone-http-help: Clone with Git using HTTP basic authentication. gist.header.clone-ssh: Clone via SSH gist.header.clone-ssh-help: Clone with Git using an SSH key. -gist.header.share: Share -gist.header.share-help: Copy shareable link for this gist. +gist.header.embed: Embed +gist.header.embed-help: Embed this gist to your website. gist.header.download-zip: Download ZIP gist.raw: Raw diff --git a/internal/i18n/locales/es-ES.yml b/internal/i18n/locales/es-ES.yml index f1542b0..89563e5 100644 --- a/internal/i18n/locales/es-ES.yml +++ b/internal/i18n/locales/es-ES.yml @@ -17,8 +17,8 @@ gist.header.clone-http: Clonar via %s gist.header.clone-http-help: Clonar con Git usando autenticación básica HTTP. gist.header.clone-ssh: Clonar via SSH gist.header.clone-ssh-help: Clonar con Git usando una clave SSH. -gist.header.share: Compartir -gist.header.share-help: Copiar enlace para compartir este gist. +gist.header.embed: +gist.header.embed-help: gist.header.download-zip: Descargar ZIP gist.raw: Sin formato diff --git a/internal/i18n/locales/fr-FR.yml b/internal/i18n/locales/fr-FR.yml index 59bc4a1..38b2cc8 100644 --- a/internal/i18n/locales/fr-FR.yml +++ b/internal/i18n/locales/fr-FR.yml @@ -17,8 +17,8 @@ gist.header.clone-http: Cloner via %s gist.header.clone-http-help: Cloner avec Git en utilisant l'authentification HTTP basic. gist.header.clone-ssh: Cloner via SSH gist.header.clone-ssh-help: Cloner avec Git en utilisant une clé SSH. -gist.header.share: Partager -gist.header.share-help: Copier le lien partageable de ce gist. +gist.header.embed: +gist.header.embed-help: gist.header.download-zip: Télécharger en ZIP gist.raw: Brut diff --git a/internal/i18n/locales/hu-HU.yml b/internal/i18n/locales/hu-HU.yml index 637ade5..e5710cd 100644 --- a/internal/i18n/locales/hu-HU.yml +++ b/internal/i18n/locales/hu-HU.yml @@ -17,8 +17,8 @@ gist.header.clone-http: "Clone-ozás ezzel: %s" gist.header.clone-http-help: Clone-ozás Git HTTP basic hitelesítéssel. gist.header.clone-ssh: Clone-ozás SSH-n keresztül gist.header.clone-ssh-help: Clone-ozás SSH kulccsal -gist.header.share: Megosztás -gist.header.share-help: Másold ki ennek a gistnek a megosztható linkjét +gist.header.embed: +gist.header.embed-help: gist.header.download-zip: ZIP archívum letöltése gist.raw: Eredeti diff --git a/internal/i18n/locales/ru-RU.yml b/internal/i18n/locales/ru-RU.yml index 06ee409..4a8cd36 100644 --- a/internal/i18n/locales/ru-RU.yml +++ b/internal/i18n/locales/ru-RU.yml @@ -17,8 +17,8 @@ gist.header.clone-http: Клонировать с помощью %s gist.header.clone-http-help: Клонировать с помощью Git используя аутентификацию HTTP. gist.header.clone-ssh: Клонировать c помощью SSH gist.header.clone-ssh-help: Клонировать c помощью Git используя ключ SSH. -gist.header.share: Поделиться -gist.header.share-help: Скопировать ссылку на фрагмент. +gist.header.embed: +gist.header.embed-help: gist.header.download-zip: Скачать ZIP-архив gist.raw: Исходник diff --git a/internal/i18n/locales/zh-CN.yml b/internal/i18n/locales/zh-CN.yml index 0680b87..079a1fd 100644 --- a/internal/i18n/locales/zh-CN.yml +++ b/internal/i18n/locales/zh-CN.yml @@ -17,8 +17,8 @@ gist.header.clone-http: 通过 %s 克隆 gist.header.clone-http-help: 使用 Git 通过 HTTP 基础认证克隆。 gist.header.clone-ssh: 通过 SSH 克隆 gist.header.clone-ssh-help: 使用 Git 通过 SSH 密钥克隆。 -gist.header.share: 分享 -gist.header.share-help: 为此 Gist 复制可供分享的链接。 +gist.header.embed: +gist.header.embed-help: gist.header.download-zip: 下载 ZIP gist.raw: 原始文件 diff --git a/internal/i18n/locales/zh-TW.yml b/internal/i18n/locales/zh-TW.yml index 6d9a96f..fd119b1 100644 --- a/internal/i18n/locales/zh-TW.yml +++ b/internal/i18n/locales/zh-TW.yml @@ -17,8 +17,8 @@ gist.header.clone-http: 透過 %s 複製 gist.header.clone-http-help: 使用 HTTP 基本認證透過 Git 複製。 gist.header.clone-ssh: 透過 SSH 複製 gist.header.clone-ssh-help: 使用 SSH 金鑰透過 Git 複製。 -gist.header.share: 分享 -gist.header.share-help: 複製這個 Gist 的連結。 +gist.header.embed: +gist.header.embed-help: gist.header.download-zip: 下載 ZIP gist.raw: 原始檔案 diff --git a/internal/render/highlight.go b/internal/render/highlight.go index d70326d..01d0a6b 100644 --- a/internal/render/highlight.go +++ b/internal/render/highlight.go @@ -8,15 +8,16 @@ import ( "github.com/alecthomas/chroma/v2/formatters/html" "github.com/alecthomas/chroma/v2/lexers" "github.com/alecthomas/chroma/v2/styles" + "github.com/rs/zerolog/log" "github.com/thomiceli/opengist/internal/db" "github.com/thomiceli/opengist/internal/git" ) type RenderedFile struct { *git.File - Type string - Lines []string - HTML string + Type string `json:"type"` + Lines []string `json:"-"` + HTML string `json:"-"` } type RenderedGist struct { @@ -66,6 +67,19 @@ func HighlightFile(file *git.File) (RenderedFile, error) { return rendered, err } +func HighlightFiles(files []*git.File) ([]RenderedFile, error) { + renderedFiles := make([]RenderedFile, 0, len(files)) + for _, file := range files { + rendered, err := HighlightFile(file) + if err != nil { + log.Warn().Err(err).Msg("Error rendering gist preview for " + file.Filename) + } + renderedFiles = append(renderedFiles, rendered) + } + + return renderedFiles, nil +} + func HighlightGistPreview(gist *db.Gist) (RenderedGist, error) { rendered := RenderedGist{ Gist: gist, diff --git a/internal/web/gist.go b/internal/web/gist.go index 2b94ccc..e633f5f 100644 --- a/internal/web/gist.go +++ b/internal/web/gist.go @@ -2,15 +2,19 @@ package web import ( "archive/zip" + "bufio" "bytes" "errors" + "fmt" "github.com/rs/zerolog/log" "github.com/thomiceli/opengist/internal/render" "html/template" "net/url" + "path/filepath" "regexp" "strconv" "strings" + "time" "github.com/google/uuid" "github.com/labstack/echo/v4" @@ -26,7 +30,17 @@ func gistInit(next echo.HandlerFunc) echo.HandlerFunc { userName := ctx.Param("user") gistName := ctx.Param("gistname") - gistName = strings.TrimSuffix(gistName, ".git") + switch filepath.Ext(gistName) { + case ".js": + setData(ctx, "gistpage", "js") + gistName = strings.TrimSuffix(gistName, ".js") + case ".json": + setData(ctx, "gistpage", "json") + gistName = strings.TrimSuffix(gistName, ".json") + case ".git": + setData(ctx, "gistpage", "git") + gistName = strings.TrimSuffix(gistName, ".git") + } gist, err := db.GetGist(userName, gistName) if err != nil { @@ -71,12 +85,15 @@ func gistInit(next echo.HandlerFunc) echo.HandlerFunc { baseHttpUrl = httpProtocol + "://" + ctx.Request().Host } + setData(ctx, "baseHttpUrl", baseHttpUrl) + if config.C.HttpGit { setData(ctx, "httpCloneUrl", baseHttpUrl+"/"+userName+"/"+gistName+".git") } setData(ctx, "httpCopyUrl", baseHttpUrl+"/"+userName+"/"+gistName) setData(ctx, "currentUrl", template.URL(ctx.Request().URL.Path)) + setData(ctx, "embedScript", fmt.Sprintf(``, baseHttpUrl+"/"+userName+"/"+gistName+".js")) nbCommits, err := gist.NbCommits() if err != nil { @@ -256,6 +273,12 @@ func allGists(ctx echo.Context) error { } func gistIndex(ctx echo.Context) error { + if getData(ctx, "gistpage") == "js" { + return gistJs(ctx) + } else if getData(ctx, "gistpage") == "json" { + return gistJson(ctx) + } + gist := getData(ctx, "gist").(*db.Gist) revision := ctx.Param("revision") @@ -272,13 +295,9 @@ func gistIndex(ctx echo.Context) error { return notFound("Revision not found") } - renderedFiles := make([]render.RenderedFile, 0, len(files)) - for _, file := range files { - rendered, err := render.HighlightFile(file) - if err != nil { - log.Warn().Err(err).Msg("Error rendering gist preview for " + gist.Uuid + " - " + gist.PreviewFilename) - } - renderedFiles = append(renderedFiles, rendered) + renderedFiles, err := render.HighlightFiles(files) + if err != nil { + return errorRes(500, "Error rendering files", err) } setData(ctx, "page", "code") @@ -289,6 +308,83 @@ func gistIndex(ctx echo.Context) error { return html(ctx, "gist.html") } +func gistJson(ctx echo.Context) error { + gist := getData(ctx, "gist").(*db.Gist) + files, err := gist.Files("HEAD") + if err != nil { + return errorRes(500, "Error fetching files", err) + } + + renderedFiles, err := render.HighlightFiles(files) + if err != nil { + return errorRes(500, "Error rendering files", err) + } + + setData(ctx, "files", renderedFiles) + + htmlbuf := bytes.Buffer{} + w := bufio.NewWriter(&htmlbuf) + if err = ctx.Echo().Renderer.Render(w, "gist_embed.html", dataMap(ctx), ctx); err != nil { + return err + } + _ = w.Flush() + + jsUrl, err := url.JoinPath(getData(ctx, "baseHttpUrl").(string), gist.User.Username, gist.Uuid+".js") + if err != nil { + return errorRes(500, "Error joining url", err) + } + + return ctx.JSON(200, map[string]interface{}{ + "owner": gist.User.Username, + "id": gist.Uuid, + "title": gist.Title, + "description": gist.Description, + "created_at": time.Unix(gist.CreatedAt, 0).Format(time.RFC3339), + "visibility": gist.VisibilityStr(), + "files": renderedFiles, + "embed": map[string]string{ + "html": htmlbuf.String(), + "css": getData(ctx, "baseHttpUrl").(string) + asset("embed.css"), + "js": jsUrl, + "js_dark": jsUrl + "?dark", + }, + }) +} + +func gistJs(ctx echo.Context) error { + if _, exists := ctx.QueryParams()["dark"]; exists { + setData(ctx, "dark", "dark") + } + + gist := getData(ctx, "gist").(*db.Gist) + files, err := gist.Files("HEAD") + if err != nil { + return errorRes(500, "Error fetching files", err) + } + + renderedFiles, err := render.HighlightFiles(files) + if err != nil { + return errorRes(500, "Error rendering files", err) + } + + setData(ctx, "files", renderedFiles) + + htmlbuf := bytes.Buffer{} + w := bufio.NewWriter(&htmlbuf) + if err = ctx.Echo().Renderer.Render(w, "gist_embed.html", dataMap(ctx), ctx); err != nil { + return err + } + _ = w.Flush() + + js := `document.write('') +document.write('%s') +` + js = fmt.Sprintf(js, getData(ctx, "baseHttpUrl").(string)+asset("embed.css"), + strings.Replace(htmlbuf.String(), "\n", `\n`, -1)) + ctx.Response().Header().Set("Content-Type", "application/javascript") + return plainText(ctx, 200, js) +} + func revisions(ctx echo.Context) error { gist := getData(ctx, "gist").(*db.Gist) userName := gist.User.Username diff --git a/internal/web/server.go b/internal/web/server.go index cb651b2..e9a3407 100644 --- a/internal/web/server.go +++ b/internal/web/server.go @@ -86,12 +86,7 @@ var ( return defaultAvatar() }, - "asset": func(file string) string { - if dev { - return "http://localhost:16157/" + file - } - return config.C.ExternalUrl + "/" + manifestEntries[file].File - }, + "asset": asset, "dev": func() bool { return dev }, @@ -482,3 +477,10 @@ func defaultAvatar() string { } return config.C.ExternalUrl + "/" + manifestEntries["default.png"].File } + +func asset(file string) string { + if dev { + return "http://localhost:16157/" + file + } + return config.C.ExternalUrl + "/" + manifestEntries[file].File +} diff --git a/internal/web/util.go b/internal/web/util.go index 4fbcfed..5f880dc 100644 --- a/internal/web/util.go +++ b/internal/web/util.go @@ -36,6 +36,10 @@ func getData(ctx echo.Context, key string) any { return data[key] } +func dataMap(ctx echo.Context) echo.Map { + return ctx.Request().Context().Value(dataKey).(echo.Map) +} + func html(ctx echo.Context, template string) error { return htmlWithCode(ctx, 200, template) } diff --git a/package-lock.json b/package-lock.json index e27c2a5..25dfaef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,9 +23,11 @@ "github-markdown-css": "^5.5.0", "nodemon": "^2.0.22", "postcss": "^8.4.13", + "postcss-cli": "^11.0.0", "postcss-cssnext": "^3.1.1", "postcss-import": "^15.1.0", "postcss-loader": "^7.1.0", + "postcss-selector-namespace": "^3.0.1", "sass": "^1.62.1", "sugarss": "^4.0.1", "tailwindcss": "^3.2.7", @@ -665,6 +667,18 @@ "node": ">= 8" } }, + "node_modules/@sindresorhus/merge-streams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", + "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@tailwindcss/forms": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", @@ -978,6 +992,15 @@ "ajv": "^6.9.1" } }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -1251,6 +1274,20 @@ "node": ">=6.0" } }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", @@ -1563,6 +1600,15 @@ "ms": "^2.1.1" } }, + "node_modules/dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -1636,6 +1682,12 @@ "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", "dev": true }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -1858,6 +1910,20 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1887,6 +1953,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stdin": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/github-markdown-css": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/github-markdown-css/-/github-markdown-css-5.5.0.tgz", @@ -1938,12 +2025,43 @@ "dev": true, "peer": true }, + "node_modules/globby": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", + "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^1.0.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/has-flag": { "version": "3.0.0", @@ -1966,6 +2084,15 @@ "node": ">= 0.4" } }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", @@ -2055,6 +2182,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2166,6 +2302,18 @@ "dev": true, "peer": true }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -2782,6 +2930,88 @@ "postcss": "^8.2.2" } }, + "node_modules/postcss-cli": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-11.0.0.tgz", + "integrity": "sha512-xMITAI7M0u1yolVcXJ9XTZiO9aO49mcoKQy6pCDFdMh9kGqhzLVpWxeD/32M/QBmkhcGypZFFOLNLmIW4Pg4RA==", + "dev": true, + "dependencies": { + "chokidar": "^3.3.0", + "dependency-graph": "^0.11.0", + "fs-extra": "^11.0.0", + "get-stdin": "^9.0.0", + "globby": "^14.0.0", + "picocolors": "^1.0.0", + "postcss-load-config": "^5.0.0", + "postcss-reporter": "^7.0.0", + "pretty-hrtime": "^1.0.3", + "read-cache": "^1.0.0", + "slash": "^5.0.0", + "yargs": "^17.0.0" + }, + "bin": { + "postcss": "index.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-cli/node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/postcss-cli/node_modules/postcss-load-config": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-5.0.2.tgz", + "integrity": "sha512-Q8QR3FYbqOKa0bnC1UQ2bFq9/ulHX5Bi34muzitMr8aDtUelO5xKeJEYC/5smE0jNE9zdB/NBnOwXKexELbRlw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + } + } + }, + "node_modules/postcss-cli/node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/postcss-color-function": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/postcss-color-function/-/postcss-color-function-4.1.0.tgz", @@ -4064,6 +4294,26 @@ "node": ">=4.0.0" } }, + "node_modules/postcss-reporter": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.5.tgz", + "integrity": "sha512-glWg7VZBilooZGOFPhN9msJ3FQs19Hie7l5a/eE6WglzYqVeH3ong3ShFcp9kDWJT1g2Y/wd59cocf9XxBtkWA==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "thenby": "^1.3.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, "node_modules/postcss-selector-matches": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-3.0.1.tgz", @@ -4094,6 +4344,41 @@ "node": ">=4.0.0" } }, + "node_modules/postcss-selector-namespace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-namespace/-/postcss-selector-namespace-3.0.1.tgz", + "integrity": "sha512-o7poXaazoGCBOK2JIRVsMQV6G0UV5qCJvYJ1t6vqRzOIpJRpsIXHZNc6VdPj9nuQ9D4Ov5LY3SupAP0xu4T/kQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/postcss-selector-namespace/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/postcss-selector-namespace/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, "node_modules/postcss-selector-not": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-3.0.1.tgz", @@ -4188,6 +4473,15 @@ "node": ">=4" } }, + "node_modules/pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", @@ -4287,6 +4581,15 @@ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", "dev": true }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -4492,6 +4795,18 @@ "semver": "bin/semver.js" } }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -4528,6 +4843,32 @@ "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", "dev": true }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/style-mod": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.0.tgz", @@ -4775,6 +5116,12 @@ "dev": true, "peer": true }, + "node_modules/thenby": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz", + "integrity": "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==", + "dev": true + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -4839,6 +5186,18 @@ "dev": true, "peer": true }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", @@ -4855,6 +5214,15 @@ "viewport-dimensions": "^0.2.0" } }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -5040,12 +5408,71 @@ "node": ">=10.13.0" } }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -5060,6 +5487,33 @@ "engines": { "node": ">= 6" } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } } } } diff --git a/package.json b/package.json index c42ec05..c95660b 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,11 @@ "github-markdown-css": "^5.5.0", "nodemon": "^2.0.22", "postcss": "^8.4.13", + "postcss-cli": "^11.0.0", "postcss-cssnext": "^3.1.1", "postcss-import": "^15.1.0", "postcss-loader": "^7.1.0", + "postcss-selector-namespace": "^3.0.1", "sass": "^1.62.1", "sugarss": "^4.0.1", "tailwindcss": "^3.2.7", diff --git a/postcss.config.js b/postcss.config.js index a751572..f9f24f4 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,7 +1,10 @@ module.exports = { plugins: { + 'postcss-import': {}, + 'tailwindcss/nesting': {}, tailwindcss: {}, autoprefixer: {}, + 'postcss-selector-namespace': {namespace() {return (process.env.EMBED) ? '.opengist-embed' : '';}}, cssnano: {}, }, } diff --git a/public/catppuccin-latte.css b/public/catppuccin-latte.css index 93bc24b..1ba478b 100644 --- a/public/catppuccin-latte.css +++ b/public/catppuccin-latte.css @@ -1,3 +1,4 @@ +.chroma:not(.markdown) { color: #4c4f69 } /* Error */ .chroma .err { color: #d20f39 } /* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit } /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } diff --git a/public/catppuccin-macchiato.css b/public/catppuccin-macchiato.css index cc4714b..953fa3a 100644 --- a/public/catppuccin-macchiato.css +++ b/public/catppuccin-macchiato.css @@ -1,3 +1,4 @@ +.chroma:not(.markdown) { color: #cad3f5 } /* Error */ .chroma .err { color: #f38ba8 } /* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit } /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } diff --git a/public/embed.scss b/public/embed.scss new file mode 100644 index 0000000..584beda --- /dev/null +++ b/public/embed.scss @@ -0,0 +1,112 @@ +@import "github-markdown-css/github-markdown-light"; +@import './catppuccin-latte'; + + +.dark { + @import "github-markdown-css/github-markdown-dark"; + @import './catppuccin-macchiato'; +} + +@tailwind base; +@tailwind components; +@tailwind utilities; + +@config "../tailwind-embed.config.js"; + +.html { + -webkit-text-size-adjust: 100%; + font-feature-settings: normal; + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji; + font-variation-settings: normal; + line-height: 1.5; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4 +} + +ol, ul { + list-style: revert; +} + +.code { + font-family: Menlo, Consolas, Liberation Mono, monospace; +} + +.code .line-num { + width: 4%; + text-align: right; +} + +.code td { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.code tbody { + line-height: 18.2px; +} + +.line-code { + @apply pl-2; + background: none !important; +} + +.line-num { + @apply cursor-pointer text-slate-600 dark:text-slate-400 hover:text-black dark:hover:text-white; +} + +table.csv-table { + @apply w-full whitespace-pre text-xs text-slate-300; +} + +table.csv-table thead { + text-align: left; +} + +table.csv-table thead tr { + @apply bg-slate-100 dark:bg-slate-800; +} + +table.csv-table tbody tr { + @apply bg-gray-500 dark:bg-gray-900; +} + +table.csv-table thead tr th { + @apply border py-2 px-1 border-slate-300 dark:border-slate-700; +} + +table.csv-table tbody td { + @apply border py-1.5 px-1 border-slate-200 dark:border-slate-800; +} + +dl.dl-config { + @apply grid grid-cols-3 text-sm; +} + +dl.dl-config dt { + @apply col-span-1 text-gray-700 dark:text-slate-300 font-bold; +} + +dl.dl-config dd { + @apply ml-1 col-span-2 break-words; +} + +.markdown-body { + @apply dark:bg-gray-900; +} + +.markdown-body pre { + @apply flex relative items-start p-0; +} + +.markdown-body .code-div { + @apply p-4 max-w-full overflow-x-auto; +} + +.markdown-body code { + @apply overflow-auto whitespace-pre; +} + +.chroma.preview.markdown code { + @apply p-4; +} diff --git a/public/embed.ts b/public/embed.ts new file mode 100644 index 0000000..d46794a --- /dev/null +++ b/public/embed.ts @@ -0,0 +1 @@ +import "./embed.scss" diff --git a/public/main.ts b/public/main.ts index b759ed8..b645c0b 100644 --- a/public/main.ts +++ b/public/main.ts @@ -1,4 +1,3 @@ -import './style.css'; import './style.scss'; import './favicon-32.png'; import './opengist.svg'; diff --git a/public/style.css b/public/style.css index 203c8d3..c0e3455 100644 --- a/public/style.css +++ b/public/style.css @@ -2,6 +2,8 @@ @tailwind components; @tailwind utilities; +@config "../tailwind.config.js"; + @layer base { ul, ol { list-style: revert; @@ -98,10 +100,6 @@ pre { max-height: 337px; } -.hljs { - color: #c9d1d9; -} - .line-code.selected { background-color: rgb(255, 247, 190) !important; box-shadow: inset 4px 0 0 rgb(255, 213, 65) !important; diff --git a/public/style.scss b/public/style.scss index ba2fcbb..9b68519 100644 --- a/public/style.scss +++ b/public/style.scss @@ -7,3 +7,5 @@ @import "github-markdown-css/github-markdown-dark"; @import './catppuccin-macchiato'; } + +@import "style.css"; diff --git a/tailwind-embed.config.js b/tailwind-embed.config.js new file mode 100644 index 0000000..be4c91d --- /dev/null +++ b/tailwind-embed.config.js @@ -0,0 +1,47 @@ +const colors = require('tailwindcss/colors') + +module.exports = { + content: [ + "./templates/pages/gist_embed.html", + ], + theme: { + colors: { + white: colors.white, + black: colors.black, + gray: { + 50: "#EEEFF1", + 100: "#DEDFE3", + 200: "#BABCC5", + 300: "#999CA8", + 400: "#75798A", + 500: "#585B68", + 600: "#464853", + 700: "#363840", + 800: "#232429", + 900: "#131316" + }, + primary: { + 50: '#d6e1ff', + 100: '#d1dfff', + 200: '#b9d2fe', + 300: '#84b1fb', + 400: '#74a4f6', + 500: '#588fee', + 600: '#3c79e2', + 700: '#356fc0', + 800: '#2d6195', + 900: '#2a5574', + 950: '#173040', + }, + + slate: colors.slate + }, + extend: { + borderWidth: { + '1': '1px', + } + }, + }, + plugins: [], + darkMode: 'class', +} diff --git a/templates/base/base_header.html b/templates/base/base_header.html index cab169c..4a571c6 100644 --- a/templates/base/base_header.html +++ b/templates/base/base_header.html @@ -30,7 +30,7 @@ {{ if dev }} - + {{ else }} diff --git a/templates/base/gist_header.html b/templates/base/gist_header.html index 2d8636a..e3996d4 100644 --- a/templates/base/gist_header.html +++ b/templates/base/gist_header.html @@ -128,13 +128,16 @@