diff --git a/config-dark.toml b/config-dark.toml new file mode 100644 index 0000000..f5fa13a --- /dev/null +++ b/config-dark.toml @@ -0,0 +1,569 @@ +############################################################################### +## +## Global, site-wide configuration settings +## +############################################################################### + +# A friendly name for the generated site. +# +# This is accessible in all templates. +#site_name = "" + +# The URL where this generated site is hosted. +# +# This is accessible in all templates. +#site_url = "" + +# A description of the generated site. +# +# This is accessible in all templates. +#site_description = "" + +# URL where the repositories can be cloned from. +# +# Use the "%REPO%" variable to substitute the repository name. +# +# This can also be set per-repository. +#clone_url = "https://github.com/your_user/%REPO%" + +# Which branch to use for generating history. +# +# Itsy-Gitsy currently only supports traversing the history of a single branch, +# which is the one named here. Common options are "master" and "main". +# Defaults to "master" if not specified. +# +# Note that this probably should not contain any remote prefix, like "origin/", +# though it may. Also note that the "default branch" is only a concept for +# remote repositories; local repositories do not have the concept, hence this +# must be explicitly specified. +# +# This can also be set per-repository. +#branch = "master" + +# List of directories, each of which contains Git repositories to +# index. +# +# For each directory listed here, Itsy-Gitsy imports all of the +# immediate subdirectories as repositories. Each repository is +# imported with its name set to the name of the subdirectory it is in. +# +# Every repository imported in this way has the global setting from +# this file applied. It is not possible to apply per-repository +# settings for bulk-imported repositories. Repositories that require +# specific configuration can be explicitly specified later in this +# file. +#recursive_repo_dirs = [] + +# List of files potentially containing repository documentation. +# +# Each repository root is searched for these files, in order. The +# first matching file is provided to the templates as a `readme` +# variable, with the file contents. Markdown files are rendered as +# HTML if the feature is enabled. +# +# This can also be set per-repository. +readme_files = ["README.md", "README"] + +# List of files to copy to the site's `global_assets` directory. +# +# The files in this list are copied unmodified, and with the same name, to the +# configured `global_asset` output directory. Use for including global, +# site-wide resources, such as stylesheets, images, and icons. +# +# Currently does NOT support globbing or directories. Each file must be listed +# individually. +# +# Use "%TEMPLATE%" variable to substitute the path to the current +# template folder. +# +# Use "%REPO%" variable to substitute the path to the currently +# processing repository (only sensible when used as a per-repo +# configuration). +# +# This can also be set per-repository, in which case the `repo_assets` output +# directory is used. +asset_files = ["%TEMPLATE%/style.css"] + +# Whether to split history output into pages +# +# If non-zero and a `history` template is specified, the history +# output is generated several times, each with the `history` variable +# in the template engine containing the next `paginate_history` number +# of entries. +# +# A `page` variable is available in the template, which contains the +# current, next, previous, and total number of pages. +# +# Use the "%PAGE%" variable in the `history` output variable to +# substitute the page number into the produced filename. +paginate_history = 50 + +# Whether to split branches output into pages +# +# If non-zero and a `branches` template is specified, the branches +# output is generated several times, each with the `branches` variable +# in the template engine containing the next `paginate_branches` +# number of entries. +# +# A `page` variable is available in the template, which contains the +# current, next, previous, and total number of pages. +# +# Use the "%PAGE%" variable in the `branches` output variable to +# substitute the page number into the produced filename. +paginate_branches = 50 + +# Whether to split tags output into pages +# +# If non-zero and a `tags` template is specified, the tags output is +# generated several times, each with the `tags` variable in the +# template engine containing the next `paginate_tags` number of +# entries. +# +# A `page` variable is available in the template, which contains the +# current, next, previous, and total number of pages. +# +# Use the "%PAGE%" variable in the `tags` output variable to +# substitute the page number into the produced filename. +paginate_tags = 50 + +# Whether to render Markdown files in repos into HTML. +# +# Rendering Markdown can make site generation take more time. It has potential +# security implications, as user-generated input (files in the repo) are +# formatted into HTML and served unescaped. Use with caution. +# +# This can also be set per-repository. +render_markdown = true + +# Whether render files with syntax highlighting, as HTML. +# +# Applying syntax highlighting is CPU-intensive, and greatly increases site +# generation time. It has potential security implications, as user-generated +# input (files in the repo) are formatted into HTML and served unescaped. Use +# with caution. +# +# This can also be set per-repository. +syntax_highlight = true + +# Which theme to use for syntax highlighting colors. +# +# The default themes from Syntect are available, namely: +# +# - `base16-ocean.light` +# - `base16-ocean.dark` +# - `base16-eighties.dark` +# - `base16-mocha.dark` +# - `InspiredGitHub` +# - `Solarized (dark)` +# - `Solarized (light)` +# +syntax_highlight_theme = "base16-ocean.dark" + +# Limits maximum number of history items (i.e. git log) to parse. +# +# After the limit is reached, no more history items will be processed or stored +# in memory, and no more commits will be output to disk. For large +# repositories, this can increase processing speed and decrease memory and disk +# usage. +# +# This can also be set per-repository. +#limit_history = 500 + +# Limits maximum number of commits to output. +# +# When the limit is reached, no more commits are written to disk. Similar to +# `limit_history`, but the entire git log is still read into RAM and provided +# to the templates. +# +# This can also be set per-repository. +#limit_commits = 500 + +# Limits maximum number of branches to parse. +# +# When the limit is reached, no more branches are parsed in memory or provided +# to the `branch` template. +# +# Since branch order is unsorted and non-deterministic, the most sensible +# values for this are very large, or 0 (to disable branches). +# +# This can also be set per-repository. +#limit_branches = 500 + +# Limits maximum number of tags to parse. +# +# When the limit is reached, no more tags are parsed in memory or provided to +# the `tag` template. +# +# Since tag order is unsorted and non-deterministic, the most sensible values +# for this are very large, or 0 (to disable tags). +# +# This can also be set per-repository. +#limit_tags = 500 + +# Limits directory depth to traverse when parsing files. +# +# Limits the number of directories traversed when enumerating files in the +# `all_files` entry, which is passed as part of the repository to each +# template. This can help reduce RAM usage, and potentially disk usage, for +# repositories with a very large number of files or directories. +# +# Set to 0 to disable both `all_files` and `root_files`, i.e. do not parse any +# file listing. If set to 1 or greater, only applies to `all_files`. +# +# This can also be set per-repository. +#limit_tree_depth = 20 + +# Limits size of files in repo with content previews. +# +# Only non-binary files smaller than this limit will have their contents +# provided to the `file` template. Large files are still processed, but do not +# include the text contents. +# +# This can also be set per-repository. +#limit_file_size = 2097152 + +# Limits size of a single produced repository. +# +# Limits the size of a generated repository preview. This is a low-precision +# limit, terminating generation wherever it happens to be, and may lead to many +# dead links in the final output. +# +# This limit is not strict: generation is terminated after the first file that +# exceeds this limit. The output size might somewhat overflow this limit. +# Also, static repository assets specified in this configuration are NOT +# included in this limit. +# +# This is intended merely as a safety mechanism to prevent massive run-away +# disk usage. +# +# This can also be set per-repository. +#limit_repo_size = 52428800 + +# Limits total size of all output. +# +# Limits the size of the total run: the sum of all repositories. This is a +# low-precision limit, terminating generation wherever it happens to be, and +# may lead to many dead links or entirely missing repositories. +# +# This limit is not strict: generation is terminated after the first file that +# exceeds this limit. The output size might somewhat overflow this limit. +# Also, static repository assets specified in this configuration are NOT +# included in this limit. +# +# This is intended merely as a safety mechanism to prevent massive run-away +# disk usage. +# +# This can also be set per-repository. +#limit_total_size = 524288000 + +# Limits number of contextual elements available to templates. +# +# By default, if this limit is not set, all repository elements +# (history, branches, tags, commits) are provided in full to all +# repository templates, so every page can see all repo metadata. +# +# For parallel output generation, one copy of the repo metadata is +# made per CPU core. All of this must be loaded into RAM, which means +# large repositories can be very slow to process, or exhaust memory. +# +# This setting limits all elements, *except* those directly relevant +# to the page being rendered. For example, all elements except +# `branches` are limited in the `branches` template, all elements +# except `tags` are limited in the `tags` template, and so on. +# +# This is critically important for very large repositories, to prevent +# them from consuming all memory and destroying all things. +# +# This can also be set per-repository. +#limit_context = 200 + +# Limit number of diffs and diff statistics. +# +# By default, if this limit is not set, every history item contains +# statistics (files changes, additions, and deletions), and every +# commit item contains a diff. These are all held in memory and +# passed to each repository template. +# +# While parsing history, and if this limit is reached, subsequent +# history and commit items will not have diffs and statistics +# included. +# +# This is critically important for very large repositories, to prevent +# them from consuming all memory and destroying all things. +# +# This can also be set per-repository. +#limit_diffs = 200 + + + +############################################################################### +## +## Subsection specifying which files to use as templates. +## +## The individual templates are relative to the `path` directory. Each +## template is a single file using the Tera template engine's format for text +## substitution. +## +## All except `path` are optional. If not specified, the associated outputs +## will not be generated. +## +############################################################################### +[gitsy_templates] + +# Path to a folder containing Tera templates. +# +# All files with a .html extension found under this directory, and its +# immediate children directories, are imported into the Tera template engine. +path = "templates/default_dark/" + +# Template responsible for the list of repositories. +# +# This template is evaluated with the list of all configured repositories. It +# is intended for providing an overview of the available repositories, but the +# full details of each repository are also included. +# +# This template executes one time. +repo_list = "repos.html" + +# Template responsible for summarizing a single repository. +# +# This template is evaluated with a single parsed repository, with all repo +# data (commits, branches, etc) available. +# +# This template executes one time per repository. +repo_summary = "summary.html" + +# Template responsible for displaying the commit history. +# +# This template is evaluated with the same data as `repo_summary`. If +# the `paginate_history` setting is non-zero, this may be called +# several times with the `history` template variable reduced to the +# requested page size, and with a `page` template variable provided to +# identify the current, previous, and next pages. +# +# This template executes at least one time per repository, or several +# times if paginated. +history = "history.html" + +# Template responsible for displaying a single commit. +# +# Called once per parsed commit, with both the whole repository and the current +# commit available to the template. +# +# This template executes many times. +commit = "commit.html" + +# Template responsible for displaying the repo branches. +# +# This template is evaluated with the same data as `repo_summary`. If +# the `paginate_branches` setting is non-zero, this may be called +# several times with the `branches` template variable reduced to the +# requested page size, and with a `page` template variable provided to +# identify the current, previous, and next pages. +# +# This template executes at least one time per repository, or several +# times if paginated. +branches = "branches.html" + +# Template responsible for displaying a single branch. +# +# Called once per parsed branch, with both the whole repository and the current +# branch available to the template. +# +# This template executes many times. +branch = "branch.html" + +# Template responsible for displaying the repo tags. +# +# This template is evaluated with the same data as `repo_summary`. If +# the `paginate_tags` setting is non-zero, this may be called several +# times with the `tags` template variable reduced to the requested +# page size, and with a `page` template variable provided to identify +# the current, previous, and next pages. +# +# This template executes at least one time per repository, or several +# times if paginated. +tags = "tags.html" + +# Template responsible for displaying a single tag. +# +# Called once per parsed tag, with both the whole repository and the current +# tag available to the template. +# +# This template executes many times. +tag = "tag.html" + +# Template responsible for displaying file tree. +# +# Called with the same variables as the `summary` page, this simply gives an +# alternative locate to list the files in the root of the repository. +# +# This template executes once per repository. +files = "files.html" + +# Template responsible for displaying a single file. +# +# Called once per parsed file, with both the whole repository and the current +# file available to the template. +# +# This template executes many times. +file = "file.html" + +# Template responsible for displaying a single directory. +# +# Called once per parsed directory, with both the whole repository and the +# current directory available to the template. +# +# This template executes many times. +dir = "dir.html" + +# Template responsible for displaying a site-wide error. +# +# Intended for 404 (page not found) errors. If used, you must configure your +# webserver to redirect HTTP errors to the generated error page. +# +# This template executes one time. +error = "404.html" + + + +############################################################################### +## +## Subsection specifying names of output files/directories. +## +## Each entry pairs with one of the entries in `gitsy_templates` above, +## specifying the directories and filenames for the rendered output, after the +## template engine has performed its substitutions. +## +## All outputs are relative to the `path` directory. +## +## There are currently two supported variables for paths: +## +## * "%REPO%" -- replaced with the name of the currently processing repository +## * "%ID%" -- replaced with the ID of the currently processing object +## * "%PAGE%" -- replaced with the current page number if output is paginated +## +## All except `path` are optional. If not specified, sensible defaults will be +## used. +## +############################################################################### +[gitsy_outputs] +path = "rendered/" +repo_list = "index.html" +repo_summary = "%REPO%/index.html" +history = "%REPO%/history%PAGE%.html" +commit = "%REPO%/commit/%ID%.html" +branches = "%REPO%/branches%PAGE%.html" +branch = "%REPO%/branch/%ID%.html" +tags = "%REPO%/tags%PAGE%.html" +tag = "%REPO%/tag/%ID%.html" +files = "%REPO%/files.html" +file = "%REPO%/file/%ID%.html" +syntax_css = "%REPO%/file/syntax.css" +dir = "%REPO%/dir/%ID%.html" +error = "404.html" + +# Output directory for files specified in global `asset_files`. +# +# Each input file is copied to this directory unmodified. +global_assets = "assets/" + +# Output directory for files specified in per-repo `asset_files`. +# +# Each input file is copied to this directory unmodified. +repo_assets = "%REPO%/assets/" + +# Directory to clone remote repositories into. +# +# Remote repositories must be cloned locally to parse. They are cloned into +# subdirectories of `cloned_repos`, as bare git repos. These are not deleted +# when Itsy-Gitsy finishes. If the directories already exist when Itsy-Gitsy +# runs, all remote refs are fetched rather than recloning. +# +# Only non-authenticated HTTPS repositories are currently supported. +cloned_repos = "cloned_repos/" + + +############################################################################### +## +## Subsection for arbitrary, global user data. +## +## These variables are available to every page template. Add extra metadata +## that you want available site-wide here. +## +############################################################################### +[gitsy_extra] +generated_by = "Itsy-Gitsy" +generated_by_url = "https://git.trevorbentley.com/itsy-gitsy/" +#global_user_defined_var = "whatever" +#these_can_also_be_numbers = 5 +#or_bools = true +#or_other_toml_types = {like_dicts = "yep, those too"} + + + +############################################################################### +## +## Individual repository configurations. +## +############################################################################### + +# The section name is used as the repository name if no `name` attribute is +# provided. +#[my_repository] + +# Path to the Git repository. +#path = "/path/to/my_repository" + +# Name of this repository, if different from the section name. +#name = "my_repository" + +# A description of this repository. +#description = "" + +# URL of website associated with this repository. +#website = "" + +# Dictionary of arbitrary, user-defined attributes associated with the repo. +# +# Specifying as an inline-table requires all keys to be on one line. +# +# Available in all repo-specific page templates. +# +#attributes = { status = "active", type = "daemon" } + +# Per-repository settings, same as the global versions described above: + +#clone_url = "https://github.com/your_user/%REPO%" +#branch = "master" +#render_markdown = false +#syntax_highlighting = false +#syntax_highlight_theme = "base16-ocean.dark" +#paginate_history = 50 +#paginate_branches = 50 +#paginate_tags = 50 +#limit_history = 500 +#limit_commits = 500 +#limit_branches = 500 +#limit_tags = 500 +#limit_tree_depth = 20 +#limit_file_size = 2097152 +#limit_repo_size = 52428800 +#limit_total_size = 524288000 +#limit_context = 200 +#limit_diffs = 200 +#asset_files = ["%REPO%/LICENSE"] +#readme_files = ["README.md", "README"] + +# An alternative way to specify the user-defined attributes. +# +# This method allows keys to be on their own lines. +# +#[circadian.attributes] +#status = "active" +#type = "daemon" + +# Remote HTTPS repositories can also be specified: +# +#[remote_repo] +#path = "https://github.com/my_user_name/remote_repo" diff --git a/config.toml b/config.toml index 33261b6..b51cf8b 100644 --- a/config.toml +++ b/config.toml @@ -73,9 +73,16 @@ readme_files = ["README.md", "README"] # Currently does NOT support globbing or directories. Each file must be listed # individually. # +# Use "%TEMPLATE%" variable to substitute the path to the current +# template folder. +# +# Use "%REPO%" variable to substitute the path to the currently +# processing repository (only sensible when used as a per-repo +# configuration). +# # This can also be set per-repository, in which case the `repo_assets` output # directory is used. -asset_files = ["templates/style.css"] +asset_files = ["%TEMPLATE%/style.css"] # Whether to split history output into pages # @@ -307,7 +314,7 @@ syntax_highlight_theme = "base16-ocean.light" # # All files with a .html extension found under this directory, and its # immediate children directories, are imported into the Tera template engine. -path = "templates/" +path = "templates/default_light/" # Template responsible for the list of repositories. # @@ -545,7 +552,7 @@ generated_by_url = "https://git.trevorbentley.com/itsy-gitsy/" #limit_total_size = 524288000 #limit_context = 200 #limit_diffs = 200 -#asset_files = ["LICENSE"] +#asset_files = ["%REPO%/LICENSE"] #readme_files = ["README.md", "README"] # An alternative way to specify the user-defined attributes. diff --git a/src/generate.rs b/src/generate.rs index 4e6bf48..b98ea57 100644 --- a/src/generate.rs +++ b/src/generate.rs @@ -631,7 +631,9 @@ impl GitsyGenerator { if repo_desc.asset_files.is_some() { let target_dir = self.settings.outputs.repo_assets(Some(&parsed_repo), None); for src_file in repo_desc.asset_files.as_ref().unwrap() { - let src_file = PathBuf::from(repo_path.to_owned() + "/" + src_file); + let src_file = src_file.replace("%TEMPLATE%", &self.settings.templates.template_dir()); + let src_file = src_file.replace("%REPO%", &repo_path); + let src_file = PathBuf::from(repo_path.to_owned() + "/" + &src_file); let mut dst_file = PathBuf::from(&target_dir); dst_file.push(src_file.file_name().expect(&format!( "Failed to copy repo asset file: {} ({})", @@ -646,6 +648,7 @@ impl GitsyGenerator { if let Ok(meta) = std::fs::metadata(dst_file) { repo_bytes += meta.len() as usize; } + loud!(" - copied asset: {}", src_file.display()); } } @@ -719,6 +722,7 @@ impl GitsyGenerator { if self.settings.asset_files.is_some() { let target_dir = self.settings.outputs.global_assets(None, None); for src_file in self.settings.asset_files.as_ref().unwrap() { + let src_file = src_file.replace("%TEMPLATE%", &self.settings.templates.template_dir()); let src_file = PathBuf::from(src_file); let mut dst_file = PathBuf::from(&target_dir); dst_file.push( @@ -731,6 +735,7 @@ impl GitsyGenerator { if let Ok(meta) = std::fs::metadata(dst_file) { global_bytes += meta.len() as usize; } + loud!(" - copied asset: {}", src_file.display()); } } diff --git a/src/main.rs b/src/main.rs index 56c9a33..9bfd0ce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,8 @@ use settings::{GitsyCli, GitsySettings}; // TODO: // -// * basic, light, dark, and fancy default themes +// * favicon +// * permalinks (at least for README?) // * better error propagation // * automated tests // * documentation + examples diff --git a/src/settings.rs b/src/settings.rs index 648efec..da3bfe5 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -127,6 +127,15 @@ pub struct GitsySettingsTemplates { pub error: Option, } +impl GitsySettingsTemplates { + pub fn template_dir(&self) -> String { + self.path.clone().canonicalize() + .expect(&format!("ERROR: unable to canonicalize template path: {}", self.path.display())) + .to_str().expect(&format!("ERROR: unable to parse template path: {}", self.path.display())) + .to_string() + } +} + #[derive(Deserialize, Debug)] pub struct GitsySettingsOutputs { pub path: PathBuf, diff --git a/templates/404.html b/templates/default_dark/404.html similarity index 100% rename from templates/404.html rename to templates/default_dark/404.html diff --git a/templates/base.html b/templates/default_dark/base.html similarity index 100% rename from templates/base.html rename to templates/default_dark/base.html diff --git a/templates/branch.html b/templates/default_dark/branch.html similarity index 100% rename from templates/branch.html rename to templates/default_dark/branch.html diff --git a/templates/branches.html b/templates/default_dark/branches.html similarity index 100% rename from templates/branches.html rename to templates/default_dark/branches.html diff --git a/templates/commit.html b/templates/default_dark/commit.html similarity index 100% rename from templates/commit.html rename to templates/default_dark/commit.html diff --git a/templates/dir.html b/templates/default_dark/dir.html similarity index 100% rename from templates/dir.html rename to templates/default_dark/dir.html diff --git a/templates/file.html b/templates/default_dark/file.html similarity index 100% rename from templates/file.html rename to templates/default_dark/file.html diff --git a/templates/files.html b/templates/default_dark/files.html similarity index 100% rename from templates/files.html rename to templates/default_dark/files.html diff --git a/templates/footer.html b/templates/default_dark/footer.html similarity index 100% rename from templates/footer.html rename to templates/default_dark/footer.html diff --git a/templates/header.html b/templates/default_dark/header.html similarity index 100% rename from templates/header.html rename to templates/default_dark/header.html diff --git a/templates/history.html b/templates/default_dark/history.html similarity index 100% rename from templates/history.html rename to templates/default_dark/history.html diff --git a/templates/repos.html b/templates/default_dark/repos.html similarity index 100% rename from templates/repos.html rename to templates/default_dark/repos.html diff --git a/templates/default_dark/style.css b/templates/default_dark/style.css new file mode 100644 index 0000000..4f466af --- /dev/null +++ b/templates/default_dark/style.css @@ -0,0 +1,362 @@ +:root { + --greyblue: #dee2ea; + --greyblue: #345886; + --greypink: #e0deea; + --greypink: #c0d2dd; + --greypink: #555; + --offwhite: #424242; + --offerwhite: #666; + --deepred: #d9ac7d; + --deepblue: #f0e0bb; + --nearwhite: #404040; + --nearblack: #f0f0f0; + --borderverylight: #ddd; + --borderlight: #515151; + --borderdark: #888; +} +body { + height: 100%; + margin: 0; + min-height: 100%; + font-family: monospace,monospace; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + line-height: 1.5; + background-color: var(--nearwhite); + color: var(--nearblack); +} +div { + color: var(--nearblack); +} +div.banner { + width: 95%; + max-width: 100rem; + color: var(--offwhite); + background-color: var(--greyblue); + border-radius: 0 0 30px 30px; + font-family: sans-serif; + text-align: center; + margin: 0 auto 0 auto; + margin-bottom: 1rem; + padding-bottom: 0.5rem; +} +div.breadcrumbs { + background-color: var(--greypink); + font-weight: bold; + padding: 0.5em; + border-radius: 10px 10px 0 0; +} +div.breadcrumbs a { + color: var(--nearblack); + text-decoration: none; +} +div.breadcrumbs span.site-title { + font-size: 1rem; +} +div.breadcrumbs span.repo-name { + font-size: 1.5rem; +} +div.site-title { + letter-spacing: .1em; + font-size: 2.5rem; + font-weight: bold; +} +div.site-description { + min-height: 1.5em; +} +a { + word-wrap: break-word; + background-color: transparent; + color: var(--deepblue); + transition: opacity .1s; +} +a:hover { + opacity: 0.5; +} +a.disabled { + pointer-events: none; + color: var(--nearblack); +} +div.main { + width: 95%; + max-width: 100rem; + margin: 0 auto 0 auto; +} +div.content { + padding: 1em 0 1em 0; +} +table { + width: 100%; +} +table.tabs { + padding: 0 0 0 0; + margin: 0 auto 0 auto; + background-color: var(--offwhite); + border-radius: 0 0 3px 3px; + border-bottom: solid 3px var(--borderlight); + border-spacing: 0; +} +table.tabs td.tab { + text-align: center; + min-width: 8em; + border-right: solid 1px var(--borderdark); +} +table.tabs td.padding { + width: 100%; +} +table.tabs a { + color: var(--deepred); + text-decoration: none; + letter-spacing: .1em; + font-weight: bold; +} +table.tabs td.selected { + background-color: var(--greyblue); + background-color: #ede5de; + background-color: var(--greypink); +} +table.summary-table, table.repo-list { + width: 100%; + max-width: 100%; + background-color: var(--offwhite); + border-radius: 8px; +} +table.summary-table th, table.repo-list th { + text-align: left; + padding-left: 0.3em; +} +table.summary-table tr:nth-child(even), table.repo-list tr:nth-child(even) { + background-color: var(--offerwhite); +} +table.repo-list td { + padding: 0.3em 0.3em 0.3em 0.3em; +} +table.summary-table td, table.repo-list td { + word-break: break-all; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + padding-left: 0.3em; +} +table.repo-list col.repo { + width: 12rem; +} +table.repo-list td.description { + max-width: 40em; +} +table.repo-list col.description { + width: 30rem; +} +table.repo-list col.website { + width: 7em; + max-width: 7em; +} +table.repo-list col.updated { + width: 10em; + max-width: 10em; +} +table.summary-table col.oid { + width: 7em; + max-width: 7em; +} +table.summary-table col.date { + width: 9em; + max-width: 9em; +} +table.summary-table col.diff { + width: 9em; + max-width: 9em; +} +table.summary-table col.msg { + width: 30rem; +} +table.summary-table col.refs { + width: 25rem; +} +table.summary-table col.branch { + width: 30em; +} +table.summary-table col.tag { + width: 30em; +} +table.summary-table col.type { + width: 7em; + max-width: 7em; +} +table.summary-table col.mode { + width: 7em; + max-width: 7em; +} +table.summary-table col.size { + width: 7em; + max-width: 7em; +} +table.summary-table td.msg { + max-width: 10em; +} +table.summary-table td.refs { + font-size: 0.8rem; +} +table.summary-table span.ref { + color: var(--nearblack); + background-color: var(--greyblue); + border-radius: 10px; + margin-right: 1em; + padding: 0 0.5em 0 0.5em; +} +table.summary-table td.sans { + font-family: sans-serif; +} +div.summary-header { + color: var(--nearblack); + letter-spacing: 0.05em; + background-color: var(--greyblue); + font-size: 1.4rem; + font-weight: bold; + text-align: center; + text-transform: uppercase; + margin-top: 2rem; + border-bottom: solid 1px var(--borderdark); + border-radius: 10px 10px 0 0; +} +div.full-header { + color: var(--nearblack); + letter-spacing: 0.05em; + background-color: var(--greyblue); + font-size: 1.4rem; + font-weight: bold; + text-align: center; + text-transform: uppercase; + margin-top: 0rem; + border-bottom: solid 1px var(--borderdark); + border-radius: 10px 10px 0 0; +} +div.nocap-header { + color: var(--nearblack); + letter-spacing: 0.05em; + background-color: var(--greyblue); + font-size: 1.4rem; + font-weight: bold; + text-align: center; + margin-top: 0rem; + border-bottom: solid 1px var(--borderdark); + border-radius: 10px 10px 0 0; +} +hr { + border-color: var(--borderverylight); +} +div.footer { + margin-top: 1em; + padding-bottom: 2em; + text-align: center; + font-size: 0.9rem; +} +nav.paginate { + text-align: center; + margin-top: 2em; +} +nav.paginate span.paginate { + margin: 0 5em 0 5em; +} +nav.paginate a.disabled { + text-decoration: none; + color: var(--borderlight); +} +div.file-contents { + background-color: var(--offwhite); + font-size: 1rem; + overflow: visible; + padding: 0 0.5em 0 0.5em; +} +div.commit-page, div.branch-page, div.tag-page { + background-color: var(--offwhite); + font-size: 1rem; + overflow: visible; +} +table.commit-header, table.branch-header, table.tag-header { + width: 100%; + background-color: var(--offerwhite); + background-color: var(--greypink); + border-radius: 10px 10px 0 0; + padding: 0.5em; + border-bottom: solid 2px var(--borderlight); +} +table.commit-header td.field, table.branch-header td.field, table.tag-header td.field { + width: 10em; + font-weight: bold; +} +div.commit-message { + padding: 1em 0.5em 2em 0.5em; + border-bottom: solid 2px var(--borderlight); +} +div.branch-message, div.tag-message { + padding: 1em 0.5em 2em 0.5em; +} +div.commit-diff { + padding: 0.5em; +} +div.commit-diff-header { + font-weight: bold; +} +div.commit span.hunk-header { + font-weight: bold; +} +div.commit-diff-header pre, div.branch-page pre, div.tag-page pre { + padding: 0; + margin: 0; +} +div.commit-page span.add { + color: #00aa00; +} +div.commit-page span.del { + color: #bb0000; +} +@media screen and (max-width:50em) { + body, table, div { + font-size: 0.8rem; + } + div.footer { + font-size: 0.7rem; + } + col.nosmall, td.nosmall, th.nosmall { + display: none; + visibility: hidden; + } + table.tabs td.tab { + min-width: 0em; + padding: 0 0.3em 0 0.3em; + } + div.file-contents { + font-size: 0.7rem; + } + div.breadcrumbs span.site-title { + font-size: 0.7rem; + } + div.breadcrumbs span.repo-name { + font-size: 0.9rem; + } +} +table.links { + width: 100%; +} +table.links td.field { + font-weight: bold; + width: 10rem; +} +table.links td.value { + text-align: left; +} +div.file-contents pre { + background-color: var(--offwhite); + padding: 0.2em 0.5em 0.2em 0.5em; +} +div.file-contents table { + border-collapse: true; + font-size: 1rem; +} +div.file-contents table th { + border-bottom: 1px solid; +} +div.file-contents table td { + padding: 0.2em 0.5em 0.2em 0.5em; +} diff --git a/templates/subheader.html b/templates/default_dark/subheader.html similarity index 100% rename from templates/subheader.html rename to templates/default_dark/subheader.html diff --git a/templates/summary.html b/templates/default_dark/summary.html similarity index 100% rename from templates/summary.html rename to templates/default_dark/summary.html diff --git a/templates/tag.html b/templates/default_dark/tag.html similarity index 100% rename from templates/tag.html rename to templates/default_dark/tag.html diff --git a/templates/tags.html b/templates/default_dark/tags.html similarity index 100% rename from templates/tags.html rename to templates/default_dark/tags.html diff --git a/templates/default_light/404.html b/templates/default_light/404.html new file mode 100644 index 0000000..6811ef0 --- /dev/null +++ b/templates/default_light/404.html @@ -0,0 +1,5 @@ +{% extends "base.html" %} + +{% block content %} +The page you are seeking does not exist. +{% endblock content %} diff --git a/templates/default_light/base.html b/templates/default_light/base.html new file mode 100644 index 0000000..2644b21 --- /dev/null +++ b/templates/default_light/base.html @@ -0,0 +1,61 @@ + + +{% set head_title = site_name | default(value="Itsy-Gitsy") -%} +{% set head_description = metadata.description | default(value=site_description | default(value="Static Git repository listings")) -%} +{% set root_url = site_url | default(value=site_dir) -%} +{% if name -%} +{% set repo_url = root_url ~ "/" ~ name -%} +{% set head_title = head_title ~ " -- " ~ name -%} +{% endif -%} +{% set asset_url = root_url ~ "/" ~ site_assets -%} +{% set head_url = repo_url | default(value=root_url) -%} + +{% block html_head -%} + + + + + {{head_title}} + + + + + + + +{% block html_head_extra -%} +{% endblock html_head_extra -%} +{% endblock html_head -%} + + + +{% block header -%}{% include "header.html" -%}{% endblock header -%} + +
+ +
+{% block subheader -%}{% include "subheader.html" -%}{% endblock subheader -%} +
+ +{% if repo_url -%} + + + + + + + + + +
summaryhistorybranchestagsfiles
+{% endif -%} + +
+{% block content %}{% endblock content %} +
+ +
+ +{% block footer -%}{% include "footer.html" -%}{% endblock footer -%} + + diff --git a/templates/default_light/branch.html b/templates/default_light/branch.html new file mode 100644 index 0000000..6c6ee14 --- /dev/null +++ b/templates/default_light/branch.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} + +{% block tab_branches_selected -%}selected{% endblock -%} + +{% block content %} +
+ + + + + + +
branch:{{branch.ref_name}}
commit:{% if branch.full_hash in commits -%}{{branch.full_hash}}{% else -%}{{branch.full_hash}}{% endif -%}
author:{{branch.author.name}} <{{branch.author.email}}>
committer:{{branch.committer.name}} <{{branch.committer.email}}>
date:{{ts_to_git_timestamp(ts=branch.ts_utc, tz=branch.ts_offset)}}
+
{{branch.message}}
+
+{% endblock content %} diff --git a/templates/default_light/branches.html b/templates/default_light/branches.html new file mode 100644 index 0000000..1e4c620 --- /dev/null +++ b/templates/default_light/branches.html @@ -0,0 +1,37 @@ +{% extends "base.html" %} + +{% block tab_branches_selected -%}selected{% endblock -%} + +{% block content %} + + + + + + + + + + + + + + + + + {% for entry in branches -%} + + + + + + + + {% endfor -%} +
BranchCommitMessageAuthorDate
{{entry.ref_name}}{{entry.short_hash}}{{entry.summary}}{{entry.author.name}}{{ts_to_date(ts=entry.ts_utc, tz=entry.ts_offset)}}
+ +{% endblock content %} diff --git a/templates/default_light/commit.html b/templates/default_light/commit.html new file mode 100644 index 0000000..89982ed --- /dev/null +++ b/templates/default_light/commit.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} + +{% block tab_history_selected -%}selected{% endblock -%} + +{% block content %} +
+ + + + + + +
commit:{{commit.full_hash}}
author:{{commit.author.name}} <{{commit.author.email}}>
committer:{{commit.committer.name}} <{{commit.committer.email}}>
date:{{ts_to_git_timestamp(ts=commit.ts_utc, tz=commit.ts_offset)}}
parents:{% for parent in commit.parents -%}{% if loop.index0 > 0 -%}, {%endif-%}{% if parent in commits -%}{{parent}}{%else-%}{{parent}}{%endif-%}{%-endfor-%}
+
+
{{commit.message}}
+
+{% if commit.diff -%} +{% for file in commit.diff.files -%} +
+
+
diff --git a/{{file.basefile}} b/{{file.basefile}}
+line changes: +{{file.additions}}/-{{file.deletions}}
+index {{file.oldid | truncate(length=7,end="")}}..{{file.newid | truncate(length=7,end="")}}
+--- {{file.oldfile}}
++++ {{file.newfile}}
+
+{% for hunk in file.hunks -%} +
{{hunk.context}}
+{%- for line in hunk.lines -%}
+{{line.prefix}}{{line.text}}
+{%- endfor -%}
+
+{% endfor -%} +
+{% endfor -%} +{% endif -%} +
+
+{% endblock content %} diff --git a/templates/default_light/dir.html b/templates/default_light/dir.html new file mode 100644 index 0000000..2d69fbb --- /dev/null +++ b/templates/default_light/dir.html @@ -0,0 +1,38 @@ +{% extends "base.html" %} + +{% block tab_files_selected -%}selected{% endblock -%} + +{% block subheader -%} + +{% endblock -%} + +{% block content %} +
{{ dir.path }}
+ + + + + + + + + + + + + + {% for file in files -%} + + {% if file.kind == "dir" -%} + {% set file_name = file.name ~ "/" -%} + {% else -%} + {% set file_name = file.name -%} + {% endif -%} + + + + + + {% endfor -%} +
FileTypeModeSize
{% if file.id in file_ids -%}{{file_name}}{% else -%}{{file_name}}{% endif -%}{{file.kind}}{{file.mode | mask(mask="0xfff") | oct}}{{file.size}}
+{% endblock content %} diff --git a/templates/default_light/file.html b/templates/default_light/file.html new file mode 100644 index 0000000..0ac4511 --- /dev/null +++ b/templates/default_light/file.html @@ -0,0 +1,26 @@ +{% extends "base.html" %} + +{% block html_head_extra %} + +{% endblock html_head_extra %} + +{% block tab_files_selected -%}selected{% endblock -%} + +{% block subheader -%} + +{% endblock -%} + +{% block content %} +
{{ file.path }}
+
+{% if file.contents_safe -%} +{% if file.contents_preformatted -%} +
{{file.contents | safe }}
+{%- else -%} +{{file.contents | safe }} +{%- endif -%} +{%- else -%} +
{{file.contents}}
+{%- endif -%} +
+{% endblock content %} diff --git a/templates/default_light/files.html b/templates/default_light/files.html new file mode 100644 index 0000000..9bf2b24 --- /dev/null +++ b/templates/default_light/files.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} + +{% block tab_files_selected -%}selected{% endblock -%} + +{% block content %} + + + + + + + + + + + + + + + {% for file in root_files -%} + + {% if file.kind == "dir" -%} + {% set file_name = file.name ~ "/" -%} + {% else -%} + {% set file_name = file.name -%} + {% endif -%} + + + + + + {% endfor -%} +
FileTypeModeSize
{% if file.id in file_ids -%}{{file_name}}{% else -%}{{file_name}}{% endif -%}{{file.kind}}{{file.mode | mask(mask="0xfff") | oct}}{{file.size}}
+{% endblock content %} diff --git a/templates/default_light/footer.html b/templates/default_light/footer.html new file mode 100644 index 0000000..2ce9c48 --- /dev/null +++ b/templates/default_light/footer.html @@ -0,0 +1,7 @@ + +{% else -%} +Generated by {{extra | get(key="generated_by", default="Itsy-Gitsy")}} on {{ts_to_git_timestamp(ts=site_generated_ts, tz=site_generated_offset)}} +{% endif -%} diff --git a/templates/default_light/header.html b/templates/default_light/header.html new file mode 100644 index 0000000..08d1fb1 --- /dev/null +++ b/templates/default_light/header.html @@ -0,0 +1,9 @@ + diff --git a/templates/default_light/history.html b/templates/default_light/history.html new file mode 100644 index 0000000..4920d19 --- /dev/null +++ b/templates/default_light/history.html @@ -0,0 +1,40 @@ +{% extends "base.html" %} + +{% block tab_history_selected -%}selected{% endblock -%} + +{% block content %} + + + + + + + + + + + + + + + + + + + {% for entry in history -%} + + + + + + + + +{% endfor -%} +
CommitMessageAuthorDateDiffRefs
{% if entry.full_hash in commit_ids -%}{{entry.short_hash}}{% else -%}{{entry.short_hash}}{% endif -%}{{entry.summary}}{{entry.author.name}}{{ts_to_date(ts=entry.ts_utc, tz=entry.ts_offset)}}{% if entry.stats -%}{{entry.stats.files}} (+{{entry.stats.additions}}/-{{entry.stats.deletions}}){% endif -%}{%- for ref in entry.alt_refs -%}{%- if loop.index0 < 3 -%}{{ref}}{%- endif -%}{%- endfor -%}{% if entry.alt_refs | length > 3 -%}...{% endif -%}
+ +{% endblock content %} diff --git a/templates/default_light/repos.html b/templates/default_light/repos.html new file mode 100644 index 0000000..a1cff45 --- /dev/null +++ b/templates/default_light/repos.html @@ -0,0 +1,26 @@ +{% extends "base.html" %} + +{% block content %} + + + + + + + + + + + + + + {% for repo in repos | sort(attribute="last_ts_utc") | reverse -%} + + + + + + +{% endfor -%} +
RepositoryDescriptionWebsiteLast Updated
{{ repo.name }}{{repo.metadata.description}}{% if repo.metadata.website -%}link{% endif -%}{{ts_to_date(ts=repo.history[0].ts_utc, tz=repo.history[0].ts_offset)}}
+{% endblock content %} diff --git a/templates/style.css b/templates/default_light/style.css similarity index 99% rename from templates/style.css rename to templates/default_light/style.css index 5032221..9f9ca06 100644 --- a/templates/style.css +++ b/templates/default_light/style.css @@ -16,6 +16,8 @@ } body { height: 100%; + margin: 0; + min-height: 100%; font-family: monospace,monospace; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; @@ -23,9 +25,8 @@ body { background-color: var(--nearwhite); color: var(--nearblack); } -body { - margin: 0; - min-height: 100%; +div { + color: var(--nearblack); } div.banner { width: 95%; diff --git a/templates/default_light/subheader.html b/templates/default_light/subheader.html new file mode 100644 index 0000000..9b7f4b5 --- /dev/null +++ b/templates/default_light/subheader.html @@ -0,0 +1 @@ + diff --git a/templates/default_light/summary.html b/templates/default_light/summary.html new file mode 100644 index 0000000..a8ac5ce --- /dev/null +++ b/templates/default_light/summary.html @@ -0,0 +1,151 @@ +{% extends "base.html" %} + +{% block tab_summary_selected -%}selected{% endblock -%} + +{% block content %} + + + + + + + + {% if readme and readme.id in file_ids -%} + + {% else -%} + + {% endif -%} + + + + {% if metadata.website -%} + + {% else -%} + + {% endif-%} + + + + + + + +
Recent history
+ + + + + + + + + + + + + + + + + + {% for entry in history -%} + {% if loop.index0 < 10 -%} + + + + + + + + +{% endif -%} +{% endfor -%} +
CommitMessageAuthorDateDiffRefs
{% if entry.full_hash in commit_ids -%}{{entry.short_hash}}{% else -%}{{entry.short_hash}}{% endif -%}{{entry.summary}}{{entry.author.name}}{{ts_to_date(ts=entry.ts_utc, tz=entry.ts_offset)}}{% if entry.stats -%}{{entry.stats.files}} (+{{entry.stats.additions}}/-{{entry.stats.deletions}}){% endif -%}{%- for ref in entry.alt_refs -%}{%- if loop.index0 < 3 -%}{{ref}}{%- endif -%}{%- endfor -%}{% if entry.alt_refs | length > 3 -%}...{% endif -%}
+ +
Recent branches
+ + + + + + + + + + + + + + + + {% for entry in branches | sort(attribute="ts_utc") | reverse -%} + {% if loop.index0 < 10 -%} + + + + + + + + {% endif -%} + {% endfor -%} +
BranchCommitMessageAuthorDate
{{entry.ref_name}}{{entry.short_hash}}{{entry.summary}}{{entry.author.name}}{{ts_to_date(ts=entry.ts_utc, tz=entry.ts_offset)}}
+ +
Recent tags
+ + + + + + + + + + + + + + + + {% for entry in tags | sort(attribute="ts_utc") | reverse -%} + {% if loop.index0 < 10 -%} + + + + + + + + {% endif -%} + {% endfor -%} +
TagCommitMessageAuthorDate
{{entry.ref_name}}{{entry.short_hash}}{{entry.summary}}{{entry.author.name}}{{ts_to_date(ts=entry.ts_utc, tz=entry.ts_offset)}}
+ +
File tree
+ + + + + + + + + + + + + + {% for file in root_files -%} + + {% if file.kind == "dir" -%} + {% set file_name = file.name ~ "/" -%} + {% else -%} + {% set file_name = file.name -%} + {% endif -%} + + + + + + {% endfor -%} +
FileTypeModeSize
{% if file.id in file_ids -%}{{file_name}}{% else -%}{{file_name}}{% endif -%}{{file.kind}}{{file.mode | mask(mask="0xfff") | oct}}{{file.size}}
+{% endblock content %} diff --git a/templates/default_light/tag.html b/templates/default_light/tag.html new file mode 100644 index 0000000..5178118 --- /dev/null +++ b/templates/default_light/tag.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} + +{% block tab_tags_selected -%}selected{% endblock -%} + +{% block content %} +
+ + + + + + +
tag:{{tag.ref_name}}
hash:{{tag.full_hash}}
tagged commit:{% if tag.tagged_id -%}{% if tag.tagged_id in commits -%}{{tag.tagged_id}}{% else -%}{{tag.tagged_id}}{% endif -%}{% endif -%}
author:{{tag.author.name}} <{{tag.author.email}}>
date:{{ts_to_git_timestamp(ts=tag.ts_utc, tz=tag.ts_offset)}}
+
{{tag.message}}
+
+{% endblock content %} diff --git a/templates/default_light/tags.html b/templates/default_light/tags.html new file mode 100644 index 0000000..b959d1a --- /dev/null +++ b/templates/default_light/tags.html @@ -0,0 +1,37 @@ +{% extends "base.html" %} + +{% block tab_tags_selected -%}selected{% endblock -%} + +{% block content %} + + + + + + + + + + + + + + + + + {% for entry in tags -%} + + + + + + + + {% endfor -%} +
TagCommitMessageAuthorDate
{{entry.ref_name}}{{entry.short_hash}}{{entry.summary}}{{entry.author.name}}{{ts_to_date(ts=entry.ts_utc, tz=entry.ts_offset)}}
+ +{% endblock content %}