diff --git a/assets/scss/app.scss b/assets/scss/app.scss index b4d9749d..667b1b11 100644 --- a/assets/scss/app.scss +++ b/assets/scss/app.scss @@ -62,6 +62,7 @@ $themeColor: {{ site.Params.style.themeColor | default "#007bff" }}; @import "components/buttons.scss"; @import "components/card.scss"; @import "components/clipboard.scss"; +@import "components/command.scss"; @import "components/comments.scss"; @import "components/navbar.scss"; @import "components/img.scss"; diff --git a/assets/scss/components/_command.scss b/assets/scss/components/_command.scss new file mode 100644 index 00000000..865014a8 --- /dev/null +++ b/assets/scss/components/_command.scss @@ -0,0 +1,43 @@ +/* Adapted from PrismJS 1.29.0 +https://prismjs.com/download.html#themes=prism&plugins=command-line */ + +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +.command-line-prompt { + border-right: 1px solid #999; + display: block; + float: left; + font-size: 100%; + letter-spacing: -1px; + margin-right: 1em; + pointer-events: none; + text-align: right; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.command-line-prompt > span::before { + opacity: 0.7; + content: " "; + display: block; + padding-right: 0.8em; +} + +.command-line-prompt > span[data-prompt]::before { + content: attr(data-prompt); +} + +.command-line-prompt > span[data-continuation-prompt]::before { + content: attr(data-continuation-prompt); +} + +.command-line span.token.output { + /* Make shell output lines a bit lighter to distinguish them from shell commands */ + opacity: 0.7; +} diff --git a/content/en/blog/code-highlighting.md b/content/en/blog/code-highlighting.md index 3220c2d1..b31e86b3 100644 --- a/content/en/blog/code-highlighting.md +++ b/content/en/blog/code-highlighting.md @@ -55,3 +55,129 @@ func GetTitleFunc(style string) func(s string) string { } } {{< / highlight >}} + +## Command Prompt Shortcode + +The `command` shortcode generates terminal output for either `bash`, `powershell`, or `sql` shell languages. + +### Bash (default shell) + +Use the `command` shortcode to generate a block with a default bash command prompt. + +```html +{{%/* command */%}} +export MY_VAR=123 +{{%/* /command */%}} +``` + +The result looks like this: +{{% command %}} +export MY_VAR=123 +{{% /command %}} + +Specify `user` and `host` to add the user context to the prompt. In addition, use `(out)` to specify an output line and use `\` to denote a line continuation. + +```html +{{%/* command user="user" host="localhost" */%}} +export MY_VAR=123 +echo "hello" +(out)hello +echo one \ +two \ +three +(out)one two three +echo "goodbye" +(out)goodbye +{{%/* /command */%}} +``` + +The result looks like this: +{{% command user="user" host="localhost" %}} +export MY_VAR=123 +echo "hello" +(out)hello +echo one \ +two \ +three +(out)one two three +echo "goodbye" +(out)goodbye +{{% /command %}} + +### PowerShell + +Set the `shell` argument to `powershell` to generate a PowerShell terminal. Override the `prompt` to add a directory if needed. Use the backtick `` ` `` symbol to denote a line continuation. + +```html +{{%/* command prompt="PS C:\Users\User>" shell="powershell" */%}} +Write-Host ` +'Hello' ` +'from' ` +'PowerShell!' +(out)Hello from PowerShell! +Write-Host 'Goodbye from PowerShell!' +(out)Goodbye from PowerShell! +{{%/* /command */%}} +``` + +The result looks like this: +{{% command prompt="PS C:\Users\User>" shell="powershell" %}} +Write-Host ` +'Hello' ` +'from' ` +'PowerShell!' +(out)Hello from PowerShell! +Write-Host 'Goodbye from PowerShell!' +(out)Goodbye from PowerShell! +{{% /command %}} + +### SQL + +Set the `shell` argument to `sql` to generate a SQL terminal. Use the `(con)` suffix to denote a line continuation. + +```html +{{%/* command prompt="mysql>" shell="sql" */%}} +set @my_var = 'foo'; +set @my_other_var = 'bar'; +CREATE TABLE people ((con) +first_name VARCHAR(30) NOT NULL,(con) +last_name VARCHAR(30) NOT NULL(con) +); +(out)Query OK, 0 rows affected (0.09 sec) +insert into people(con) +values ('John', 'Doe'); +(out)Query OK, 1 row affected (0.02 sec) +select *(con) +from people(con) +order by last_name; +(out)+------------+-----------+ +(out)| first_name | last_name | +(out)+------------+-----------+ +(out)| John | Doe | +(out)+------------+-----------+ +(out)1 row in set (0.00 sec) +{{%/* /command */%}} +``` + +The result looks like this: +{{% command prompt="mysql>" shell="sql" %}} +set @my_var = 'foo'; +set @my_other_var = 'bar'; +CREATE TABLE people ((con) +first_name VARCHAR(30) NOT NULL,(con) +last_name VARCHAR(30) NOT NULL(con) +); +(out)Query OK, 0 rows affected (0.09 sec) +insert into people(con) +values ('John', 'Doe'); +(out)Query OK, 1 row affected (0.02 sec) +select *(con) +from people(con) +order by last_name; +(out)+------------+-----------+ +(out)| first_name | last_name | +(out)+------------+-----------+ +(out)| John | Doe | +(out)+------------+-----------+ +(out)1 row in set (0.00 sec) +{{% /command %}} diff --git a/layouts/shortcodes/command.html b/layouts/shortcodes/command.html new file mode 100644 index 00000000..9688cb33 --- /dev/null +++ b/layouts/shortcodes/command.html @@ -0,0 +1,70 @@ +{{ $host := .Get "host" }} +{{ $user := .Get "user" }} +{{ $prompt := .Get "prompt" }} +{{ $filter := "(out)" }} +{{ $input := trim .Inner "\n" }} + +{{ $shell := lower (.Get "shell") }} +{{ $continuationPrompt := ">" }} +{{ $continuationStr := "\\" }} +{{ if eq $shell "powershell" }} + {{ if not $prompt }}{{ $prompt = "PS>" }}{{ end }} + {{ $continuationPrompt = ">>" }} + {{ $continuationStr = "`" }} +{{ else if eq $shell "sql" }} + {{ if not $prompt }}{{ $prompt = "sql>" }}{{ end }} + {{ $continuationPrompt = "->" }} + {{ $continuationStr = "(con)" }} +{{ else }} + {{ $shell = "bash" }} + {{ if not $prompt }}{{ $prompt = "$" }}{{ end }} + {{ if (and ($host) ($user)) }} + {{ $prompt = printf "[%s@%s] %s" $user $host $prompt}} + {{ end }} +{{ end }} + + + + +{{ $lines := split $input "\n" }} +{{ $prefix := ""}} +{{ $prevLine := "" }} +{{ $refined := "" }} +{{ range $line := $lines }} + {{ if hasPrefix $line $filter }} + {{ $prefix = printf "%s" $prefix }} + {{ if eq $shell "sql" }} + {{ $line = printf "--%s" (strings.TrimPrefix $filter $line) }} + {{ else }} + {{ $line = printf "#%s" (strings.TrimPrefix $filter $line) }} + {{ end }} + {{ else if (strings.HasSuffix $prevLine $continuationStr) }} + {{ $prefix = printf "%s" $prefix $continuationPrompt }} + {{ else }} + {{ $prefix = printf "%s" $prefix $prompt }} + {{ end }} + {{ $prevLine = $line }} + {{ if (and (eq $shell "sql") (strings.HasSuffix $line $continuationStr)) }} + {{ $line = strings.TrimSuffix $continuationStr $line }} + {{ end }} + {{ $refined = printf "%s\n%s" $refined $line }} +{{ end }} + +{{ $refined := trim $refined "\n" }} + +{{ $output := (transform.Highlight $refined $shell | safeHTML) }} + + + +{{ $insert := printf "%s" $prefix }} + +{{ $output := (replace $output ("" | safeHTML) $insert 1 | safeHTML) }} + +{{ if eq $shell "sql"}} + {{ $output = (replace $output "--" "" | safeHTML) }} +{{ else }} + {{ $output = (replace $output "#" "" | safeHTML) }} + {{ $output = (replace $output "#" "" | safeHTML) }} +{{ end }} + +{{ $output }} \ No newline at end of file diff --git a/package.json b/package.json index 2cf1f554..0a141e9c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@markdumay/hugo-theme-hinode", - "version": "0.4.6", + "version": "0.5.0", "description": "Hinode is a clean blog theme for Hugo, an open-source static site generator", "main": "index.js", "publishConfig": {