Skip to content

Commit a1ba0a4

Browse files
committed
add spe
1 parent 8203324 commit a1ba0a4

File tree

8 files changed

+550
-0
lines changed

8 files changed

+550
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<pre class="mermaid">
2+
{{- .Inner }}
3+
</pre>
4+
{{ .Page.Store.Set "hasMermaid" true }}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<!-- Prism Render Hook -->
2+
{{ if eq .Page.Site.Params.docs.prism true }}
3+
{{- $attributes := .Attributes }}
4+
{{- $ordinal := .Ordinal }}
5+
6+
<!-- Create SHA1 Hash of Code Block-->
7+
{{ $innerRemoveLB := replaceRE "\r\n?|\n" "" .Inner | string }}
8+
{{ $innerHash := substr (sha1 (printf "%s%s" $innerRemoveLB $ordinal)) 0 7 }}
9+
10+
{{- $classes := slice (printf "language-%s" .Type) .Attributes.class }}
11+
12+
<!-- Options List -->
13+
{{- $options := .Options }}
14+
{{ $optionslist := newScratch }}
15+
{{ range $k, $v := $options }}
16+
{{ $optionslist.Add "options" (printf " %s" $k) }}
17+
{{ end }}
18+
{{ $optionsclasslist := $optionslist.Get "options" }}
19+
20+
<!-- Line Number Highlight -->
21+
{{- if isset .Options "hl_lines" }}
22+
{{ $lines := .Options.hl_lines }}
23+
24+
{{ $offset := 0 }}
25+
{{- if isset .Options "linenostart" }}
26+
{{ $offset = .Options.linenostart }}
27+
{{ else }}
28+
{{ $offset = 1 }}
29+
{{ end }}
30+
31+
{{ $data := newScratch }}
32+
{{ range $value := $lines }}
33+
{{ $value = uniq $value }}
34+
{{ if lt (len $value) 2 }}
35+
{{ $value = slice (add $offset (index $value 0)) }}
36+
{{ else }}
37+
{{ $value = slice (delimit (slice (add $offset (index $value 0)) (add $offset (index $value 1))) "-") }}
38+
{{ end }}
39+
{{ $data.Add "lines" $value }}
40+
{{ end }}
41+
{{ $lines = delimit ($data.Get "lines") "," }}
42+
43+
{{- $attributes = merge $attributes (dict "data-line" $lines) }}
44+
45+
<!-- https://github.com/PrismJS/prism/issues/2714 -->
46+
{{- if and (isset .Options "linenos") (ne .Options.linenos false) }}
47+
{{- $attributes = merge $attributes (dict "data-line-offset" (string $offset)) }}
48+
{{ else }}
49+
{{- $attributes = merge $attributes (dict "data-line-offset" (string (sub $offset 1))) }}
50+
{{ end }}
51+
52+
{{ end -}}
53+
54+
<!-- Line Numbers -->
55+
{{- if and (isset .Options "linenos") (ne .Options.linenos false) }}
56+
{{- $classes = $classes | append "line-numbers" }} <!-- https://discourse.gohugo.io/t/scope-issue-inside-conditional-block-i-think/29273/4 -->
57+
{{ end -}}
58+
59+
<!-- Line Number Start -->
60+
{{- if isset .Options "linenostart" }}
61+
{{- $attributes = merge $attributes (dict "data-start" (string .Options.linenostart)) }}
62+
{{ end -}}
63+
64+
<!-- Linkable Line Numbers -->
65+
{{- if and (isset .Options "anchorlinenos") (ne .Options.anchorlinenos false) }}
66+
{{- $classes = $classes | append "linkable-line-numbers" }}
67+
{{ end -}}
68+
69+
{{- $attributes = merge $attributes (dict "class" (delimit $classes " ")) }}
70+
71+
<div class="prism-codeblock {{ $optionsclasslist }}">
72+
<pre id="{{ $innerHash }}"
73+
{{- range $k, $v := $attributes }}
74+
{{- printf " %s=%q" $k $v | safeHTMLAttr }}
75+
{{- end -}}
76+
>
77+
<code>
78+
{{- .Inner -}}
79+
</code>
80+
</pre>
81+
</div>
82+
{{ else }}
83+
{{ $result := transform.HighlightCodeBlock . }}
84+
{{ $result.Wrapped }}
85+
{{ end }}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h{{ .Level }} id="{{ .Anchor | safeURL }}">{{ .Text | safeHTML }} <a href="#{{ .Anchor | safeURL }}" class="anchor" aria-hidden="true"><i class="material-icons align-middle">link</i></a></h{{ .Level }}>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{{ $dest := .Destination }}
2+
{{ $text := .PlainText }}
3+
{{ $url := urls.Parse $dest }}
4+
5+
{{ $image := newScratch }}
6+
{{ with $url.Scheme }}
7+
{{ $image.Set "resource" (resources.GetRemote $dest) }}
8+
{{ else }}
9+
{{ $image.Set "resource" (resources.Get $dest) }}
10+
{{ end }}
11+
12+
{{ if .Title }}
13+
<figure>
14+
{{ with ($image.Get "resource") }}
15+
{{ if eq .MediaType.SubType "svg" }}
16+
{{ .Content | safeHTML }}
17+
{{ else }}
18+
<img src="{{ .RelPermalink | safeURL }}" alt="{{ $text }}" width="{{ .Width }}" height="{{ .Height }}" loading="lazy">
19+
{{ end }}
20+
{{ else }}
21+
<img src="{{ .Destination | safeURL }}" alt="{{ $text }}" width="{{ .Width }}" height="{{ .Height }}" loading="lazy">
22+
{{ end }}
23+
<figcaption>{{ .Title | markdownify }}</figcaption>
24+
</figure>
25+
{{ else }}
26+
{{ with ($image.Get "resource") }}
27+
{{ if eq .MediaType.SubType "svg" }}
28+
{{ .Content | safeHTML }}
29+
{{ else }}
30+
<img src="{{ .RelPermalink | safeURL }}" alt="{{ $text }}" width="{{ .Width }}" height="{{ .Height }}" loading="lazy">
31+
{{ end }}
32+
{{ end }}
33+
{{ end }}
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
{{- /* Last modified: 2023-09-04T09:23:04-07:00 */}}
2+
3+
{{- /*
4+
Copyright 2023 Veriphor LLC
5+
6+
Licensed under the Apache License, Version 2.0 (the "License"); you may not
7+
use this file except in compliance with the License. You may obtain a copy of
8+
the License at
9+
10+
https://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14+
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15+
License for the specific language governing permissions and limitations under
16+
the License.
17+
*/}}
18+
19+
{{- /*
20+
This render hook resolves internal destinations by looking for a matching:
21+
22+
1. Content page
23+
2. Page resource (a file in the current page bundle)
24+
3. Section resource (a file in the current section)
25+
4. Global resource (a file in the assets directory)
26+
27+
It skips the section resource lookup if the current page is a leaf bundle.
28+
29+
External destinations are not modified.
30+
31+
You must place global resources in the assets directory. If you have placed
32+
your resources in the static directory, and you are unable or unwilling to move
33+
them, you must mount the static directory to the assets directory by including
34+
both of these entries in your site configuration:
35+
36+
[[module.mounts]]
37+
source = 'assets'
38+
target = 'assets'
39+
40+
[[module.mounts]]
41+
source = 'static'
42+
target = 'assets'
43+
44+
By default, if this render hook is unable to resolve a destination, including a
45+
fragment if present, it passes the destination through without modification. To
46+
emit a warning or error, set the error level in your site configuration:
47+
48+
[params.render_hooks.link]
49+
errorLevel = 'warning' # ignore (default), warning, or error (fails the build)
50+
51+
When you set the error level to warning, and you are in a development
52+
environment, you can visually highlight broken internal links:
53+
54+
[params.render_hooks.link]
55+
errorLevel = 'warning' # ignore (default), warning, or error (fails the build)
56+
highlightBroken = true # true or false (default)
57+
58+
This will add a "broken" class to anchor elements with invalid src attributes.
59+
Add a rule to your CSS targeting the broken links:
60+
61+
a.broken {
62+
background: #ff0;
63+
border: 2px solid #f00;
64+
padding: 0.1em 0.2em;
65+
}
66+
67+
This render hook may be unable to resolve destinations created with the ref and
68+
relref shortcodes. Unless you set the error level to ignore you should not use
69+
either of these shortcodes in conjunction with this render hook.
70+
71+
@context {string} Destination The link destination.
72+
@context {page} Page A reference to the page containing the link.
73+
@context {string} PlainText The link description as plain text.
74+
@context {string} Text The link description.
75+
@context {string} Title The link title.
76+
77+
@returns {template.html}
78+
*/}}
79+
80+
{{- /* Initialize. */}}
81+
{{- $renderHookName := "link" }}
82+
83+
{{- /* Verify minimum required version. */}}
84+
{{- $minHugoVersion := "0.114.0" }}
85+
{{- if lt hugo.Version $minHugoVersion }}
86+
{{- errorf "The %q render hook requires Hugo v%s or later." $renderHookName $minHugoVersion }}
87+
{{- end }}
88+
89+
{{- /* Error level when unable to resolve destination: ignore, warning, or error. */}}
90+
{{- $errorLevel := or site.Params.render_hooks.link.errorLevel "ignore" | lower }}
91+
92+
{{- /* If true, adds "broken" class to broken links. Applicable in development environment when errorLevel is warning. */}}
93+
{{- $highlightBrokenLinks := or site.Params.render_hooks.link.highlightBroken false }}
94+
95+
{{- /* Validate error level. */}}
96+
{{- if not (in (slice "ignore" "warning" "error") $errorLevel) }}
97+
{{- errorf "The %q render hook is misconfigured. The errorLevel %q is invalid. Please check your site configuration." $renderHookName $errorLevel }}
98+
{{- end }}
99+
100+
{{- /* Determine content path for warning and error messages. */}}
101+
{{- $contentPath := "" }}
102+
{{- with .Page.File }}
103+
{{- $contentPath = .Path }}
104+
{{- else }}
105+
{{- $contentPath = .Path }}
106+
{{- end }}
107+
108+
{{- /* Parse destination. */}}
109+
{{- $u := urls.Parse .Destination }}
110+
111+
{{- /* Set common message. */}}
112+
{{- $msg := printf "The %q render hook was unable to resolve the destination %q in %s" $renderHookName $u.String $contentPath }}
113+
114+
{{- /* Set attributes for anchor element. */}}
115+
{{- $attrs := dict "href" $u.String }}
116+
{{- if $u.IsAbs }}
117+
{{- /* Destination is a remote resource. */}}
118+
{{- with .Page.Site.Params.docs.extLinkNewTab | default true }}
119+
{{- $attrs = merge $attrs (dict "rel" "external" "target" "_blank") }}
120+
{{- else }}
121+
{{- $attrs = merge $attrs (dict "rel" "external") }}
122+
{{- end -}}
123+
{{- else }}
124+
{{- with $u.Path }}
125+
{{- with $p := or ($.Page.GetPage .) ($.Page.GetPage (strings.TrimRight "/" .)) }}
126+
{{- /* Destination is a page. */}}
127+
{{- $href := .RelPermalink }}
128+
{{- $tooltipDelay := dict "show" 550 "hide" 300 | jsonify | htmlEscape }}
129+
{{- $pathDesc := .Description }}
130+
{{- $pathTitle := .Title }}
131+
{{- $pathParentSection := .Parent.Title | upper }}
132+
{{- $pathHTML := printf "<a href='%s'><p>%s</p><strong>%s</strong><br>%s</a>" $href $pathParentSection $pathTitle $pathDesc }}
133+
{{- with $u.RawQuery }}
134+
{{- $href = printf "%s?%s" $href . }}
135+
{{- end }}
136+
{{- with $u.Fragment }}
137+
{{- $ctx := dict
138+
"contentPath" $contentPath
139+
"errorLevel" $errorLevel
140+
"page" $p
141+
"parsedURL" $u
142+
"renderHookName" $renderHookName
143+
}}
144+
{{- partial "inline/h-rh-l/validate-fragment.html" $ctx }}
145+
{{- $href = printf "%s#%s" $href . }}
146+
{{- end }}
147+
{{- if eq .Page.Site.Params.docs.intLinkTooltip true }}
148+
{{- $attrs = dict "href" $href "data-bs-toggle" "tooltip" "data-bs-delay" $tooltipDelay "data-bs-html" "true" "data-bs-title" $pathHTML }}
149+
{{- else }}
150+
{{- $attrs = dict "href" $href }}
151+
{{- end -}}
152+
{{- else }}
153+
{{- with $.Page.Resources.Get $u.Path }}
154+
{{- /* Destination is a page resource; drop query and fragment. */}}
155+
{{- $attrs = dict "href" .RelPermalink }}
156+
{{- else }}
157+
{{- with (and (ne $.Page.BundleType "leaf") ($.Page.CurrentSection.Resources.Get $u.Path)) }}
158+
{{- /* Destination is a section resource, and current page is not a leaf bundle. */}}
159+
{{- $attrs = dict "href" .RelPermalink }}
160+
{{- else }}
161+
{{- with resources.Get $u.Path }}
162+
{{- /* Destination is a global resource; drop query and fragment. */}}
163+
{{- $attrs = dict "href" .RelPermalink }}
164+
{{- else }}
165+
{{- if eq $errorLevel "warning" }}
166+
{{- warnf $msg }}
167+
{{- if and $highlightBrokenLinks (eq hugo.Environment "development") }}
168+
{{- $attrs = merge $attrs (dict "class" "broken") }}
169+
{{- end }}
170+
{{- else if eq $errorLevel "error" }}
171+
{{- errorf $msg }}
172+
{{- end }}
173+
{{- end }}
174+
{{- end }}
175+
{{- end }}
176+
{{- end }}
177+
{{- else }}
178+
{{- with $u.Fragment }}
179+
{{- /* Destination is on the same page; prepend relative permalink. */}}
180+
{{- $ctx := dict
181+
"contentPath" $contentPath
182+
"errorLevel" $errorLevel
183+
"page" $.Page
184+
"parsedURL" $u
185+
"renderHookName" $renderHookName
186+
}}
187+
{{- partial "inline/h-rh-l/validate-fragment.html" $ctx }}
188+
{{- $attrs = dict "href" (printf "%s#%s" $.Page.RelPermalink .) }}
189+
{{- else }}
190+
{{- if eq $errorLevel "warning" }}
191+
{{- warnf $msg }}
192+
{{- if and $highlightBrokenLinks (eq hugo.Environment "development") }}
193+
{{- $attrs = merge $attrs (dict "class" "broken") }}
194+
{{- end }}
195+
{{- else if eq $errorLevel "error" }}
196+
{{- errorf $msg }}
197+
{{- end }}
198+
{{- end }}
199+
{{- end }}
200+
{{- end }}
201+
{{- with .Title }}
202+
{{- $attrs = merge $attrs (dict "title" .) }}
203+
{{- end -}}
204+
205+
{{- /* Render anchor element. */ -}}
206+
<a
207+
{{- range $k, $v := $attrs }}
208+
{{- printf " %s=%q" $k $v | safeHTMLAttr }}
209+
{{- end -}}
210+
>{{ .Text | safeHTML }}{{- if $u.IsAbs }}{{ with .Page.Site.Params.docs.extLinkNewTab | default true }}<svg width="16" height="16" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M14 5c-.552 0-1-.448-1-1s.448-1 1-1h6c.552 0 1 .448 1 1v6c0 .552-.448 1-1 1s-1-.448-1-1v-3.586l-7.293 7.293c-.391.39-1.024.39-1.414 0-.391-.391-.391-1.024 0-1.414l7.293-7.293h-3.586zm-9 2c-.552 0-1 .448-1 1v11c0 .552.448 1 1 1h11c.552 0 1-.448 1-1v-4.563c0-.552.448-1 1-1s1 .448 1 1v4.563c0 1.657-1.343 3-3 3h-11c-1.657 0-3-1.343-3-3v-11c0-1.657 1.343-3 3-3h4.563c.552 0 1 .448 1 1s-.448 1-1 1h-4.563z"/></svg>{{ end }}{{ end }}</a>
211+
212+
{{- define "partials/inline/h-rh-l/validate-fragment.html" }}
213+
{{- /*
214+
Validates the fragment portion of a link destination.
215+
216+
@context {string} contentPath The page containing the link.
217+
@context {srting} errorLevel The error level when unable to resolve destination; ignore (default), warning, or error.
218+
@context {page} page The page corresponding to the link destination
219+
@context {struct} parsedURL The link destination parsed by urls.Parse.
220+
@context {string} renderHookName The name of the render hook.
221+
*/}}
222+
223+
{{- /* Initialize. */}}
224+
{{- $contentPath := .contentPath }}
225+
{{- $errorLevel := .errorLevel }}
226+
{{- $p := .page }}
227+
{{- $u := .parsedURL }}
228+
{{- $renderHookName := .renderHookName }}
229+
230+
{{- /* Validate. */}}
231+
{{- with $u.Fragment }}
232+
{{- if $p.Fragments.Identifiers.Contains . }}
233+
{{- if gt ($p.Fragments.Identifiers.Count .) 1 }}
234+
{{- $msg := printf "The %q render hook detected duplicate heading IDs %q in %s" $renderHookName . $contentPath }}
235+
{{- if eq $errorLevel "warning" }}
236+
{{- warnf $msg }}
237+
{{- else if eq $errorLevel "error" }}
238+
{{- errorf $msg }}
239+
{{- end }}
240+
{{- end }}
241+
{{- else }}
242+
{{- /* Determine target path for warning and error message. */}}
243+
{{- $targetPath := "" }}
244+
{{- with $p.File }}
245+
{{- $targetPath = .Path }}
246+
{{- else }}
247+
{{- $targetPath = .Path }}
248+
{{- end }}
249+
{{- /* Set common message. */}}
250+
{{- $msg := printf "The %q render hook was unable to find heading ID %q in %s. See %s" $renderHookName . $targetPath $contentPath }}
251+
{{- if eq $targetPath $contentPath }}
252+
{{- $msg = printf "The %q render hook was unable to find heading ID %q in %s" $renderHookName . $targetPath }}
253+
{{- end }}
254+
{{- /* Throw warning or error. */}}
255+
{{- if eq $errorLevel "warning" }}
256+
{{- warnf $msg }}
257+
{{- else if eq $errorLevel "error" }}
258+
{{- errorf $msg }}
259+
{{- end }}
260+
{{- end }}
261+
{{- end }}
262+
{{- end -}}

0 commit comments

Comments
 (0)