HUGO Relearn Theme Customization

relearn-banner

The number of Themes has been increased rapidly over time and since the very beginning of HUGO - a static web site generator.

The HUGO Relearn theme has one outstanding feature as it fully supports file mode, which means that there is no web server required to get access to the web site content.

Once a site has been generated, it is only required to double click on the main <my-user-directory>\public\index.html file. All dependent files are served from the file system via the file:// protocol which is supported by all modern browsers. Dependencies are relative to the main root and so there is also no problem with CORS policy whatsoever.

When rendering a site, the BaseUrl which usually is the web server address name (like https://johann-oberdorfer.eu) is replaced by ./ and all articles are represented by a trailing index.html so that there is no name resolving needed (which usually is done by a web server). For all urls used in the all the html files, etc… relative notation is used.

Beside other great features, for me this was one of the main reasons for choosing this theme (to build a local documentation system).

Use cases

The theme claims to be a “documentation” theme. In this respect it fits perfectly to build a personal or in-house documentation system (intranet) for small business.

Advantages:

  • personal/company information is pure text and thus future prove, can be stored locally

  • markdown editing (no proprietary data and software required)

  • file structure in the content directory is used to build up the site navigation menu, a really nice feature most useful for documentations etc,…

  • build in search functionality

  • text and layout is separated (except the shortcodes - embedded in markdown)

  • once installed, easily maintainable (and expandable if wanted)

  • attachments of existing PDF’s can be done quite easy,

  • print capability to print one article, chapters or even the whole site articles at once

Overall, a modern way to edit, manage and present information.

Start Batch file

The following batch file can be used under windows to start the actual web site. During web development and also while editing articles, I always wanted to have something simple to take away repetitive tasks.

Web site development usually takes place locally by using HUGO’s integrated web server.

Another possibility - which is fully supported by the Relearn theme - is to use the web site completely independent of any web server in file mode only!

In fact, when developing a site, both modes need to be maintained. My solution in such a scenario is to use the batch file to get up and running.

The batch file takes care of some of the basic command line arguments when starting the HUGO executable for various purposes.

Source code...

@echo off
color F0

rem -----------------------------------------------------------------------------
rem --- Start-Documentation.bat
rem -----------------------------------------------------------------------------
rem (c) 2023, Johann Oberdorfer - Engineering Support | CAD | Software
rem     johann.oberdorfer [at] gmail [dot] com
rem     www.johann-oberdorfer.eu
rem -----------------------------------------------------------------------------
rem This source file is distributed under the BSD license.
rem   This program is distributed in the hope that it will be useful,
rem   but WITHOUT ANY WARRANTY; without even the implied warranty of
rem   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
rem   See the BSD License for more details.
rem -----------------------------------------------------------------------------
rem Revision history:
rem 2023-09-21 J.Oberdorfer, Initial Release
rem -----------------------------------------------------------------------------
rem
rem Problems encountered:
rem WARN 2023/09/19 20:02:40 "_index.md":
rem   DEPRECATED usage of old 'home' archetype found,
rem   add 'archetype="home"' to your frontmatter and remove the leading h1 heading; see
rem   https://mcshelby.github.io/hugo-theme-relearn/basics/migration/#500
rem Documentation:
rem   https://mcshelby.github.io/hugo-theme-relearn/basics/migration/index.html
rem -----------------------------------------------------------------------------

echo.
echo ------------------------------
echo - Documentation Start Script -
echo ------------------------------
echo.

set CDIR=%CD%
set HUGO=".\themes\hugo.exe"
set DESTINATION=.\Documentation-Public
set DOCUDESTINATION=..\Documentation-Public-RELEARN-Theme

set BROWSER1="C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
set BROWSER2="C:\Program Files\Google\Chrome\Application\chrome.exe"

if exist %BROWSER1% (
	set BROWSER=%BROWSER1%
) else (
	if exist %BROWSER2% (
		set BROWSER=%BROWSER2%
	) else (
		echo.
		echo -------------------------------------------
		echo Error: BROWSER variable for Chrome not set!
		echo -------------------------------------------
		echo   Edit configuration in file:
		echo   %0%
		echo   and try again.
		echo -------------------------------------------
		echo.
		goto END1
	)
)

:SelectionMenu

echo.
echo Available Options
echo =================
echo.
echo.
echo [0] : Delete running Web Server Process (if any...)
echo.
echo     For Editing:
echo     ------------
echo     :
echo [1] : Start or Restart Website Server (LIVE DEVELOPMENT)
echo     : Use this for site editing, open a markdown file in the content directory,
echo     : content will be life updated in the browser once a change is safed in the editor!
echo     : Named Web server process already running will be automatically terminated.
echo     :
echo [2] : Compile Website (STANDALONE, NO SERVER REQUIRED)
echo     : After compilation, just open the file: %CDIR%\%DESTINATION%\index.html
echo.
echo     For Viewing:
echo     ------------
echo     : Prefered - use one of the following option to browse through the website.
echo     : Note that the website is serverless, standalone and fully accessable
echo     : via the file:// protocol. The powerful search engine is also supported in this mode.
echo     :
echo [3] : CHROME - Compile and Start Website (STATIC MODE)
echo [4] : EDGE   - Compile and Start Website (STATIC MODE)
echo.
echo     Extras:
echo     -------
echo     :
echo [X] : Generate internal Website Docu (THE RELEARN HUGO THEME)
echo     : After generation, open the file: %CDIR%\%DOCUDESTINATION%\index.html
echo     : to load the internal documentation which describes all available
echo     : configuration options and shortcodes for managing the content.
echo     :
echo [Y] : Open the 'RELEARN Theme Documentation' directly with Chrome ...
echo.
echo.
echo [Q] Quit
echo.
echo =================
echo.

set usr=0
set /p usr="Please choose an option: "

if %usr%==0 goto Option0
if %usr%==1 goto Option1
if %usr%==2 goto Option2
if %usr%==3 goto Option3
if %usr%==4 goto Option4
if %usr%==x goto OptionX
if %usr%==X goto OptionX
if %usr%==y goto OptionY
if %usr%==Y goto OptionY
if %usr%==q goto END1
if %usr%==Q goto END1

cls & goto SelectionMenu

:Option0

for /f "tokens=2 delims=," %%a in ('
    tasklist /fi "imagename eq cmd.exe" /v /fo:csv /nh 
    ^| findstr -i  "Local-Web-Server"
') do taskkill /pid %%a

echo.
echo Web server processes cleanup done.
echo.

goto SelectionMenu

:Option1
cls

echo.
echo --------------------------------
echo 'Start Website Server' selected.
echo --------------------------------
echo.
echo Leave this window open during development.
echo Closing this window means that the development server process will be terminated.
echo.
echo Server is up and running,
echo please stand by, you browser (CHROME) will be continuously live-updated...
echo.
echo.

echo.
echo Attempt to delete any existing named web server process...
echo.

rem for /f "tokens=2" %%a in (`tasklist /v ^| findstr -i  "Local-Web-Server"`) do ...
rem https://stackoverflow.com/questions/26552368/
rem   windows-batch-file-taskkill-if-window-title-contains-text

for /f "tokens=2 delims=," %%a in ('
    tasklist /fi "imagename eq cmd.exe" /v /fo:csv /nh 
    ^| findstr -i  "Local-Web-Server"
') do taskkill /pid %%a

echo.
echo Web server processes cleanup done.
echo.

rem 1.) Required to run the browser *before hugo**.
rem     Seems that the browser automatically runs in background mode...

SET URL=" http:\\localhost:1313"
rem -disabled, previously used-
rem start /b %BROWSER% %URL%

start "" %BROWSER% %URL%
timeout 2 > NUL

rem 2.) execute hugo
rem     hugo does not want to run in background mode,
rem     that's why, we have to run hugo at the very end...

echo.
echo Executing:
echo %HUGO% --logLevel info --disableFastRender--cleanDestinationDir --noBuildLock --destination %DESTINATION% --watch server
echo.

rem start cmd /k ...
start /min "Local-Web-Server" cmd /c %HUGO% ^
	--logLevel info --disableFastRender --cleanDestinationDir --noBuildLock ^
	--destination %DESTINATION% --watch server

goto SelectionMenu


:Option2
cls

echo.
echo ---------------------------
echo 'Compile Website' selected.
echo ---------------------------
echo.

%HUGO% --logLevel info --cleanDestinationDir --noBuildLock --minify --destination "%DESTINATION%"

goto SelectionMenu

:Option3
cls

echo.
echo -------------------------------------
echo 'Compile and Start Website' selected.
echo -------------------------------------
echo.

set CDIR=%CD%
set URL="file://%CDIR%/%DESTINATION%/index.html"

rem --buildDrafts
rem --baseURL "/"
rem --forceSyncStatic

%HUGO% --logLevel info --cleanDestinationDir --noBuildLock --minify --destination "%DESTINATION%"
start "" %BROWSER% %URL%
rem start msedge %URL%

goto SelectionMenu

:Option4
cls

echo.
echo -------------------------------------
echo 'Compile and Start Website' selected.
echo -------------------------------------
echo.

set CDIR=%CD%
set URL="file://%CDIR%/%DESTINATION%/index.html"

%HUGO% --logLevel info --cleanDestinationDir --noBuildLock --minify --destination %DESTINATION%
start msedge %URL%

goto END

:OptionX
cls

echo.
echo ------------------------------------------
echo 'Generate internal Website Docu' selected.
echo ------------------------------------------
echo.

rem note:
rem   the command line option for '--contentDir' will be superseded
rem   by the 'module mount' declaration rem in the config.yaml file, so we have to
rem   delete the module mount so that the following command will work...

set DOCUCONTENT="themes/hugo-theme-relearn-main/exampleSite/content"

%HUGO% ^
	--logLevel info ^
	--cleanDestinationDir --noBuildLock --minify ^
	--contentDir "%DOCUCONTENT%" ^
	--destination "%DOCUDESTINATION%"

goto END

:OptionY
cls

echo.
echo ------------------------------------------------
echo 'Open the RELEARN Theme Documentation' selected.
echo ------------------------------------------------
echo.

set URL="https://mcshelby.github.io/hugo-theme-relearn/basics/migration/index.html"
start "" %BROWSER% %URL%
rem start msedge %URL%

Goto SelectionMenu

:END

echo.
echo -----------------
echo Command finished.
echo -----------------
echo.
pause

goto SelectionMenu

:END1

echo.
echo ---------
echo Done now.
echo ---------
echo.

Theme customizations

To make the theme even more useful I added some more functionality to it.

Functions added:

  • categories & tags cloud

    shortcode/tag_cloud.html...

    {{/*
    	--- shortcode/widgets/tag_cloud.html
    	Credits:
    		This code was inspired by the academic theme.
    		Thanks to: George Cushen
    	Purpose:
    		This function does not take any arguments into account.
    		Read all "tags" and "categories" from the site's taxonomies
    		and create a test cloud which can be used to navigate the site.
    	
    	(c) 2020, Johann Oberdorfer - Engineering Support | CAD | Software
    		www.johann-oberdorfer.eu
    	This source file is distributed under the MIT license.
    	This program is distributed in the hope that it will be useful,
    	but WITHOUT ANY WARRANTY; without even the implied warranty of
    	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    	See the MIT License for more details.
    */}}
    
    {{ $read_tags := true }}
    
    {{ $fontSmall := .Page.Params.design.font_size_min | default 0.9 }}
    {{ $fontBig := .Page.Params.design.font_size_max | default 1.5 }}
    {{ $fontDelta := sub $fontBig $fontSmall }}
    
    {{/* read "categories"... */}}
    {{ $data := .Site.Taxonomies.categories.ByCount }}
    
    {{/* read "tags"
         and add this information to the data array... */}}
    
    {{ if $read_tags }}
    
    	{{ $tags := .Site.Taxonomies.tags.ByCount }}
    
    	{{ if ne (len $tags) 0 }}
    		{{ $data = $data | append $tags }}
    	{{ end }}
    
    {{ end }}
    
    {{/* output goes here... */}}
    
    {{ if ne (len $data) 0 }}
    	<style>
    		.tag-cloud-tags {
    			display: block;
    			margin: 0;
    			list-style-type: none;
    		}
    		.tag-cloud-tags a {
    			display: inline-block;
    			padding: 0.3rem 0.3rem 0rem 0.3rem;
    			line-height: 1em;
    			word-break: break-word;
    			white-space: normal;
    			text-decoration: none;
    			border-bottom: 1px solid LightGrey;
    		}
    		.tag-cloud-tags a:nth-child(5n+1) { transform: rotate(-2deg); }
    		.tag-cloud-tags a:nth-child(3n+3) { transform: rotate(1deg); }
    		.tag-cloud-tags a:nth-child(3n+4) { transform: rotate(-3deg); }
    		.tag-cloud-tags a:nth-child(5n+5) { transform: rotate(3deg); }
    
    		/* underline animation from left */
    
    		.hover-animate-from-left {
    		  display: inline-block;
    		  vertical-align: middle;
    		  -webkit-transform: perspective(1px) translateZ(0);
    		  transform: perspective(1px) translateZ(0);
    		  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
    		  position: relative;
    		  overflow: hidden;
    		}
    		
    		.hover-animate-from-left:before {
    		  content: "";
    		  position: absolute;
    		  z-index: -1;
    		  left: 0;
    		  right: 100%;
    		  bottom: -1px;
    		  background: #2098D1;
    		  height: 3px;
    		  -webkit-transition-property: right;
    		  transition-property: right;
    		  -webkit-transition-duration: 0.8s;
    		  transition-duration: 0.8s;
    		  -webkit-transition-timing-function: ease-out;
    		  transition-timing-function: ease-out;
    		}
    
    		.hover-animate-from-left:hover:before,
    		.hover-animate-from-left:focus:before,
    		.hover-animate-from-left:active:before {
    		  right: 0;
    		}
    	</style>
    
    	{{/* Warning:
    			Hugo's `Reverse` function appears to operate in-place,
    			hence the order of performing $max/$min matters.
    	*/}}
    
    	{{ $max := add (len (index $data 0).Pages) 1 }}
    	{{ $min := len (index ($data).Reverse 0).Pages }}
    	{{ $delta := sub $max $min }}
    	{{ $fontStep := div $fontDelta $delta }}
    
    	<div class="row" style="padding:5px"> <!-- background-color:HoneyDew; -->
    	<div class="heading text-center" style="margin-top:5px">
    
    	<div> <!-- class="col-12 text-center" -->
    
    		<!-- <span>Categories & Tags</span> -->
    
    		<div class="tag-cloud-tags">
    		{{ range $item := (sort $data ".Page.Title" "asc") }}
    
    			{{ $tagCount := len $item.Pages }}
    			{{ $weight := div (sub (math.Log $tagCount) (math.Log $min)) (sub (math.Log $max) (math.Log $min)) }}
    			{{ $fontSize := add $fontSmall (mul (sub $fontBig $fontSmall) $weight) }}
    
    			<!-- class="button button-border button-mini button-border-thin button-blue button-circle" -->
    
    			<!--
    			.Page.RelPermalink changed to
    			partial "relLangPrettyUglyURL.hugo" (dict "to" .Page)
    			-->
    			{{ if ne (upper .Page.Title) "ARCHIVED" }}
    				<a 	href='{{ partial "relLangPrettyUglyURL.hugo" (dict "to" .Page) }}'
    					style="font-size:{{ $fontSize }}rem" class="hover-animate-from-left">
    					{{- .Page.Title | upper -}}
    					<span style="color: LightGrey; font-size:{{ $fontSmall }}rem"> ({{ $tagCount }}) </span>
    				</a>
    			{{ end }}
    
    		{{ end }}
    		</div>
    
    	</div>
    	</div>
    	</div>
    {{ end }}
    
  • columns shortcode

    shortcodes/columns.html...

    <style>
    .flex{display:flex}
    .flex-auto{flex:auto}
    .flex-even{flex:1 1}
    .flex-wrap{flex-wrap:wrap}
    .book-columns>div{margin:1rem 0;min-width:10rem;padding:0 1rem}
    .markdown-inner>:first-child{margin-top:0}
    .markdown-inner>:last-child{margin-bottom:0}
    </style>
    
    <div class="book-columns flex flex-wrap">
    {{ range split .Inner "<--->" }}
      <div class="flex-even markdown-inner">
        {{ . | $.Page.RenderString }}
      </div>
    {{ end }}
    </div>
    
  • support for custom.css

    partials/custom-header.html...

    <!--
    <style>
      #body img.bg-white {background-color: white;}
    </style>
    -->
    
    {{- $assetBusting := not .Site.Params.disableAssetsBusting }}
    <link href='{{"css/custom.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}' rel="stylesheet">
    
  • footer bar with previous and next article

    partials/custom-comments.html...

    <style>
    .bottom-container {
        height:45px;
        clear:both;
        position:absolute;
        bottom:0;
        width:100%;
    	color:var(--MENU-SECTIONS-LINK-color);
    	background-color:var(--MENU-SECTION-ACTIVE-CATEGORY-BG-color);
    	/* test: background-color:green; */
    }
    </style>
    
    {{- if or .PrevInSection .NextInSection }}
    
    	<div class="bottom-container">
    
    	{{- if .NextInSection }}
    
    		{{ $next := .NextInSection.Permalink }}
    
    		<div class="btn cstyle transparent w3-display-left w3-margin-left">
    			<a href='{{ partial "relLangPrettyUglyURL.hugo" (dict "to" .NextInSection) }}'>
    				<i class="fa fa-angle-left"></i>
    				{{- with .NextInSection }}
    					{{ .Title | truncate 30 }}
    				{{- end }}
    			</a>
    		</div>
    	{{- end }}
    
    	{{- if .PrevInSection }}
    	
    		{{ $prev := .PrevInSection.Permalink }}
    	
    		<div class="btn cstyle transparent w3-display-right w3-margin-right">
    			<a href='{{ partial "relLangPrettyUglyURL.hugo"  (dict "to" .PrevInSection) }}'> 
    				{{- with .PrevInSection }}
    					{{ .Title | truncate 30 }}
    				{{- end }}
    				<i class="fa fa-angle-right"></i>
    			</a>
    		</div>
    	{{- end }}
    
    	</div>
    
    {{- end }}
    
    
  • page taxonomy in the header for each article

    content-header.html...

    <style>
    .entry-meta {
    	font-style:italic;
    	font-size:small;
    	display: flex;
    	justify-content: center;
    	margin-top:0px;
    	padding:0px;
    	font-weight:300;
    }
    </style>
    
    {{- if not (eq .Params.archetype "home") }}
    {{- if eq .Params.type "docs" }}
    
    <div class="entry-meta box cstyle transparent w3-animate-fading-mod1">
    
    	<small>
    		<span>
    			<i class="far fa-calendar" style="color:var(--CODE-BLOCK-BORDER-color);"></i>
    			Posted:
    			{{ .Date.Format .Site.Params.date_format }}
    		</span>
    		
    		{{ if ne .Date .Lastmod }}
    			<span>
    				,
    				<i class="far fa-calendar" style="color:var(--CODE-BLOCK-BORDER-color);"></i>
    				Last modified:
    				{{ .Params.lastmod.Format .Site.Params.date_format }}
    			</span>
    		{{ end }}
    
    		{{ if isset .Params "author" }}
    			<span>
    				,
    				<i class="far fa-user-circle" style="color:var(--CODE-BLOCK-BORDER-color);"></i>
    				{{ i18n "author" }}{{ .Params.author }}
    			</span>
    		{{ else }}
    			<span>
    				,
    				<i class="far fa-user-circle" style="color:var(--CODE-BLOCK-BORDER-color);"></i>
    				Admin
    			</span>
    		{{ end }}
    	
    		<!-- hans: copied over from tags.html -->
    		{{- $page := . }}
    		{{- if .Params.categories }}
    		<br/>
    		<span class="categories">
    			{{- $categories := slice | append .Params.categories }}
    			{{- range sort $categories }}
    				{{- if gt (len .) 0 }}
    					{{- $category := . }}
    					{{- with $page.Site.GetPage (printf "%s%s" ("/categories/" | relURL ) ( $category | anchorize ) ) }}
    						{{- $to := . }}
    						<span>
    							<i class="fa fa-tags" style="color:var(--CODE-BLOCK-BORDER-color);"></i>
    							<a href='{{ partial "relLangPrettyUglyURL.hugo" (dict "to" $to) }}'>{{ $category | upper }}</a>
    						</span>
    					{{- end }}
    				{{- end }}
    			{{- end }}
    		</span>
    		{{- end }}
    
    		<!-- hans: copied over from tags.html -->
    		{{- if .Params.tags }}
    		<span class="tags">
    			{{- $tags := slice | append .Params.tags }}
    			{{- range sort $tags }}
    				{{- if gt (len .) 0 }}
    					{{- $tag := . }}
    					{{- with $page.Site.GetPage (printf "%s%s" ("/tags/" | relURL ) ( $tag | anchorize ) ) }}
    						{{- $to := . }}
    						<span>
    							<i class="fa fa-hashtag" style="color:var(--CODE-BLOCK-BORDER-color);"></i>
    							<a href='{{ partial "relLangPrettyUglyURL.hugo" (dict "to" $to) }}'>{{ $tag | upper }}</a>
    						</span>
    					{{- end }}
    				{{- end }}
    			{{- end }}
    		</span>
    		{{- end }}
    
    		<span>
    			,
    			<i class="far fa-clock" style="color:var(--CODE-BLOCK-BORDER-color);"> </i>
    			Time to read:
    			{{ .ReadingTime }} min.
    		</span>
    
    	</small>
    </div>
    
    {{- end }}
    {{- end }}
    
    
  • animated scroll-up “rocket” buttom

    goto_top_rocket.html...

    <!-- scroll to top -->
    <button onclick='topFunction()' id='myBtn' title='Go to top'></button>
    
    <style>
    	#myBtn {
    		display:none;position:fixed;bottom:45px;right:30px;z-index:99;
    		border:2px;outline:none;background-color:HoneyDew;cursor:pointer;padding:15px;
    		border-radius:15px;width:40px;height:40px;	background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABJ0AAASdAHeZh94AAAAB3RJTUUH5wcPDRE1IGQ5vAAABEdJREFUWMPNWc9LMl0YPX5Egos2ThQpUhAk7kwNxJixaNWmbcuCWrd00SIUwj8gBFdta+ULoiC6caJFYEGLQKPciEKDtioT0Tjv4s35mnz7cvxR3wMXnHvvc+fMfc557g8NJDEskySJACDLsmFog5IcSnG73QRAAHS73RzWuEMZJBAIEAAfHh748PBAAAwEAvxfALy9vSUARqNRdiwajRIAb29v+eMAAdDlcvGjLS4u8g+DfhBgKBQiAFar1S6A1WqVABgKhQYCaehXxaVSifPz8xBFEYeHh6jVapp2QRCwv7+Ps7Mz3N/fw2azGb5VxUdHR6pqvypHR0f89hADYDAY5FcWDAYH4mJfToVCgQCYy+W+BJjL5QiAhUKB38bB5eVlNptN5HK5nvp7PB4YjUacn5/r5uE/eh1arRYqlQqWlpY09eFwGH6/H36/H+FwWNO2tLSESqWCVqs1epFks1kC4NPTE0ny7u5OFYMkSXxbjwmAd3d3JMmnpycCYDab5cg5mE6nO6Qn//CDFouFiqKodYqi0GKxdPVLp9OjB7i1tUWz2UyS1JGoaTabub29PXqAdrudGxsbJElRFClJ0qcKliSJoiiSJDc2Nmi323UD1C2SQqEAURR1c10URRQKBYxcxQAwNzcHAFhdXYUsy3h8fOzq8/j4CFmWsbq6qvEZuYoBMJlMashvs9k0PKxWq7TZbBqRJJPJvlaUsX4/6n3I7XY7JicnIUkS3rb8atvffEYSYpLqmcNg+HdBWFhYAEkcHByoX935vbCwoPbr+LyJavghNplMagKOx+PUa/F4XPU3mUwcqoqtVivb7bYapmKxqDtUHR+SaLfbsFqtHEqIY7EYK5UKyuUyAGB6eho3Nze6Ad7c3GBmZgYAUC6XUalUEIvFOHCIAXBvb08N1c7ODgVB0B1iQRC4u7urPu/t7fWk6v9szGQyBMDr62t14JOTE0366NUA8OTkRH2+vr4mAGYyGfYN0OVy0efzaV4kyzIBsF6v9wyuXq8TAGVZ1tT7fL7OiVC/SBqNBhRFgcfj0dQ7HA5MTEwgEon0zL9IJIKJiQk4HI6ujayiKGg0Gvo5eHV1RQDM5/NdM7K+vk6n09nzDDqdTq6vr3fV5/N5AuDV1RV1hziVSn3KtUQiQQAsFotfgisWiwTARCLxKTdTqRR1L3Wd7fnl5SUURdG0zc7OAgCOj4/h9/vRbDb/OobRaEQ2m1V9ksmkpn1qakrzLl0hfp/5R13eVqbh3iy8HYY4OTnZNTMdW1tbw/PzMy4uLvq/L+z3QN1rPgTAX79+8dvvZgwGA3VORF+zONbvzMdiMYyPj8Nms6FWq+Hl5QWCIAAAarUaTCYTBEFAqVRCu93+uSvg98fJlZUVrqys8MPxdKDxxzAEq9frAIDX19euukFtYIBer1fNi+/5PDs7C6/XOzDAgdLMR9vc3CQAnJ6eDu1viN9K6g7T3mN8QAAAAABJRU5ErkJggg),no-repeat;
    	}
    	#myBtn:hover {
    		background-color: var(--INTERNAL-MENU-SECTIONS-LINK-HOVER-color);
    	}
    </style>
    
    <script type="text/javascript">
    
    	let mybutton = document.getElementById('myBtn');
    	let elmnt = document.getElementById("R-body-inner");
    	elmnt.style.scrollBehavior = 'smooth';
    
    	function scrollFunction() {
    		// probably deactivated/overwritten by perfect-scrollbar.js:
    		// document.body.scrollTop, document.documentElement.scrollTop
    		// let y = elmnt.scrollTop;
    		// console.log(y);
    
    		if (elmnt.scrollTop > 20 ) {
    			mybutton.style.display = 'block';
    		} else {
    			mybutton.style.display = 'none';
    		}
    	}
    	function topFunction() {
    		elmnt.scrollTop = 0; // for Safari
    		// document.documentElement.scrollTop = 0; // for Chrome, Firefox, IE and Opera
    	}
    	
    	// window.onscroll = function() {scrollFunction()};
    	// the following works:
    	window.addEventListener('scroll', function() {
    		scrollFunction();
    	}, true);
    
    </script>
    <!-- scroll to top -->
    

    The shortcode goes here:

    body.html...

    {{- partial "goto_top_rocket.html" . }}
    
    {{- $page := .page }}
    {{- $content := .content }}
    {{- $outputFormat := partial "output-format.hugo" .page }}
    {{- partial "single-article.hugo" (dict "page" $page "content" $content "outputFormat" $outputFormat) }}
    
  • custom.css support with some more font size adjustments

    custom.css...

    /* Hans:
    	partly copied from the theme ksu-cs-textbooks-hugo-theme-relearn-main
    	to override css properties declared in theme.css
    */
    .brown {
    	color:Brown;
    	font-weight:bold;
    }
    .lbrown {
    	color:Bisque;
    	font-weight:bold;
    	text-shadow:0px 0px 4px #000000;
    }
    .lred {
    	color:Crimson;
    	font-weight:bold;
    }
    .yellow {
    	color:Yellow;
    	font-weight:bold;
    	text-shadow:0px 0px 4px #000000;
    }
    
    table {
    	/* width:auto;
    	  height:auto; */
    	line-height:12px;
    }
    
    .w3-display-container{position:relative;}
    .w3-top,.w3-bottom{position:fixed;width:100%;z-index:1}.w3-top{top:0}.w3-bottom{bottom:0}
    .w3-display-container:hover .w3-display-hover{display:block}.w3-display-container:hover span.w3-display-hover{display:inline-block}.w3-display-hover{display:none}
    .w3-display-left{position:absolute;top:50%;left:0%;transform:translate(0%,-50%);-ms-transform:translate(-0%,-50%)}
    .w3-display-right{position:absolute;top:50%;right:0%;transform:translate(0%,-50%);-ms-transform:translate(0%,-50%)}
    .w3-margin-left{margin-left:16px!important}.w3-margin-right{margin-right:16px!important}
    .w3-display-position{position:absolute}
    .w3-center .w3-bar{display:inline-block;width:auto}
    .w3-animate-zoom {animation:animatezoom 0.6s}@keyframes animatezoom{from{transform:scale(0)} to{transform:scale(1)}}
    .w3-opacity,.w3-hover-opacity:hover{opacity:0.60}.w3-opacity-off,.w3-hover-opacity-off:hover{opacity:1}
    .w3-opacity-max{opacity:0.25}.w3-opacity-min{opacity:0.75}
    .w3-padding-16{padding-top:16px!important;padding-bottom:16px!important}
    .w3-padding-24{padding-top:24px!important;padding-bottom:24px!important}
    .w3-padding-32{padding-top:32px!important;padding-bottom:32px!important}
    .w3-padding-48{padding-top:48px!important;padding-bottom:48px!important}
    
    .w3-animate-fading-mod {
    	animation:fading 4s linear
    }
    @keyframes fading {
    	0%{opacity:0}
    	25%{opacity:0.25}
    	50%{opacity:0.5}
    	75%{opacity:0.75}
    	100%{opacity:1}
    }
    
    .w3-animate-fading-mod1 {
    	animation:fading1 1s linear
    }
    @keyframes fading1 {
    	0%{opacity:0}
    	50%{opacity:0.5}
    	100%{opacity:1}
    }
    
    /*
    	-------------------
    	theme.css overrides
    	-------------------
    */
    
    /* EMBED page should be 100% width */
    .embed {
        width: 100%;
    }
    
    /* Fix Font Weights for Lato */
    body {
        font-size: 1.1rem; /* --- 1.015625rem; --- */
        font-weight: 400;
        line-height: 1.2; /* --- 1.574; --- */
    }
    
    h1 {
        font-size: 1.85rem; /* --- 3.25rem; --- */
    }
    
    h2 {
        font-size: 1.8rem; /* --- 2.2rem; --- */
        font-weight: 500;
    }
    
    h3, .article-subheading {
        font-size: 1.5rem; /* --- 1.8rem; --- */
        font-weight: 500;
    }
    
    #R-body h2 {
        font-weight: 700;
        font-size: 1.5rem;
    }
    #R-body h3 {
        font-weight: 600;
        font-size: 1.3rem;
    }
    #R-body h4 {
        font-weight: 600;
        font-size: 1.3rem;
    }
    
    #R-sidebar {
        font-size: .953125rem; /* --- .953125rem; --- */
        line-height: 1.2; /* 1.574; */
    }
    #R-sidebar ul li {
        line-height: 1.0;
    }
    #R-sidebar ul.collapsible-menu li.active > a {
        border-inline-end-color: var(--INTERNAL-MENU-BORDER-color);
    }
    #R-sidebar ul.collapsible-menu > li > label {
        margin-left: 2px;
    }
    
    /* Sidebar Titles */
    #R-sidebar ul.topics > li > a b {
        font-weight: 400;
        opacity: 0.5;
        line-height: 1;
    }
    
    #R-body .flex-block-wrapper {
    	/*
        margin-left: auto;
        margin-right: auto;
    	*/
    
        max-width: /* calc( 81.25rem - 18.75rem - 2 * 3.25rem ); */
    				  calc( 88.25rem - 18.75rem - 2 * 1.25rem );
    }
    
    
    /* we limit width if we have large screens */
    @media screen and ( min-width: 88.25rem ){ /* #R-sidebar/width + ./max-width */
        #R-body .flex-block-wrapper {
            width: calc( 88.25rem - var(--INTERNAL-MENU-WIDTH-L) - 2 * 3.25rem );
        }
        body:not(.print) #R-body .narrow .flex-block-wrapper {
            width: calc( 88.25rem - var(--INTERNAL-MENU-WIDTH-L) - 2 * 9.75rem );
        }
    }
    
    
  • full page view for easier reading (temporary removes the menu)

    ….

Credits: