Introduction
This is /test.md
rendered as /test.html
.
It uses /_layouts/test.html
layout file.
Usage
In /_layouts/test.html
you can change source to
/assets/js/test-search.js
instead of search.js
.
After testing, copy code changes to the /_layouts/test.html
to the other
layouts default.html
, hrb.html
, post.html
and programs.html
Table of Contents
Setting Colors
In _sass
directory are:
-rw-rw-r-- 1 rick rick 7056 Nov 3 2022 jekyll-theme-cayman.scss
-rw-rw-r-- 1 rick rick 4909 Oct 18 2022 rouge-github-gruvbox.scss
-rw-rw-r-- 1 rick rick 3998 Oct 17 2022 rouge-github-monokai-sublime.scss
-rw-rw-r-- 1 rick rick 3297 Oct 19 2022 rouge-github-original.scss
-rw-rw-r-- 1 rick rick 4909 Oct 18 2022 rouge-github.scss
-rw-rw-r-- 1 rick rick 3689 Oct 16 2022 rouge-github-virtua-creative.scss
-rw-rw-r-- 1 rick rick 105 Dec 5 2021 toc.scss
For cayman theme the default rouge color is a bluish #567482 that appears washed out on chocolate background.
/assets/css/style.scss
Yellow Sun / Black Moon in /assets/css/style.scss
:
/* Color Scheme Picker Button in page header */
.color-scheme-button {
// button rotates when clicked see tcm-common-code.js
display: inline-block;
vertical-align: middle;
position: absolute;
left: 0;
margin-left: .3rem;
background: transparent;
border: none;
outline: none;
background-repeat: no-repeat;
background-size: cover;
transition: transform 0.3s;
//@include large { height: 44px; width: 44px; }
// @include medium { height: 36px; width: 36px; }
//@include medium { height: 42px; width: 42px; }
//@include small { height: 42px; width: 42px; }
height: 44px;
width: 44px;
&:hover {
filter: brightness(150%);
}
}
.rotate-button {
// Toggle this class on/off color-scheme-button when clicked
transform: rotate(180deg);
}
Javascript
_includes/tcm-common-code.js
/* Get all .color-scheme-button class instances. `/_includes/page-header.html`
has .color-scheme-button in two different HTML places.
Defined in `/_includes/getRootColors.js`:
currentColorScheme // "colorSchemeCayman" or "colorSchemeDark"
imageColorSchemeCayman =
"https://www.pippim.com/assets/img/icons/color_scheme_cayman.png"
imageColorSchemeDark =
"https://www.pippim.com/assets/img/icons/color_scheme_dark.png"
*/
var cspButtonClasses = document.getElementsByClassName("color-scheme-button")
var cspButtonClick = function() {
// Color Scheme Picker button was clicked on one of page header <div>s
this.classList.toggle('rotate-button') // Add/remove rotate image in button
if (currentColorScheme == "colorSchemeCayman") {
currentColorScheme = "colorSchemeDark"
setColorScheme(colorSchemeDark) // _includes/getRootColors.js
}
else {
currentColorScheme = "colorSchemeCayman"
setColorScheme(colorSchemeCayman) // _includes/getRootColors.js
}
localStorage.setItem("colorScheme", currentColorScheme)
// Wait 300 ms for transition to finish then change image
setTimeout(function(){
setColorSchemeButtonImage(currentColorScheme)
}, 300)
}
for (var ndx = 0; ndx < cspButtonClasses.length; ndx++) {
cspButtonClasses[ndx].addEventListener('click', cspButtonClick, false)
}
function setColorSchemeButtonImage(schemeName) {
// Changing foreground image problematic. Use background image instead
for (var ndx = 0; ndx < cspButtonClasses.length; ndx++) {
var elm = cspButtonClasses[ndx]
if (schemeName == "colorSchemeCayman") {
elm.style.backgroundImage = "url('" + imageColorSchemeDark + "')"
elm.title = "Switch Pippim Website to color scheme Dark"
}
else {
elm.style.backgroundImage = "url('" + imageColorSchemeCayman + "')"
elm.title = "Switch Pippim Website to color scheme Cayman"
}
}
}
setColorSchemeButtonImage(currentColorScheme)
// Get all .tcm-button class instances `/_layouts/default.html` has
// .tcm-button in two different place.
var tcmButtonClasses = document.getElementsByClassName("tcm-button"); // New class
var tcmButtonClick = function() {
// TCM button was clicked on one of page header <div>s
document.querySelector('#tcm_window').style.cssText = `
display: flex;
flex-direction: column;
`;
// Make tcm-button class invisible
for (var ndx = 0; ndx < tcmButtonClasses.length; ndx++) {
tcmButtonClasses[ndx].style.cssText = `
opacity: 0.0;
background: transparent;
background-image: none;
border: none;
`;
}
};
for (var ndx = 0; ndx < tcmButtonClasses.length; ndx++) {
tcmButtonClasses[ndx].addEventListener('click', tcmButtonClick, false);
}
_includes/getRootColors.js
var currentColorScheme // "colorSchemeCayman" or "colorSchemeDark"
// https://www.pippim.com is required when File Save As used for off-line copy
var imageColorSchemeCayman =
"https://www.pippim.com/assets/img/icons/color_scheme_cayman.png"
var imageColorSchemeDark =
"https://www.pippim.com/assets/img/icons/color_scheme_dark.png"
function getCurrentColors() {
/* Local storage key "colorScheme" contains our scheme name.
If it doesn't exist use "colorSchemeCayman" and save to new key.
*/
currentColorScheme = localStorage.getItem('colorScheme')
if (currentColorScheme == null) {
localStorage.setItem("colorScheme", "colorSchemeCayman")
currentColorScheme = "colorSchemeCayman"
}
return (extractRootColors(currentColorScheme))
}
function extractRootColors(schemeName) {
// Set passed "colorScheme" of "Cayman" or "Dark"
var scheme = window[schemeName] // Get scheme object from name
var root = ""
// console.log("/assets/js/setRootColors.js color scheme:", scheme.name)
for (const key of Object.keys(scheme)) {
if (!(key.startsWith("--"))) continue // Ignore "name"
root += " " + key + ": " + scheme[key] + ";\n"
}
return root
}
getCurrentColors() // We are done now. Rest of functions are optional
/* Optional functions to control root variables */
const browser = getBrowser()
const environment = navigator.oscpu + " " + browser.name + " " +
browser.version
function getBrowser() {
// From: https://stackoverflow.com/a/16938481/6929343
var ua = navigator.userAgent, tem
var M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []
if (/trident/i.test(M[1])) {
tem = /\brv[ :]+(\d+)/g.exec(ua) || []
return {name: 'IE', version: (tem[1] || '') }
}
if (M[1]==='Chrome') {
tem=ua.match(/\bOPR|Edge\/(\d+)/)
if (tem!=null) return { name:'Opera', version:tem[1] }
}
M=M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?']
if ((tem=ua.match(/version\/(\d+)/i))!=null) M.splice(1,1,tem[1])
return {
name: M[0],
version: M[1]
}
}
function getColorCode(scheme, key) {
//const rootElm = document.querySelector(':root')
//const rs = getComputedStyle(rootElm)
const value = scheme[key]
return value
}
function setColorCode(scheme, key) {
const value = scheme[key]
if (value === null) return
const rootElm = document.querySelector(':root')
rootElm.style.setProperty(key, value);
}
function setColorScheme(scheme) {
// Set dark theme
//console.log("/_includes/getRootColors.js setColorScheme():", scheme.name)
currentColorScheme = scheme.name
//localStorage.setItem("colorScheme", "colorSchemeDark")
// Above is breaking system???
for (const key of Object.keys(scheme)) {
if (!(key.startsWith("--"))) continue // Ignore "name"
setColorCode(scheme, key)
}
}
Color Codes - rouge-github-monokai-sublime.scss
.highlight .gh { color: #999999; }
.highlight .sr { color: #f6aa11; }
.highlight .go { color: #888888; }
.highlight .gp { color: #555555; }
.highlight .gu { color: #aaaaaa; }
.highlight .nb { color: #f6aa11; }
.highlight .cm { color: #5F9EA0; }
.highlight .err{ color: #960050; }
.highlight .gd { color: #49483e; }
.highlight .kc { color: #66d9ef; }
.highlight .mf { color: #ae81ff; }
.highlight .sd { color: #e6db74; }
.highlight .fm { color: #a6e22e; }
.highlight .vc { color: #00cdcd; }
.highlight .w { color: #ffffff; }
.highlight .ow { color: #f92672; }
.highlight .pi { color: #fbf1c7; }
ALL { background-color: #272822; }
dimgrey => '#75715e'
Rouge List of Tokens
The table below is from the Rouge Ruby List of Tokens ⧉ 🔗.
Token name | Token shortname | Description |
---|---|---|
Text | Any type of text data | |
Text.Whitespace | w | Specially highlighted whitespace |
Error | err | Lexer errors |
Escape | esc | Escape (New) |
Other | x | Token for data not matched by a parser (e.g. HTML markup in PHP code) |
Keyword | k | Any keyword |
Keyword.Constant | kc | Keywords that are constants |
Keyword.Declaration | kd | Keywords used for variable declaration (e.g. var in javascript) |
Keyword.Namespace | kn | Keywords used for namespace declarations |
Keyword.Pseudo | kp | Keywords that aren’t really keywords |
Keyword.Reserved | kr | Keywords which are reserved (such as end in Ruby) |
Keyword.Type | kt | Keywords which refer to a type id (such as int in C) |
Name | n | Variable/function names |
Name.Attribute | na | Attributes (in HTML for instance) |
Name.Builtin | nb | Builtin names which are available in the global namespace |
Name.Builtin.Pseudo | bp | Builtin names that are implicit (such as self in Ruby) |
Name.Class | nc | For class declaration |
Name.Constant | no | For constants |
Name.Decorator | nd | For decorators in languages such as Python or Java |
Name.Entity | ni | Token for entities such as in HTML |
Name.Exception | ne | Exceptions and errors (e.g. ArgumentError in Ruby) |
Name.Function | nf | Function names |
Name.Property | py | Token for properties |
Name.Label | nl | For label names |
Name.Namespace | nn | Token for namespaces |
Name.Other | nx | For other names |
Name.Tag | nt | Tag mainly for markup such as XML or HTML |
Name.Variable | nv | Token for variables |
Name.Variable.Class | vc | Token for class variables (e.g. @@var in Ruby) |
Name.Variable.Global | vg | For global variables (such as $LOAD_PATH in Ruby) |
Name.Variable.Instance | vi | Token for instance variables (such as @var in Ruby) |
Name.Variable.Magic | vm | Token for magic variables (New) |
Literal | l | Any literal (if not further defined) |
Literal.Date | ld | Date literals |
Literal.String | s | String literals |
Literal.String.Affix | sa | String Affix (New) |
Literal.String.Backtick | sb | String enclosed in backticks |
Literal.String.Char | sc | Token type for single characters |
Literal.String.Delimiter | dl | String Delimiter (New) |
Literal.String.Doc | sd | Documentation strings (such as in Python) |
Literal.String.Double | s2 | Double quoted strings |
Literal.String.Escape | se | Escaped sequences in strings |
Literal.String.Heredoc | sh | For “heredoc” strings (e.g. in Ruby) |
Literal.String.Interpol | si | For interpolate part in strings (e.g. in Ruby) |
Literal.String.Other | sx | Token type for any other strings (for example %q{foo} string constructs in Ruby) |
Literal.String.Regex | sr | Regular expressions literals |
Literal.String.Single | s1 | Single quoted strings |
Literal.String.Symbol | ss | Symbols (such as :foo in Ruby) |
Literal.Number | m | Any number literal (if not further defined) |
Literal.Number.Float | mf | Float numbers |
Literal.Number.Hex | mh | Hexadecimal numbers |
Literal.Number.Integer | mi | Integer literals |
Literal.Number.Integer.Long | il | Long integer literals |
Literal.Number.Oct | mo | Octal literals |
Literal.Number.Hex | mx | Hexadecimal literals |
Literal.Number.Bin | mb | Binary literals |
Operator | o | Operators (commonly +, -, /, *) |
Operator.Word | ow | Word operators (e.g. and) |
Punctuation | p | Punctuation which is not an operator |
Punctuation.Indicator | pi | Punctuation indicator (New) |
Comment | c | Single line comments |
Comment.Hashbang | ch | Hashbang comment (New) |
Comment.Doc | cd | Doc comment (New) |
Comment.Multiline | cm | Multiline comments |
Comment.Preproc | cp | Preprocessor comments such as <% %> in ERb |
Comment.PreprocFile | cpf | Preprocessor comments file (New) |
Comment.Single | c1 | Comments that end at the end of the line |
Comment.Special | cs | Special data in comments such as @license in Javadoc |
Generic | g | Unstyled token |
Generic.Deleted | gd | Token value as deleted |
Generic.Emph | ge | Token value as emphasized |
Generic.Error | gr | Token value as an error message |
Generic.Heading | gh | Token value as a headline |
Generic.Inserted | gi | Token value as inserted |
Generic.Output | go | Marked as a program output |
Generic.Prompt | gp | Marked as a command prompt |
Generic.Strong | gs | Mark the token value as bold (for rst lexer) |
Generic.Subheading | gu | Marked as a sub-headline |
Generic.Traceback | gt | Mark the token as a part of an error traceback |
Generic.Lineno | gl | Line numbers |
Code provided by tech support on Github.
Rouge token.rb
🔗
Test Fetch rouge-ruby
(Cross-Origin Errors in Console Debug)
Rouge Legend
Copy the color scheme you want to use to /_sass/github-rouge.scss
.
As of September 18, 2023 (and for the last year),
/_sass/rouge-github-gruvbox.scss
has been copied.
IMPORTANT NOTE:
The plain text color for rouge is inherited from cayman/dark code block:
`"--code-text-color": "#29ee14"`
The cayman theme background color for code block is:
`"--code-bg-color": "#aa2266"` (ugly purple, easy to read) `"--code-bg-color": "#331100"` (nice easy to read, but dark background) `"--code-bg-color": "#ffddcc"` (ugly salmon, text hard to read) `"--code-bg-color": "#ffbbff"` (ugly bright pink, text hard to read) `"--code-bg-color": "#ffeeff"` (ugly light pink, hard to read) `"--code-bg-color": "#eeeeee"` (off whilte, 40% reading, not distracting) `"--code-bg-color": "#dddddd"` (purple tint, hard to read) `"--code-bg-color": "#f0eef0"` (can't read) `"--code-bg-color": "#eeccee"` (ugly pink, can't read) `"--code-bg-color": "#bcbcbc"` (light grey, can't read) `"--code-bg-color": "#320a3c"` (dark purple joker tint, easy to read)
The dark theme background color for code block is:
`"--code-bg-color": "#332211"` (dark purple, not bad, easy to read)
Option 2
The Green text color for rouge is inherited from cayman/dark code block:
`"--code-text-color": "#5e9755"`
Option 3
The Dull Green text color:
`"--code-text-color": "#6a8759"`
The cayman theme background color for code block is:
`"--code-bg-color": "#dddddd"`
The dark theme background color for code block is:
`"--code-bg-color": "#202020"`
/**
* From: https://code.gov.cz/gov-cz/about/-/blob/a1cb43f3effc4de4d270f8cca881cbf8f3ddc064/_sass/_syntax-highlighting.scss
* Syntax highlighting styles
*/
.highlight {
background: #fff;
@extend %vertical-rhythm;
.highlighter-rouge & {
background: #eef;
}
.c { color: #998; font-style: italic } // Comment
.err { color: #a61717; background-color: #e3d2d2 } // Error
.k { font-weight: bold } // Keyword
.o { font-weight: bold } // Operator
.cm { color: #998; font-style: italic } // Comment.Multiline
.cp { color: #999; font-weight: bold } // Comment.Preproc
.c1 { color: #998; font-style: italic } // Comment.Single
.cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special
.gd { color: #000; background-color: #fdd } // Generic.Deleted
.gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific
.ge { font-style: italic } // Generic.Emph
.gr { color: #a00 } // Generic.Error
.gh { color: #999 } // Generic.Heading
.gi { color: #000; background-color: #dfd } // Generic.Inserted
.gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific
.go { color: #888 } // Generic.Output
.gp { color: #555 } // Generic.Prompt
.gs { font-weight: bold } // Generic.Strong
.gu { color: #aaa } // Generic.Subheading
.gt { color: #a00 } // Generic.Traceback
.kc { font-weight: bold } // Keyword.Constant
.kd { font-weight: bold } // Keyword.Declaration
.kp { font-weight: bold } // Keyword.Pseudo
.kr { font-weight: bold } // Keyword.Reserved
.kt { color: #458; font-weight: bold } // Keyword.Type
.m { color: #099 } // Literal.Number
.s { color: #d14 } // Literal.String
.na { color: #008080 } // Name.Attribute
.nb { color: #0086B3 } // Name.Builtin
.nc { color: #458; font-weight: bold } // Name.Class
.no { color: #008080 } // Name.Constant
.ni { color: #800080 } // Name.Entity
.ne { color: #900; font-weight: bold } // Name.Exception
.nf { color: #900; font-weight: bold } // Name.Function
.nn { color: #555 } // Name.Namespace
.nt { color: #000080 } // Name.Tag
.nv { color: #008080 } // Name.Variable
.ow { font-weight: bold } // Operator.Word
.w { color: #bbb } // Text.Whitespace
.mf { color: #099 } // Literal.Number.Float
.mh { color: #099 } // Literal.Number.Hex
.mi { color: #099 } // Literal.Number.Integer
.mo { color: #099 } // Literal.Number.Oct
.sb { color: #d14 } // Literal.String.Backtick
.sc { color: #d14 } // Literal.String.Char
.sd { color: #d14 } // Literal.String.Doc
.s2 { color: #d14 } // Literal.String.Double
.se { color: #d14 } // Literal.String.Escape
.sh { color: #d14 } // Literal.String.Heredoc
.si { color: #d14 } // Literal.String.Interpol
.sx { color: #d14 } // Literal.String.Other
.sr { color: #009926 } // Literal.String.Regex
.s1 { color: #d14 } // Literal.String.Single
.ss { color: #990073 } // Literal.String.Symbol
.bp { color: #999 } // Name.Builtin.Pseudo
.vc { color: #008080 } // Name.Variable.Class
.vg { color: #008080 } // Name.Variable.Global
.vi { color: #008080 } // Name.Variable.Instance
.il { color: #099 } // Literal.Number.Integer.Long
}
Rouge _sass/rouge-github-gruvbox.scss
/* https://github.com/daveyarwood/gruvbox-pygments/blob/master/gruvbox.css
Oct 17/22 copy from rouge-github-gruvbox.scss (backup version)
https://github.com/rouge-ruby/rouge/blob/master/lib/rouge/token.rb#L75
Note we use Num as an alias for Literal::Number and Str as an alias for Literal::String.
*/
.highlight table td { padding: 5px; }
.highlight table pre { margin: 0; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #282828; background-color: #282828; color: #ebdbb2; }
.highlight .c { color: #928374; font-style: italic; } /* Comment */
.highlight .err { color: #ebdbb2; } /* Error */
.highlight .esc { color: #ebdbb2; } /* Escape */
.highlight .g { color: #ebdbb2; } /* Generic */
.highlight .k { color: #fe8019; } /* Keyword */
.highlight .l { color: #ebdbb2; } /* Literal */
.highlight .n { color: #ebdbb2; } /* Name */
.highlight .o { color: #fe8019; } /* Operator */
.highlight .x { color: #ebdbb2; } /* Other */
.highlight .p { color: #ebdbb2; } /* Punctuation */
.highlight .ch { color: #928374; font-style: italic; } /* Comment.Hashbang */
.highlight .cm { color: #928374; font-style: italic; } /* Comment.Multiline */
.highlight .cp { color: #8ec07c; } /* Comment.Preproc */
.highlight .c1 { color: #928374; font-style: italic; } /* Comment.Single */
.highlight .cs { color: #928374; font-style: italic; } /* Comment.Special */
.highlight .gd { color: #282828; background-color: #fb4934 } /* Generic.Deleted */
.highlight .ge { color: #83a598; text-decoration: underline; } /* Generic.Emph */
.highlight .gr { color: #ebdbb2; font-weight: bold; background-color: #fb4934 } /* Generic.Error */
.highlight .gh { color: #b8bb26; font-weight: bold; } /* Generic.Heading */
.highlight .gi { color: #282828; background-color: #b8bb26 } /* Generic.Inserted */
.highlight .go { color: #504945; } /* Generic.Output */
.highlight .gp { color: #ebdbb2; } /* Generic.Prompt */
.highlight .gs { color: #ebdbb2; } /* Generic.Strong */
.highlight .gu { color: #b8bb26; font-weight: bold; } /* Generic.Subheading */
.highlight .gt { color: #ebdbb2; font-weight: bold; background-color: #fb4934 } /* Generic.Traceback */
.highlight .kc { color: #fe8019; } /* Keyword.Constant */
.highlight .kd { color: #fe8019; } /* Keyword.Declaration */
.highlight .kn { color: #fe8019; } /* Keyword.Namespace */
.highlight .kp { color: #fe8019; } /* Keyword.Pseudo */
.highlight .kr { color: #fe8019; } /* Keyword.Reserved */
.highlight .kt { color: #fabd2f; } /* Keyword.Type */
.highlight .ld { color: #ebdbb2; } /* Literal.Date */
.highlight .m { color: #d3869b; } /* Literal.Number */
.highlight .s { color: #b8bb26; } /* Literal.String */
.highlight .na { color: #b8bb26; font-weight: bold; } /* Name.Attribute */
.highlight .nb { color: #fabd2f; } /* Name.Builtin */
.highlight .nc { color: #ebdbb2; } /* Name.Class */
.highlight .no { color: #d3869b; } /* Name.Constant */
.highlight .nd { color: #ebdbb2; } /* Name.Decorator */
.highlight .ni { color: #fabd2f; } /* Name.Entity */
.highlight .ne { color: #fb4934; } /* Name.Exception */
.highlight .nf { color: #fabd2f; } /* Name.Function */
.highlight .nl { color: #fb4934; } /* Name.Label */
.highlight .nn { color: #ebdbb2; } /* Name.Namespace */
.highlight .nx { color: #ebdbb2; } /* Name.Other */
.highlight .py { color: #ebdbb2; } /* Name.Property */
.highlight .nt { color: #fb4934; } /* Name.Tag */
.highlight .nv { color: #ebdbb2; } /* Name.Variable */
.highlight .ow { color: #fe8019; } /* Operator.Word */
.highlight .w { color: #ebdbb2; } /* Text.Whitespace */
.highlight .mb { color: #d3869b; } /* Literal.Number.Bin */
.highlight .mf { color: #d3869b; } /* Literal.Number.Float */
.highlight .mh { color: #d3869b; } /* Literal.Number.Hex */
.highlight .mi { color: #d3869b; } /* Literal.Number.Integer */
.highlight .mo { color: #d3869b; } /* Literal.Number.Oct */
.highlight .sb { color: #b8bb26; } /* Literal.String.Backtick */
.highlight .sc { color: #b8bb26; } /* Literal.String.Char */
.highlight .sd { color: #b8bb26; } /* Literal.String.Doc */
.highlight .s2 { color: #b8bb26; } /* Literal.String.Double */
.highlight .se { color: #b8bb26; } /* Literal.String.Escape */
.highlight .sh { color: #b8bb26; } /* Literal.String.Heredoc */
.highlight .si { color: #b8bb26; } /* Literal.String.Interpol */
.highlight .sx { color: #b8bb26; } /* Literal.String.Other */
.highlight .sr { color: #b8bb26; } /* Literal.String.Regex */
.highlight .s1 { color: #b8bb26; } /* Literal.String.Single */
.highlight .ss { color: #83a598; } /* Literal.String.Symbol */
.highlight .bp { color: #fabd2f; } /* Name.Builtin.Pseudo */
.highlight .vc { color: #ebdbb2; } /* Name.Variable.Class */
.highlight .vg { color: #ebdbb2; } /* Name.Variable.Global */
.highlight .vi { color: #ebdbb2; } /* Name.Variable.Instance */
.highlight .il { color: #d3869b; } /* Literal.Number.Integer.Long */
/* End of rouge-github-gruvbox.scss */
Rouge _sass/rouge-github-monokai-sublime.scss
/* https://github.com/pages-themes/cayman/blob/master/_sass/rouge-github.scss
Oct 15/22 copy from rouge-github-monokai-sublime.scss (backup version)
// = found in original cayman theme
// missing = found here but not in cayman theme
*/
.highlight table td { padding: 5px; }
.highlight table pre { margin: 0; }
.highlight .gh { color: #999999; } //
.highlight .sr { color: #f6aa11; } //
.highlight .go { color: #888888; } //
.highlight .gp { color: #555555; } //
.highlight .gs { font-weight: bold; } //
.highlight .gu { color: #aaaaaa; } //
.highlight .nb { color: #f6aa11; } //
.highlight .cm { color: #5F9EA0; font-style: italic; } //
.highlight .cp { color: #5F9EA0; } //
.highlight .c1 { color: #5F9EA0; font-style: italic; } //
.highlight .cs { color: #5F9EA0; font-weight: bold; font-style: italic; } //
.highlight .c { color: #5F9EA0; font-style: italic; } //
.highlight .ch { color: #5F9EA0; } // missing
.highlight .cd { color: #5F9EA0; font-style: italic; } //
.highlight .cpf{ color: #5F9EA0; } // missing
.highlight .err{ color: #960050; } // background ?
.highlight .gr { color: #960050; } //
.highlight .gt { color: #960050; } //
.highlight .gd { color: #49483e; } // background ?
.highlight .gi { color: #49483e; } //
.highlight .ge { color: #49483e; font-style: italic; } //
.highlight .kc { color: #66d9ef; font-weight: bold; } //
.highlight .kd { color: #66d9ef; font-weight: bold; } //
.highlight .kr { color: #66d9ef; font-weight: bold; } //
.highlight .no { color: #66d9ef; } //
.highlight .kt { color: #66d9ef; font-weight: bold; } //
.highlight .mf { color: #ae81ff; } //
.highlight .mh { color: #ae81ff; } //
.highlight .il { color: #ae81ff; } //
.highlight .mi { color: #ae81ff; } //
.highlight .mo { color: #ae81ff; } //
.highlight .m { color: #ae81ff; } //
.highlight .mb { color: #ae81ff; } //
.highlight .mx { color: #ae81ff; } //
.highlight .sc { color: #ae81ff; } //
.highlight .se { color: #ae81ff; } //
.highlight .ss { color: #ae81ff; } //
.highlight .sd { color: #e6db74; } //
.highlight .s2 { color: #e6db74; } //
.highlight .sb { color: #e6db74; } //
.highlight .sh { color: #e6db74; } //
.highlight .si { color: #e6db74; } //
.highlight .sx { color: #e6db74; } //
.highlight .s1 { color: #e6db74; } //
.highlight .s { color: #e6db74; } //
.highlight .sa { color: #e6db74; } // missing
.highlight .dl { color: #e6db74; } // missing
.highlight .na { color: #a6e22e; } //
.highlight .nc { color: #a6e22e; } //
.highlight .nd { color: #a6e22e; font-weight: bold; } //
.highlight .ne { color: #a6e22e; font-weight: bold; } //
.highlight .nf { color: #a6e22e; font-weight: bold; } //
.highlight .fm { color: #a6e22e; } // missing
.highlight .vc { color: #00cdcd; } //
.highlight .nn { color: #00cdcd; } //
.highlight .nl { color: #00cdcd; font-weight: bold; } //
.highlight .ni { color: #00cdcd; font-weight: bold; } //
.highlight .bp { color: #00cdcd; } //
.highlight .vg { color: #00cdcd; } //
.highlight .vi { color: #00cdcd; } //
.highlight .nv { color: #00cdcd; } //
.highlight .vm { color: #00cdcd; } // missing
.highlight .w { color: #ffffff; } //
.highlight .n { color: #ffffff; } // missing
.highlight .py { color: #ffffff; } // missing
.highlight .nx { color: #ffffff; } // missing
.highlight .ow { color: #f92672; font-weight: bold; } //
.highlight .nt { color: #f92672; } //
.highlight .k { color: #f92672; font-weight: bold; } //
.highlight .kv { color: #f92672; font-weight: bold; } //
.highlight .kn { color: #f92672; font-weight: bold; } //
.highlight .kp { color: #f92672; font-weight: bold; } //
.highlight .o { color: #f92672; font-weight: bold; } //
.highlight .p { color: #fbf1c7; } // missing
.highlight .pi { color: #fbf1c7; } // missing
.highlight {
color: #ffffff;
background-color: #272822;
border-radius: .5rem;
/* Oct 15/22 - Following already in Cayman
margin-bottom: 30px;
margin-top: 27px;
margin-left: 0px;
margin-right: 0px;
width: 100%; */
}
/* End of rouge-github-monokai-sublime.scss */
Miscellaneous Color Codes
--body-link-color: #1e6bb8;
--body-link-inverted-color: #e19447;
#819198
#f3f6fa
#567482 bluish color code in rouge plain text
#dce6f0
#e9ebec
#eff0f1
#fafbfc
#c6cbd1
#959da5
#444d56
#e9ebec
Copy code
This section shows how to copy code inside Rouge to the system clipboard.
The original Author’s old code and new code is below. However Pippim website had to use a totally new technique.
https://github.com/AleksandrHovhannisyan/aleksandrhovhannisyan.com/issues/35
Test Single Text Line
<!-- This is a single line of HTML comment -->
Test Two Text Lines
<!-- This is the first line of HTML comment -->
<!-- This is the second line -->
New Javascript /assets/js/theCookieMachine.js
// COPY ROUGE CODE BLOCKS
const copyButtonLabel = "Copy 📋";
let blocks = document.querySelectorAll("div.highlight") // Rouge second level out of three
blocks.forEach((block) => {
// only add button if browser supports Clipboard API
if (navigator.clipboard) {
block.classList.add("rouge-code-block")
let copyRougeButton = document.createElement("button")
// Remove ', "page-header-button"' or replace with your own button styling class name
copyRougeButton.classList.add("copy-rouge-button", "page-header-button")
copyRougeButton.innerText = copyButtonLabel
copyRougeButton.setAttribute('title', 'Copy code to clipboard')
copyRougeButton.setAttribute('aria-label', "Copy code to clipboard")
copyRougeButton.addEventListener("click", copyRougeCode)
block.appendChild(copyRougeButton)
}
});
async function copyRougeCode(event) {
const button = event.srcElement
const pre = button.parentElement
let code = pre.querySelector("code")
let text = code.innerText
await navigator.clipboard.writeText(text)
button.innerText = "Copied ✓" /* ✓ or ✔️ ✓ */
setTimeout(()=> button.innerText = copyButtonLabel, 1500)
}
Old HTML
<!-- Copy code block contents to system clipboard. From:
https://www.aleksandrhovhannisyan.com/blog/
how-to-add-a-copy-to-clipboard-button-to-your-jekyll-blog/
-->
<div class="code-header">
<button class="copy-code-button" title="Copy code to clipboard"
aria-label="Copy code to clipboard"></button>
</div>
Old CSS
// Copy code block contents to clipboard
// See: _includes/copyHeader.html for credit
.code-header {
display: flex;
justify-content: flex-end;
}
.copy-code-button {
display: grid;
grid-auto-flow: column;
align-items: center;
grid-column-gap: 4px;
border: none;
cursor: pointer;
font-size: 1rem;
padding: 4px 8px;
&::before {
content: "Copy";
}
&::after {
content: "📋";
display: block;
}
// This class will be toggled via JavaScript
&.copied {
&::before { content: "Copied!"; }
&::after { content: "✔️"; }
}
}
Old Javascript
// Copy code block contents to clipboard.
// See _includes/copyHeader.html for credit
// This assumes that you're using Rouge; if not, update the selector
const codeBlocks = document.querySelectorAll('.code-header + .highlighter-rouge');
const copyCodeButtons = document.querySelectorAll('.copy-code-button');
copyCodeButtons.forEach((copyCodeButton, index) => {
const code = codeBlocks[index].innerText;
copyCodeButton.addEventListener('click', () => {
// Copy the code to the user's clipboard
window.navigator.clipboard.writeText(code);
// Update the button text visually
/* NEW CODE published May 23, 2022:
const { innerText: originalText } = copyCodeButton;
copyCodeButton.innerText = 'Copied!';
*/
// (Optional) Toggle a class for styling the button
copyCodeButton.classList.add('copied');
// After 2 seconds, reset the button to its initial UI
setTimeout(() => {
/* NEW CODE published May 23, 2022:
copyCodeButton.innerText = originalText;
*/
copyCodeButton.classList.remove('copied');
}, 2000);
});
});
New JavaScript on Author’s Website
import { THEME_KEY, Themes, copyToClipboardButtonStrings } from './constants.mjs';
import ThemeToggle from './components/ThemeToggle/index.mjs';
const themeToggleElement = document.getElementById('theme-toggle');
const cachedTheme = localStorage.getItem(THEME_KEY);
const preferredTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? Themes.DARK : Themes.LIGHT;
// eslint-disable-next-line no-unused-vars
const themeToggle = new ThemeToggle({
toggleElement: themeToggleElement,
initialTheme: cachedTheme ?? preferredTheme,
setTheme: (theme) => {
document.documentElement.dataset[THEME_KEY] = theme;
themeToggleElement.setAttribute('aria-pressed', theme === Themes.DARK);
},
setCachedTheme: (theme) => localStorage.setItem(THEME_KEY, theme),
themes: {
[Themes.LIGHT]: Themes.DARK,
[Themes.DARK]: Themes.LIGHT,
},
});
const copyableCodeBlocks = document.querySelectorAll('code[data-copyable="true"]');
copyableCodeBlocks.forEach((codeBlock) => {
const code = codeBlock.innerText;
const copyCodeButton = document.createElement('button');
copyCodeButton.className = 'copy-code-button fs-sm';
copyCodeButton.innerText = copyToClipboardButtonStrings.default;
copyCodeButton.setAttribute('aria-label', copyToClipboardButtonStrings.ariaLabel);
copyCodeButton.type = 'button';
codeBlock.parentElement.append(copyCodeButton);
// Accessible alert whose inner text changes when we copy.
const copiedAlert = document.createElement('span');
copiedAlert.setAttribute('role', 'alert');
copiedAlert.classList.add('screen-reader-only');
codeBlock.parentElement.append(copiedAlert);
copyCodeButton.addEventListener('click', () => {
window.navigator.clipboard.writeText(code);
copyCodeButton.classList.add('copied');
copyCodeButton.innerText = copyToClipboardButtonStrings.copied;
copiedAlert.innerText = copyToClipboardButtonStrings.copied;
setTimeout(() => {
copyCodeButton.classList.remove('copied');
copyCodeButton.innerText = copyToClipboardButtonStrings.default;
copiedAlert.innerText = '';
}, 2000);
});
});
Author’s new CSS
/* stylelint-disable no-descending-specificity */
@import "../functions";
@import "../mixins";
/* VS Code Dark Plus theme: https://github.com/PrismJS/prism-themes/blob/master/themes/prism-vsc-dark-plus.css */
$code-block-padding: spacing(5);
pre[class*="language-"] {
background: var(--color-code-background);
box-shadow: var(--shadow-code-block);
color: var(--color-code-text);
position: relative;
@include full-bleed;
@include tablet {
border-radius: spacing(-2);
}
&:hover {
.copy-code-button {
opacity: 1;
}
}
code {
padding: $code-block-padding;
text-align: start;
white-space: pre;
word-spacing: normal;
word-break: normal;
tab-size: 2;
overflow-x: auto;
display: block;
&[data-file] {
padding-top: calc(#{$code-block-padding} + 3em);
// File name
&::before {
content: "Filename: " attr(data-file);
position: absolute;
top: 0;
left: 0;
color: var(--color-code-text);
word-break: break-all;
padding: $code-block-padding $code-block-padding 0;
@include font-family("title");
@include font-weight("title", "bold");
@include font-size("sm");
}
}
}
.namespace {
opacity: 0.7;
}
&::selection,
& *::selection {
text-shadow: none;
color: unset;
background: var(--color-code-selection);
}
}
.token {
&:is(.doctype, .doctype-tag) {
.name {
color: var(--color-code-attribute);
}
}
&.comment {
margin: 0;
}
&:is(.comment, .prolog) {
color: var(--color-code-comment);
}
&.number {
color: var(--color-code-constant);
}
&.script {
color: var(--color-code-text);
}
&.punctuation,
&.cdata {
color: var(--color-code-punctuation);
}
/* stylelint-disable-next-line max-line-length */
&:is(.keyword, .tag, .boolean, .constant, .inserted, .operator.arrow, .key.atrule, .rule, .keyword.module, .keyword.control-flow, .entity, .important, .punctuation.interpolation-punctuation, .doctype, .doctype-tag, .directive-hash),
&.atrule .url {
color: var(--color-code-keyword);
}
&:is(.selector, .string, .char, .builtin, .deleted, .regex, .attr-value),
&.attr-value &.punctuation {
color: var(--color-code-string);
}
&:is(.operator, .entity, .function),
&.atrule &.url &.punctuation,
&.attr-value &.punctuation.attr-equals,
&.function &.maybe-class-name {
color: var(--color-code-text);
}
&:is(.attr-name, .constant, .console, .property, .variable),
&.imports &.maybe-class-name,
&.exports &.maybe-class-name {
color: var(--color-code-attribute);
}
&.italic {
font-style: italic;
}
}
/* Language Specific */
pre[class*="language-css"],
pre[class*="language-scss"],
pre[class*="language-sass"] {
.token.selector {
color: var(--color-code-selector);
}
}
pre[class*="language-bash"] {
.token:not(.comment) {
color: var(--color-code-text) !important;
}
}
.copy-code-button {
opacity: 0;
position: absolute;
right: $code-block-padding;
top: $code-block-padding;
display: none;
color: var(--color-code-text);
background-color: var(--color-code-overlay-1);
padding: spacing(-2) spacing(0);
border-radius: spacing(-3);
&:is(.copied, :focus) {
opacity: 1;
}
&:is(.copied, :hover) {
color: black;
background-color: var(--color-code-overlay-2);
}
@include tablet {
display: unset;
}
}
Override buttons
Use these buttons to force screen size