Repository: gohugoio/hugo (language: go)

Issue:
[feature] New attribute for highlight shortcode to allow span tag like inline but syntax highlighted code
- [Discussion on Discourse](https://discourse.gohugo.io/t/is-there-a-way-to-inline-syntax-highlight-short-code-snippets/36834)
- [experiment](https://inline-highlight-sc-attempt--hugo-mwe.netlify.app/posts/inline-highlight-shortcode/#hack) | [markdown source](https://gitlab.com/hugo-mwe/hugo-mwe/-/raw/inline-highlight-sc-attempt/content/posts/inline-highlight-shortcode.md)

---

Right now, if I have this in the markdown:

```md
I am attempting to inline
{{< highlight emacs "linenos=inline" >}}(message "this highlight shortcode"){{< /highlight >}}.
But it is creating a paragraph break around it.
```

it renders to:

![image](https://user-images.githubusercontent.com/3578197/151622151-e3bf8e6a-345a-49a4-b7e6-80e12a87faa4.png)


This issue is to request a feature addition to the highlight shortcode with a boolean attribute like `inline`, where if `inline=true` is set, it will render `span` tags instead of `div` tags and remove the `pre` tags.

With a shortcode "hl4.html" defined this way:

```html
{{- transform.Highlight .Inner (.Get 0) (.Get 1 | default "")
    | replaceRE `^<div class="highlight"><pre [^>]+>((.|\n)+)</pre></div>$`
                `<span class="highlight-inline chroma">${1}</span>`
    | safeHTML -}}
```

and this in the markdown:

```md
I am attempting to inline
{{< hl4 emacs >}}(message "this hl4 shortcode"){{< /hl4>}}. And this!! finally works.
```

we can get this:

![image](https://user-images.githubusercontent.com/3578197/151622366-1a8aa9b7-adbc-4efb-9fb4-38a20e6cfdfe.png)



Discussion / hints:
@bep I am following up on this request. 

I have started using this shortcode called `inline-src` in my posts.

## `inline-src.html` shortcode

- The first `replaceRE` replaces the div+pre block with span (inline HTML)
- The second `replaceRE` removes a wrapping `class="line"` span because Chroma sets `display: flex;` for that `.chroma .line` which creates strange artifacts for the piece of text that's supposed to stay inline.

```html
{{- transform.Highlight .Inner (.Get 0) (.Get 1 | default "")
    | replaceRE `^<div class="highlight"><pre [^>]+>((.|\n)+)</pre></div>$`
                `<span class="inline-src chroma">${1}</span>`
    | replaceRE `<span class="line">((.|\n)+)</span>`
                `${1}`
    | safeHTML -}}
```

.. and the results look great!

## Results

```md
If you liked how these _"generics"_ work in SystemVerilog and how the
{{< inline-src systemverilog >}}math #(int)::add(1, 2));{{< /inline-src >}} syntax
looks, check out the
```

![image](https://user-images.githubusercontent.com/3578197/153610577-e154c9bb-7e85-4742-bf35-8726c16ce051.png)

```md
In order to make `add` work with strings as well, we need this messy
_cast_ when the type name is _"string"_ : {{< inline-src systemverilog >}}$cast(ret_val, $sformatf("%s%s", a, b));{{< /inline-src >}}. It's basically
```

![image](https://user-images.githubusercontent.com/3578197/153611062-22447656-4b35-4ae8-97b0-427fe262a4d4.png)

## What's Next?

Can you include this shortcode as one of the inbuilt shortcodes?
What I suggest we do to make this as consistent as possible without adding too much "new stuff":

* See https://github.com/gohugoio/hugo/blob/19f816f77e9c0a9caddfd112d525bad8b717da44/markup/highlight/highlight.go#L85
* If we add an option (e.g. `inline`) to the highlight shortcode + the regular hightlight template function
* Then we could change the signature on https://github.com/gohugoio/hugo/blob/19f816f77e9c0a9caddfd112d525bad8b717da44/markup/highlight/highlight.go#L71  to be inline with the other, and use the `.Inner` in the inline case.
Thanks. 

Adding an `inline` option to the `highlight` shortcode is good. 

I looked through the code snippets you linked but I have no clue how I would implement this. [My best go skill is adding a new test by copy-pasting and modifying an existing one :)].

Thanks for accepting this feature proposal. Hopefully someone can implement this. 

Fix patch:
diff --git a/markup/highlight/config.go b/markup/highlight/config.go
index 1142c5e1147..46ef79071a7 100644
--- a/markup/highlight/config.go
+++ b/markup/highlight/config.go
@@ -72,6 +72,9 @@ type Config struct {
 	// A space separated list of line numbers, e.g. “3-8 10-20”.
 	Hl_Lines string
 
+	// If set, the markup will not be wrapped in any container.
+	Hl_inline bool
+
 	// A parsed and ready to use list of line ranges.
 	HL_lines_parsed [][2]int `json:"-"`
 
diff --git a/markup/highlight/highlight.go b/markup/highlight/highlight.go
index 892cb72eed4..7d108ebe134 100644
--- a/markup/highlight/highlight.go
+++ b/markup/highlight/highlight.go
@@ -75,11 +75,24 @@ func (h chromaHighlighter) Highlight(code, lang string, opts interface{}) (strin
 	}
 	var b strings.Builder
 
-	if _, _, err := highlight(&b, code, lang, nil, cfg); err != nil {
+	low, high, err := highlight(&b, code, lang, nil, cfg)
+
+	if err != nil {
 		return "", err
 	}
 
-	return b.String(), nil
+	if !cfg.Hl_inline {
+		return b.String(), nil
+	}
+
+	hr := HightlightResult{
+		highlighted: template.HTML(b.String()),
+		innerLow:    low,
+		innerHigh:   high,
+	}
+
+	return string(hr.Inner()), nil
+
 }
 
 func (h chromaHighlighter) HighlightCodeBlock(ctx hooks.CodeblockContext, opts interface{}) (HightlightResult, error) {
diff --git a/markup/internal/attributes/attributes.go b/markup/internal/attributes/attributes.go
index a20690c4cc6..0351bb54ca1 100644
--- a/markup/internal/attributes/attributes.go
+++ b/markup/internal/attributes/attributes.go
@@ -38,6 +38,7 @@ var chromaHightlightProcessingAttributes = map[string]bool{
 	"nohl":               true,
 	"style":              true,
 	"tabWidth":           true,
+	"hl_inline":          true, // New in 0.94.0.
 }
 
 func init() {


Test patch:
diff --git a/markup/highlight/integration_test.go b/markup/highlight/integration_test.go
new file mode 100644
index 00000000000..93d9a1db0d2
--- /dev/null
+++ b/markup/highlight/integration_test.go
@@ -0,0 +1,53 @@
+// Copyright 2022 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package highlight_test
+
+import (
+	"testing"
+
+	"github.com/gohugoio/hugo/hugolib"
+)
+
+func TestHighlightInline(t *testing.T) {
+	t.Parallel()
+
+	files := `
+-- config.toml --
+[markup]
+[markup.highlight]
+codeFences = true
+noClasses = false
+-- content/p1.md --
+---
+title: "p1"
+---
+
+Inline:{{< highlight emacs "hl_inline=true" >}}(message "this highlight shortcode"){{< /highlight >}}:End.
+
+-- layouts/_default/single.html --
+{{ .Content }}
+`
+
+	b := hugolib.NewIntegrationTestBuilder(
+		hugolib.IntegrationTestConfig{
+			T:           t,
+			TxtarString: files,
+			NeedsOsFS:   false,
+		},
+	).Build()
+
+	b.AssertFileContent("public/p1/index.html", `
+	<p>Inline:<span class="line"><span class="cl"><span class="p">(</span><span class="nf">message</span> <span class="s">&#34;this highlight shortcode&#34;</span><span class="p">)</span></span></span>:End.</p>
+	`)
+}