Compare commits
20 Commits
bfeae89ab5
...
donations
| Author | SHA1 | Date | |
|---|---|---|---|
| d5f478b3c6 | |||
| 0f96b93532 | |||
| 5449affbc8 | |||
| 2cf19900db | |||
| efe5d08430 | |||
| 994e9ed8d2 | |||
| 72af5cb7f0 | |||
| 308ee34025 | |||
| 9839befdf1 | |||
| d688df6c92 | |||
| 24eef25984 | |||
| 77ae0be899 | |||
| ca939da28e | |||
| 5d0920cb6d | |||
| d1ea7b5364 | |||
| ebdb986e2a | |||
| 4bb6695c2e | |||
| a6c5a42c1d | |||
| c44c718d06 | |||
| 5e4097453b |
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,3 +1,9 @@
|
||||
[submodule "code/aoc-2020"]
|
||||
path = code/aoc-2020
|
||||
url = https://dev.danilafe.com/Advent-of-Code/AdventOfCode-2020.git
|
||||
[submodule "code/libabacus"]
|
||||
path = code/libabacus
|
||||
url = https://dev.danilafe.com/Experiments/libabacus
|
||||
[submodule "themes/vanilla"]
|
||||
path = themes/vanilla
|
||||
url = https://dev.danilafe.com/Web-Projects/vanilla-hugo.git
|
||||
|
||||
36
assets/scss/donate.scss
Normal file
36
assets/scss/donate.scss
Normal file
@@ -0,0 +1,36 @@
|
||||
@import "../../themes/vanilla/assets/scss/mixins.scss";
|
||||
|
||||
.donation-methods {
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-spacing: 0 0.5rem;
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
|
||||
&:first-child {
|
||||
@include bordered-block;
|
||||
text-align: right;
|
||||
border-right: none;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
@include bordered-block;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
}
|
||||
5
config-gen.toml
Normal file
5
config-gen.toml
Normal file
@@ -0,0 +1,5 @@
|
||||
[params]
|
||||
[params.submoduleLinks]
|
||||
[params.submoduleLinks.aoc2020]
|
||||
url = "https://dev.danilafe.com/Advent-of-Code/AdventOfCode-2020/src/commit/7a8503c3fe1aa7e624e4d8672aa9b56d24b4ba82"
|
||||
path = "aoc-2020"
|
||||
@@ -20,9 +20,3 @@ summaryLength = 20
|
||||
endLevel = 4
|
||||
ordered = false
|
||||
startLevel = 3
|
||||
|
||||
[params]
|
||||
[params.submoduleLinks]
|
||||
[params.submoduleLinks.aoc2020]
|
||||
path = "aoc-2020"
|
||||
url = "https://dev.danilafe.com/Advent-of-Code/AdventOfCode-2020/src/commit/7a8503c3fe1aa7e624e4d8672aa9b56d24b4ba82"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: About
|
||||
---
|
||||
{{< donate_css >}}
|
||||
|
||||
I'm Daniel, a Computer Science student currently working towards my Master's Degree at Oregon State University.
|
||||
Due to my initial interest in calculators and compilers, I got involved in the Programming Language Theory research
|
||||
group, gaining same experience in formal verification, domain specific language, and explainable computing.
|
||||
@@ -8,3 +10,34 @@ group, gaining same experience in formal verification, domain specific language,
|
||||
For work, school, and hobby projects, I use a variety of programming languages, most commonly C/C++,
|
||||
Haskell, [Crystal](https://crystal-lang.org/), and [Elm](https://elm-lang.org/). I also have experience
|
||||
with Java, Python, Haxe, and JavaScript.
|
||||
|
||||
A few notes about me or this site:
|
||||
* __Correctness__: I mostly write technical content. Even though I proofread my articles, there's
|
||||
always a fairly good chance that I'm wrong. You should always use your best judgement when reading
|
||||
anything on this site -- if something seems wrong, it may very well be. I'm far from an expert.
|
||||
* __Schedule__: I do not have a set post schedule. There are many reasons for this:
|
||||
schoolwork, personal life, lack of inspiration. It also takes a _very_ long time for
|
||||
me to write a single article. My article on [polymorphic type checking]({{< relref "/blog/10_compiler_polymorphism.md" >}})
|
||||
is around 8,000 words long; besides writing it, I have to edit it, link up all the code
|
||||
references, and proofread the final result. And of course, I need to write the code and
|
||||
occasionally do some research.
|
||||
* __Design__: I am doing my best to keep this website accessible and easy on the eyes.
|
||||
I'm also doing my best to avoid any and all uses of JavaScript. I used to use a lot of
|
||||
uMatrix, and most of the websites I browsed during this time were broken. Similarly,
|
||||
a lot of websites were unusable on my weaker machines. So, I'm doing my part and
|
||||
making this site usable without any JavaScript, and, as it seems to me, even
|
||||
without any CSS.
|
||||
* __Source code__: This blog is open source, but not on GitHub. Instead,
|
||||
you can find the code on my [Gitea instance](https://dev.danilafe.com/Web-Projects/blog-static).
|
||||
If you use this code for your own site, I would prefer that you don't copy the theme.
|
||||
|
||||
### Donate
|
||||
I don't run ads, nor do I profit from writing anything on here. I have no trouble paying for hosting,
|
||||
and I write my articles voluntarily, for my own enjoyment. However, if you found something particularly
|
||||
helpful on here, and would like to buy me a cup of coffee or help host the site, you can donate using
|
||||
the method(s) below.
|
||||
|
||||
{{< donation_methods >}}
|
||||
{{< donation_method "Bitcoin" "1BbXPZhdzv4xHq5LYhme3xBiUsHw5fmafd" >}}
|
||||
{{< donation_method "Ethereum" "0xd111E49344bEC80570e68EE0A00b87B1EFcb5D56" >}}
|
||||
{{< /donation_methods >}}
|
||||
|
||||
BIN
content/blog/codelines/example.png
Normal file
BIN
content/blog/codelines/example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
268
content/blog/codelines/index.md
Normal file
268
content/blog/codelines/index.md
Normal file
@@ -0,0 +1,268 @@
|
||||
---
|
||||
title: "Pleasant Code Includes with Hugo"
|
||||
date: 2021-01-13T21:31:29-08:00
|
||||
tags: ["Hugo"]
|
||||
---
|
||||
|
||||
Ever since I started [the compiler series]({{< relref "00_compiler_intro.md" >}}),
|
||||
I began to include more and more fragments of code into my blog.
|
||||
I didn't want to be copy-pasting my code between my project
|
||||
and my Markdown files, so I quickly wrote up a Hugo [shortcode](https://gohugo.io/content-management/shortcodes/)
|
||||
to pull in other files in the local directory. I've since improved on this
|
||||
some more, so I thought I'd share what I created with others.
|
||||
|
||||
### Including Entire Files and Lines
|
||||
My needs for snippets were modest at first. For the most part,
|
||||
I had a single code file that I wanted to present, so it was
|
||||
acceptable to plop it in the middle of my post in one piece.
|
||||
The shortcode for that was quite simple:
|
||||
|
||||
```
|
||||
{{ highlight (readFile (printf "code/%s" (.Get 1))) (.Get 0) "" }}
|
||||
```
|
||||
|
||||
This leverages Hugo's built-in [`highlight`](https://gohugo.io/functions/highlight/)
|
||||
function to provide syntax highlighting to the included snippet. Hugo
|
||||
doesn't guess at the language of the code, so you have to manually provide
|
||||
it. Calling this shortcode looks as follows:
|
||||
|
||||
```
|
||||
{{</* codeblock "C++" "compiler/03/type.hpp" */>}}
|
||||
```
|
||||
|
||||
Note that this implicitly adds the `code/` prefix to all
|
||||
the files I include. This is a personal convention: I want
|
||||
all my code to be inside a dedicated directory.
|
||||
|
||||
Of course, including entire files only takes you so far.
|
||||
What if you only need to discuss a small part of your code?
|
||||
Alternaitvely, what if you want to present code piece-by-piece,
|
||||
in the style of literate programming? I quickly ran into the
|
||||
need to do this, for which I wrote another shortcode:
|
||||
|
||||
```
|
||||
{{ $s := (readFile (printf "code/%s" (.Get 1))) }}
|
||||
{{ $t := split $s "\n" }}
|
||||
{{ if not (eq (int (.Get 2)) 1) }}
|
||||
{{ .Scratch.Set "u" (after (sub (int (.Get 2)) 1) $t) }}
|
||||
{{ else }}
|
||||
{{ .Scratch.Set "u" $t }}
|
||||
{{ end }}
|
||||
{{ $v := first (add (sub (int (.Get 3)) (int (.Get 2))) 1) (.Scratch.Get "u") }}
|
||||
{{ if (.Get 4) }}
|
||||
{{ .Scratch.Set "opts" (printf ",%s" (.Get 4)) }}
|
||||
{{ else }}
|
||||
{{ .Scratch.Set "opts" "" }}
|
||||
{{ end }}
|
||||
{{ highlight (delimit $v "\n") (.Get 0) (printf "linenos=table,linenostart=%d%s" (.Get 2) (.Scratch.Get "opts")) }}
|
||||
```
|
||||
|
||||
This shortcode takes a language and a filename as before, but it also takes
|
||||
the numbers of the first and last lines indicating the part of the code that should be included. After
|
||||
splitting the contents of the file into lines, it throws away all lines before and
|
||||
after the window of code that you want to include. It seems to me (from my commit history)
|
||||
that Hugo's [`after`](https://gohugo.io/functions/after/) function (which should behave
|
||||
similarly to Haskell's `drop`) doesn't like to be given an argument of `0`.
|
||||
I had to add a special case for when this would occur, where I simply do not invoke `after` at all.
|
||||
The shortcode can be used as follows:
|
||||
|
||||
```
|
||||
{{</* codelines "C++" "compiler/04/ast.cpp" 19 22 */>}}
|
||||
```
|
||||
|
||||
To support a fuller range of Hugo's functionality, I also added an optional argument that
|
||||
accepts Hugo's Chroma settings. This way, I can do things like highlight certain
|
||||
lines in my code snippet, which is done as follows:
|
||||
|
||||
```
|
||||
{{</* codelines "Idris" "typesafe-interpreter/TypesafeIntrV3.idr" 31 39 "hl_lines=7 8 9" */>}}
|
||||
```
|
||||
|
||||
Note that the `hl_lines` field doesn't seem to work properly with `linenostart`, which means
|
||||
that the highlighted lines are counted from 1 no matter what. This is why in the above snippet,
|
||||
although I include lines 31 through 39, I feed lines 7, 8, and 9 to `hl_lines`. It's unusual,
|
||||
but hey, it works!
|
||||
|
||||
### Linking to Referenced Code
|
||||
Some time after implementing my initial system for including lines of code,
|
||||
I got an email from a reader who pointed out that it was hard for them to find
|
||||
the exact file I was referencing, and to view the surrounding context of the
|
||||
presented lines. To address this, I decided that I'd include the link
|
||||
to the file in question. After all, my website and all the associated
|
||||
code is on a [Git server I host](https://dev.danilafe.com/Web-Projects/blog-static),
|
||||
so any local file I'm referencing should -- assuming it was properly committed --
|
||||
show up there, too. I hardcoded the URL of the `code` directory on the web interface,
|
||||
and appended the relative path of each included file to it. The shortcode came out as follows:
|
||||
|
||||
```
|
||||
{{ $s := (readFile (printf "code/%s" (.Get 1))) }}
|
||||
{{ $t := split $s "\n" }}
|
||||
{{ if not (eq (int (.Get 2)) 1) }}
|
||||
{{ .Scratch.Set "u" (after (sub (int (.Get 2)) 1) $t) }}
|
||||
{{ else }}
|
||||
{{ .Scratch.Set "u" $t }}
|
||||
{{ end }}
|
||||
{{ $v := first (add (sub (int (.Get 3)) (int (.Get 2))) 1) (.Scratch.Get "u") }}
|
||||
{{ if (.Get 4) }}
|
||||
{{ .Scratch.Set "opts" (printf ",%s" (.Get 4)) }}
|
||||
{{ else }}
|
||||
{{ .Scratch.Set "opts" "" }}
|
||||
{{ end }}
|
||||
<div class="highlight-group">
|
||||
<div class="highlight-label">From <a href="https://dev.danilafe.com/Web-Projects/blog-static/src/branch/master/code/{{ .Get 1 }}">{{ path.Base (.Get 1) }}</a>,
|
||||
{{ if eq (.Get 2) (.Get 3) }}line {{ .Get 2 }}{{ else }} lines {{ .Get 2 }} through {{ .Get 3 }}{{ end }}</div>
|
||||
{{ highlight (delimit $v "\n") (.Get 0) (printf "linenos=table,linenostart=%d%s" (.Get 2) (.Scratch.Get "opts")) }}
|
||||
</div>
|
||||
```
|
||||
|
||||
This results in code blocks like the one in the image below. The image
|
||||
is the result of the `codelines` call for the Idris language, presented above.
|
||||
|
||||
{{< figure src="example.png" caption="An example of how the code looks." class="medium" >}}
|
||||
|
||||
I got a lot of mileage out of this setup . . . until I wanted to include code from _other_ git repositories.
|
||||
For instance, I wanted to talk about my [Advent of Code](https://adventofcode.com/) submissions,
|
||||
without having to copy-paste the code into my blog repository!
|
||||
|
||||
### Code from Submodules
|
||||
My first thought when including code from other repositories was to use submodules.
|
||||
This has the added advantage of "pinning" the version of the code I'm talking about,
|
||||
which means that even if I push significant changes to the other repository, the code
|
||||
in my blog will remain the same. This, in turn, means that all of my `codelines`
|
||||
shortcodes will work as intended.
|
||||
|
||||
The problem is, most Git web interfaces (my own included) don't display paths corresponding
|
||||
to submodules. Thus, even if all my code is checked out and Hugo correctly
|
||||
pulls the selected lines into its HTML output, the _links to the file_ remain
|
||||
broken!
|
||||
|
||||
There's no easy way to address this, particularly because _different submodules
|
||||
can be located on different hosts_! The Git URL used for a submodule is
|
||||
not known to Hugo (since, to the best of my knowledge, it can't run
|
||||
shell commands), and it could reside on `dev.danilafe.com`, or `github.com`,
|
||||
or elsewhere. Fortunately, it's fairly easy to tell when a file is part
|
||||
of a submodule, and which submodule that is. It's sufficient to find
|
||||
the longest submodule path that matches the selected file. If no
|
||||
submodule path matches, then the file is part of the blog repository,
|
||||
and no special action is needed.
|
||||
|
||||
Of course, this means that Hugo needs to be made aware of the various
|
||||
submodules in my repository. It also needs to be aware of the submodules
|
||||
_inside_ those submodules, and so on: it needs to be recursive. Git
|
||||
has a command to list all submodules recursively:
|
||||
|
||||
```Bash
|
||||
git submodule status --recursive
|
||||
```
|
||||
|
||||
However, this only prints the commit, submodule path, and the upstream branch.
|
||||
I don't think there's a way to list the remotes' URLs with this command; however,
|
||||
we do _need_ the URLs, since that's how we create links to the Git web interfaces.
|
||||
|
||||
There's another issue: how do we let Hugo know about the various submodules,
|
||||
even if we can find them? Hugo can read files, but doing any serious
|
||||
text processing is downright impractical. However, Hugo
|
||||
itself is not able to run commands, so it needs to be able to read in
|
||||
the output of another command that _can_ find submodules.
|
||||
|
||||
I settled on using Hugo's `params` configuration option. This
|
||||
allows users to communicate arbitrary properties to Hugo themes
|
||||
and templates. In my case, I want to communicate a collection
|
||||
of submodules. I didn't know about TOML's inline tables, so
|
||||
I decided to represent this collection as a map of (meaningless)
|
||||
submodule names to tables:
|
||||
|
||||
```TOML
|
||||
[params]
|
||||
[params.submoduleLinks]
|
||||
[params.submoduleLinks.aoc2020]
|
||||
url = "https://dev.danilafe.com/Advent-of-Code/AdventOfCode-2020/src/commit/7a8503c3fe1aa7e624e4d8672aa9b56d24b4ba82"
|
||||
path = "aoc-2020"
|
||||
```
|
||||
|
||||
Since it was seemingly impossible to wrangle Git into outputting
|
||||
all of this information using one command, I decided
|
||||
to write a quick Ruby script to generate a list of submodules
|
||||
as follows. I had to use `cd` in one of my calls to Git
|
||||
because Git's `--git-dir` option doesn't seem to work
|
||||
with submodules, treating them like a "bare" checkout.
|
||||
I also chose to use an allowlist of remote URLs,
|
||||
since the URL format for linking to files in a
|
||||
particular repository differs from service to service.
|
||||
For now, I only use my own Git server, so only `dev.danilafe.com`
|
||||
is allowed; however, just by adding `elsif`s to my code,
|
||||
I can add other services in the future.
|
||||
|
||||
```Ruby
|
||||
puts "[params]"
|
||||
puts " [params.submoduleLinks]"
|
||||
|
||||
def each_submodule(base_path)
|
||||
`cd #{base_path} && git submodule status`.lines do |line|
|
||||
hash, path = line[1..].split " "
|
||||
full_path = "#{base_path}/#{path}"
|
||||
url = `git config --file #{base_path}/.gitmodules --get 'submodule.#{path}.url'`.chomp.delete_suffix(".git")
|
||||
safe_name = full_path.gsub(/\/|-|_\./, "")
|
||||
|
||||
if url =~ /dev.danilafe.com/
|
||||
file_url = "#{url}/src/commit/#{hash}"
|
||||
else
|
||||
raise "Submodule URL #{url.dump} not in a known format!"
|
||||
end
|
||||
|
||||
yield ({ :path => full_path, :url => file_url, :name => safe_name })
|
||||
each_submodule(full_path) { |m| yield m }
|
||||
end
|
||||
end
|
||||
|
||||
each_submodule(".") do |m|
|
||||
next unless m[:path].start_with? "./code/"
|
||||
puts " [params.submoduleLinks.#{m[:name].delete_prefix(".code")}]"
|
||||
puts " url = #{m[:url].dump}"
|
||||
puts " path = #{m[:path].delete_prefix("./code/").dump}"
|
||||
end
|
||||
```
|
||||
|
||||
I pipe the output of this script into a separate configuration file
|
||||
called `config-gen.toml`, and then run Hugo as follows:
|
||||
|
||||
```
|
||||
hugo --config config.toml,config-gen.toml
|
||||
```
|
||||
|
||||
Finally, I had to modify my shortcode to find and handle the longest submodule prefix.
|
||||
Here's the relevant portion, and you can
|
||||
[view the entire file here](https://dev.danilafe.com/Web-Projects/blog-static/src/commit/bfeae89ab52d1696c4a56768b7f0c6682efaff82/themes/vanilla/layouts/shortcodes/codelines.html).
|
||||
|
||||
```
|
||||
{{ .Scratch.Set "bestLength" -1 }}
|
||||
{{ .Scratch.Set "bestUrl" (printf "https://dev.danilafe.com/Web-Projects/blog-static/src/branch/master/code/%s" (.Get 1)) }}
|
||||
{{ $filePath := (.Get 1) }}
|
||||
{{ $scratch := .Scratch }}
|
||||
{{ range $module, $props := .Site.Params.submoduleLinks }}
|
||||
{{ $path := index $props "path" }}
|
||||
{{ $bestLength := $scratch.Get "bestLength" }}
|
||||
{{ if and (le $bestLength (len $path)) (hasPrefix $filePath $path) }}
|
||||
{{ $scratch.Set "bestLength" (len $path) }}
|
||||
{{ $scratch.Set "bestUrl" (printf "%s%s" (index $props "url") (strings.TrimPrefix $path $filePath)) }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
And that's what I'm using at the time of writing!
|
||||
|
||||
### Conclusion
|
||||
My current system for code includes allows me to do the following
|
||||
things:
|
||||
|
||||
* Include entire files or sections of files into the page. This
|
||||
saves me from having to copy and paste code manually, which
|
||||
is error prone and can cause inconsistencies.
|
||||
* Provide links to the files I reference on my Git interface.
|
||||
This allows users to easily view the entire file that I'm talking about.
|
||||
* Correctly link to files in repositories other than my blog
|
||||
repository, when they are included using submodules. This means
|
||||
I don't need to manually copy and update code from other projects.
|
||||
|
||||
I hope some of these shortcodes and script come in handy for someone else.
|
||||
Thank you for reading!
|
||||
79
content/blog/hugo_functions.md
Normal file
79
content/blog/hugo_functions.md
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
title: "Approximating Custom Functions in Hugo"
|
||||
date: 2021-01-17T18:44:53-08:00
|
||||
tags: ["Hugo"]
|
||||
---
|
||||
|
||||
This will be an uncharacteristically short post. Recently,
|
||||
I wrote about my experience with [including code from local files]({{< relref "codelines" >}}).
|
||||
After I wrote that post, I decided to expand upon my setup. In particular,
|
||||
I wanted to display links to the files I'm referring to, in three
|
||||
different cases: when I'm referring to an entire code file, to an entire raw (non-highlighted)
|
||||
file, or to a portion of a code file.
|
||||
|
||||
The problem was that in all three cases, I needed to determine the
|
||||
correct file URL to link to. The process for doing so is identical: it
|
||||
really only depends on the path to the file I'm including. However,
|
||||
many other aspects of each case are different. In the "entire code file"
|
||||
case, I simply need to read in a file. In the "portion of a code file"
|
||||
case, I have to perform some processing to extract the specific lines I want to include.
|
||||
Whenever I include a code file -- entirely or partially -- I need to invoke the `highlight`
|
||||
function to perform syntax highlighting; however, I don't want to do that when including a raw file.
|
||||
It would be difficult to write a single shortcode or partial to handle all of these different cases.
|
||||
|
||||
However, computing the target URL is a simple transformation
|
||||
of a path and a list of submodules into a link. More plainly,
|
||||
it is a function. Hugo doesn't really have support for
|
||||
custom functions, at least according to this [Discourse post](https://discourse.gohugo.io/t/adding-custom-functions/14164). The only approach to add a _real_ function to Hugo is to edit the Go-based
|
||||
source code, and recompile the thing. However, your own custom functions
|
||||
would then not be included in normal Hugo distributions, and any websites
|
||||
using these functions would not be portable. _Really_ adding your own functions
|
||||
is not viable.
|
||||
|
||||
However, we can approximate functions using Hugo's
|
||||
[scratchpad feature](https://gohugo.io/functions/scratch/)
|
||||
By feeding a
|
||||
{{< sidenote "right" "mutable-note" "scratchpad" >}}
|
||||
In reality, any mutable container will work. The scratchpad
|
||||
just seems like the perfect tool for this purpose.
|
||||
{{< /sidenote >}}
|
||||
to a partial, and expecting the partial to modify the
|
||||
scratchpad in some way, we can effectively recover data.
|
||||
For instance, in my `geturl` partial, I have something like
|
||||
the following:
|
||||
|
||||
```
|
||||
{{ .scratch.Set "bestUrl" theUrl }}
|
||||
```
|
||||
|
||||
Once this partial executes, and the rendering engine is back to its call site,
|
||||
the scratchpad will contain `bestUrl`. To call this partial while providing inputs
|
||||
(like the file path, for example), we can use Hugo's `dict` function. An (abridged)
|
||||
example:
|
||||
|
||||
```
|
||||
{{ partial "geturl.html" (dict "scratch" .Scratch "path" filePath) }}
|
||||
```
|
||||
|
||||
Now, from inside the partial, we'll be able to access the two variable using `.scratch` and `.path`.
|
||||
Once we've called our partial, we simply extract the returned data from the scratchpad and use it:
|
||||
|
||||
```
|
||||
{{ partial "geturl.html" (dict "scratch" .Scratch "path" filePath) }}
|
||||
{{ $bestUrl := .Scratch.Get "bestUrl" }}
|
||||
{{ ... do stuff with $bestUrl ... }}
|
||||
```
|
||||
|
||||
Thus, although it's a little bit tedious, we're able to use `geturl` like a function,
|
||||
thereby refraining from duplicating its definition everywhere the same logic is needed. A few
|
||||
closing thoughts:
|
||||
|
||||
* __Why not just use a real language?__ It's true that I wrote a Ruby script to
|
||||
do some of the work involved with linking submodules. However, generating the same
|
||||
information for all calls to `codelines` would complicate the process of rendering
|
||||
the blog, and make live preview impossible. In general, by limiting the use of external
|
||||
scripts, it's easier to make `hugo` the only "build tool" for the site.
|
||||
* __Is there an easier way?__ I _think_ that calls to `partial` return a string. If you
|
||||
simply wanted to return a string, you could probably do without using a scratchpad.
|
||||
However, if you wanted to do something more complicated (say, return a map or list),
|
||||
you'd probably want the scratchpad method after all.
|
||||
14
content/search.md
Normal file
14
content/search.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
title: Search
|
||||
type: "search"
|
||||
description: Interactive search for posts on Daniel's personal site.
|
||||
---
|
||||
|
||||
Here's a [Stork](https://github.com/jameslittle230/stork)-powered search for all articles on
|
||||
this site. Stork takes some time to load on slower devices, which is why this isn't on
|
||||
every page (or even on the index page). Because the LaTeX rendering occurs _after_
|
||||
the search indexing, you may see raw LaTeX code in the content of the presented
|
||||
articles, like `\beta`. This does, however, also mean that you can search for mathematical
|
||||
symbols using only the English alphabet!
|
||||
|
||||
If you're just browsing, you could alternatively check out [all posts](/blog), or perhaps my [favorite articles](/favorites) from this blog.
|
||||
2
layouts/shortcodes/donate_css.html
Normal file
2
layouts/shortcodes/donate_css.html
Normal file
@@ -0,0 +1,2 @@
|
||||
{{ $style := resources.Get "scss/donate.scss" | resources.ToCSS | resources.Minify }}
|
||||
<link rel="stylesheet" href="{{ $style.Permalink }}">
|
||||
4
layouts/shortcodes/donation_method.html
Normal file
4
layouts/shortcodes/donation_method.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<tr>
|
||||
<td>{{ .Get 0 }}</td>
|
||||
<td><code>{{ .Get 1 }}</code></td>
|
||||
</tr>
|
||||
3
layouts/shortcodes/donation_methods.html
Normal file
3
layouts/shortcodes/donation_methods.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<table class="donation-methods">
|
||||
{{ .Inner }}
|
||||
</table>
|
||||
Binary file not shown.
BIN
static/index.st
Normal file
BIN
static/index.st
Normal file
Binary file not shown.
@@ -1,19 +1,27 @@
|
||||
puts "[params]"
|
||||
puts " [params.submoduleLinks]"
|
||||
|
||||
`git submodule status --recursive`.lines do |line|
|
||||
hash, path = line[1..].split " "
|
||||
next unless path.start_with? "code/"
|
||||
code_path = path.delete_prefix "code/"
|
||||
url = `git config --file .gitmodules --get 'submodule.#{path}.url'`.chomp.delete_suffix(".git")
|
||||
safe_name = code_path.gsub(/\/|-|_/, "")
|
||||
def each_submodule(base_path)
|
||||
`cd #{base_path} && git submodule status`.lines do |line|
|
||||
hash, path = line[1..].split " "
|
||||
full_path = "#{base_path}/#{path}"
|
||||
url = `git config --file #{base_path}/.gitmodules --get 'submodule.#{path}.url'`.chomp.delete_suffix(".git")
|
||||
safe_name = full_path.gsub(/\/|-|_\./, "")
|
||||
|
||||
if url =~ /dev.danilafe.com/
|
||||
file_url = "#{url}/src/commit/#{hash}"
|
||||
else
|
||||
raise "Submodule URL not in a known format!"
|
||||
if url =~ /dev.danilafe.com/
|
||||
file_url = "#{url}/src/commit/#{hash}"
|
||||
else
|
||||
raise "Submodule URL #{url.dump} not in a known format!"
|
||||
end
|
||||
|
||||
yield ({ :path => full_path, :url => file_url, :name => safe_name })
|
||||
each_submodule(full_path) { |m| yield m }
|
||||
end
|
||||
puts " [params.submoduleLinks.#{safe_name}]"
|
||||
puts " path = #{code_path.dump}"
|
||||
puts " url = #{file_url.dump}"
|
||||
end
|
||||
|
||||
each_submodule(".") do |m|
|
||||
next unless m[:path].start_with? "./code/"
|
||||
puts " [params.submoduleLinks.#{m[:name].delete_prefix(".code")}]"
|
||||
puts " url = #{m[:url].dump}"
|
||||
puts " path = #{m[:path].delete_prefix("./code/").dump}"
|
||||
end
|
||||
|
||||
1
themes/vanilla
Submodule
1
themes/vanilla
Submodule
Submodule themes/vanilla added at b56ac908f6
@@ -1,20 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 YOUR_NAME_HERE
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,2 +0,0 @@
|
||||
+++
|
||||
+++
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 376 B |
Binary file not shown.
|
Before Width: | Height: | Size: 536 B |
@@ -1,93 +0,0 @@
|
||||
@import "variables.scss";
|
||||
|
||||
$code-color-lineno: grey;
|
||||
$code-color-keyword: black;
|
||||
$code-color-type: black;
|
||||
$code-color-comment: grey;
|
||||
|
||||
.highlight-label {
|
||||
padding: 0.25rem 0.5rem 0.25rem 0.5rem;
|
||||
border: $code-border;
|
||||
border-bottom: none;
|
||||
|
||||
a {
|
||||
font-family: $font-code;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: $font-code;
|
||||
background-color: $code-color;
|
||||
border: $code-border;
|
||||
padding: 0 0.25rem 0 0.25rem;
|
||||
}
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
padding: 0.5rem;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.chroma {
|
||||
.lntable {
|
||||
border-spacing: 0;
|
||||
padding: 0.5rem 0 0.5rem 0;
|
||||
background-color: $code-color;
|
||||
border-radius: 0;
|
||||
border: $code-border;
|
||||
display: block;
|
||||
overflow: auto;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.lntd:last-child {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.lntr {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.lnt {
|
||||
display: block;
|
||||
padding: 0 1rem 0 1rem;
|
||||
color: $code-color-lineno;
|
||||
}
|
||||
|
||||
.hl {
|
||||
display: block;
|
||||
background-color: #fffd99;
|
||||
|
||||
.lnt::before {
|
||||
content: "*";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.kr, .k {
|
||||
font-weight: bold;
|
||||
color: $code-color-keyword;
|
||||
}
|
||||
|
||||
.kt {
|
||||
font-weight: bold;
|
||||
color: $code-color-type;
|
||||
}
|
||||
|
||||
.c, .c1 {
|
||||
color: $code-color-comment;
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
@import "variables.scss";
|
||||
@import "mixins.scss";
|
||||
|
||||
$margin-width: 30rem;
|
||||
$margin-inner-offset: 0.5rem;
|
||||
$margin-outer-offset: 1rem;
|
||||
|
||||
@mixin below-two-margins {
|
||||
@media screen and
|
||||
(max-width: $container-width-threshold +
|
||||
2 * ($margin-width + $margin-inner-offset + $margin-outer-offset)) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin below-one-margin {
|
||||
@media screen and
|
||||
(max-width: $container-width-threshold +
|
||||
($margin-width + $margin-inner-offset + $margin-outer-offset)) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin margin-content {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: $margin-width;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@mixin margin-content-left {
|
||||
left: 0;
|
||||
margin-left: -($margin-width + $container-min-padding + $margin-inner-offset);
|
||||
|
||||
@include below-two-margins {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin margin-content-right {
|
||||
right: 0;
|
||||
margin-right: -($margin-width + $container-min-padding + $margin-inner-offset);
|
||||
|
||||
@include below-one-margin {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
@import "variables.scss";
|
||||
|
||||
@mixin bordered-block {
|
||||
border: $standard-border;
|
||||
border-radius: .2rem;
|
||||
}
|
||||
|
||||
@mixin below-container-width {
|
||||
@media screen and (max-width: $container-width-threshold){
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
@import "variables.scss";
|
||||
@import "mixins.scss";
|
||||
|
||||
$search-input-padding: 0.5rem;
|
||||
$search-element-padding: 0.5rem 1rem 0.5rem 1rem;
|
||||
|
||||
@mixin green-shadow {
|
||||
box-shadow: 0px 0px 5px rgba($primary-color, 0.7);
|
||||
}
|
||||
|
||||
.stork-wrapper {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.stork-input-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
input.stork-input {
|
||||
@include bordered-block;
|
||||
font-family: $font-body;
|
||||
padding: $search-input-padding;
|
||||
|
||||
&:active, &:focus {
|
||||
@include green-shadow;
|
||||
border-color: $primary-color;
|
||||
}
|
||||
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.stork-close-button {
|
||||
@include bordered-block;
|
||||
font-family: $font-body;
|
||||
padding: $search-input-padding;
|
||||
|
||||
background-color: $code-color;
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
|
||||
border-left: none;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.stork-output-visible {
|
||||
@include bordered-block;
|
||||
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.stork-result, .stork-message, .stork-attribution {
|
||||
padding: $search-element-padding;
|
||||
}
|
||||
|
||||
.stork-message:not(:last-child), .stork-result {
|
||||
border-bottom: $standard-border;
|
||||
}
|
||||
|
||||
.stork-results {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.stork-result {
|
||||
list-style: none;
|
||||
|
||||
&.selected {
|
||||
background-color: $code-color;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
.stork-title, .stork-excerpt {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.stork-excerpt {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.stork-title {
|
||||
font-family: $font-heading;
|
||||
font-size: 1.4rem;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stork-highlight {
|
||||
background-color: lighten($primary-color, 30%);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
@import "variables.scss";
|
||||
@import "mixins.scss";
|
||||
@import "margin.scss";
|
||||
|
||||
$sidenote-padding: 1rem;
|
||||
$sidenote-highlight-border-width: .2rem;
|
||||
|
||||
.sidenote {
|
||||
&:hover {
|
||||
.sidenote-label {
|
||||
background-color: $primary-color;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidenote-content {
|
||||
border: $sidenote-highlight-border-width dashed;
|
||||
padding: $sidenote-padding -
|
||||
($sidenote-highlight-border-width - $standard-border-width);
|
||||
border-color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidenote-label {
|
||||
border-bottom: .2rem dashed $primary-color;
|
||||
}
|
||||
|
||||
.sidenote-checkbox {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidenote-content {
|
||||
@include margin-content;
|
||||
@include bordered-block;
|
||||
margin-top: -1.5rem;
|
||||
padding: $sidenote-padding;
|
||||
text-align: left;
|
||||
|
||||
&.sidenote-right {
|
||||
@include margin-content-right;
|
||||
}
|
||||
|
||||
&.sidenote-left {
|
||||
@include margin-content-left;
|
||||
}
|
||||
}
|
||||
|
||||
.sidenote-delimiter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@mixin hidden-sidenote {
|
||||
position: static;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
width: 100%;
|
||||
|
||||
.sidenote-checkbox:checked ~ & {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@include below-two-margins {
|
||||
.sidenote-content.sidenote-left {
|
||||
@include hidden-sidenote;
|
||||
margin-left: 0rem;
|
||||
}
|
||||
}
|
||||
|
||||
@include below-one-margin {
|
||||
.sidenote-content.sidenote-right {
|
||||
@include hidden-sidenote;
|
||||
margin-right: 0rem;
|
||||
}
|
||||
}
|
||||
@@ -1,265 +0,0 @@
|
||||
@import "variables.scss";
|
||||
@import "mixins.scss";
|
||||
@import "margin.scss";
|
||||
@import "toc.scss";
|
||||
|
||||
body {
|
||||
font-family: $font-body;
|
||||
font-size: 1.0rem;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 1rem;
|
||||
text-align: justify;
|
||||
|
||||
@include below-container-width {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-bottom: .1rem;
|
||||
margin-top: .5rem;
|
||||
font-family: $font-heading;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
|
||||
a {
|
||||
border-bottom: none;
|
||||
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
max-width: $container-width;
|
||||
box-sizing: border-box;
|
||||
|
||||
@include below-container-width {
|
||||
padding: 0 $container-min-padding 0 $container-min-padding;
|
||||
margin: 0;
|
||||
max-width: $container-width + 2 * $container-min-padding;
|
||||
}
|
||||
|
||||
@include below-two-margins {
|
||||
left: -($margin-width + $margin-inner-offset + $margin-outer-offset)/2;
|
||||
}
|
||||
|
||||
@include below-one-margin {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.button, input[type="submit"] {
|
||||
padding: 0.5rem;
|
||||
background-color: $primary-color;
|
||||
border: none;
|
||||
color: white;
|
||||
transition: color 0.25s, background-color 0.25s;
|
||||
text-align: left;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: white;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
width: 100%;
|
||||
margin: 0rem 0rem 1rem 0rem;
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
a {
|
||||
padding: 0.25rem 0.75rem 0.25rem .75rem;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
display: inline-block;
|
||||
border-bottom: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.post-subscript {
|
||||
color: #8f8f8f;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.post-content {
|
||||
margin-top: .5rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.0rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2.6rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1.0rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
border-bottom: .2rem solid $primary-color;
|
||||
transition: color 0.25s;
|
||||
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%
|
||||
}
|
||||
|
||||
table {
|
||||
@include bordered-block;
|
||||
margin: auto;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
tr {
|
||||
@include below-container-width {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
@include below-container-width {
|
||||
overflow-x: auto;
|
||||
}
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
div.highlight tr {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
hr.header-divider {
|
||||
background-color: $primary-color;
|
||||
height: 0.3rem;
|
||||
border: none;
|
||||
border-radius: 0.15rem;
|
||||
}
|
||||
|
||||
hr.footer-divider {
|
||||
margin: auto;
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border: none;
|
||||
border-bottom: $standard-border;
|
||||
max-width: $container-width;
|
||||
|
||||
@include below-container-width {
|
||||
max-width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
ul.post-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
@include bordered-block;
|
||||
margin-bottom: 1rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a.post-title {
|
||||
border-bottom: none;
|
||||
font-size: 1.4rem;
|
||||
font-family: $font-heading;
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
|
||||
p.post-wordcount {
|
||||
text-align: center;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
.katex-html {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
figure {
|
||||
img {
|
||||
max-width: 70%;
|
||||
display: block;
|
||||
margin: auto;
|
||||
|
||||
@include below-container-width {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
figcaption {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.tiny img {
|
||||
max-height: 15rem;
|
||||
}
|
||||
|
||||
&.small img {
|
||||
max-height: 20rem;
|
||||
}
|
||||
|
||||
&.medium img {
|
||||
max-height: 30rem;
|
||||
}
|
||||
}
|
||||
|
||||
.twitter-tweet {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.draft-warning {
|
||||
@include bordered-block;
|
||||
padding: 0.5rem;
|
||||
background-color: #ffee99;
|
||||
border-color: #f5c827;
|
||||
}
|
||||
|
||||
.feather {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
stroke: currentColor;
|
||||
stroke-width: 2;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
fill: currentColor;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
@import "variables.scss";
|
||||
@import "mixins.scss";
|
||||
|
||||
$toc-color: $code-color;
|
||||
$toc-border-color: $code-border-color;
|
||||
|
||||
.table-of-contents {
|
||||
@include margin-content;
|
||||
@include margin-content-left;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
em {
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
#TableOfContents > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
nav {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding-left: 2rem;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
a {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.wrapper {
|
||||
@include bordered-block;
|
||||
padding: 1rem;
|
||||
background-color: $toc-color;
|
||||
border-color: $toc-border-color;
|
||||
box-sizing: border-box;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
$container-width: 45rem;
|
||||
$container-min-padding: 1rem;
|
||||
$container-width-threshold: $container-width + 2 * $container-min-padding;
|
||||
$standard-border-width: .075rem;
|
||||
|
||||
$primary-color: #36e281;
|
||||
$border-color: #bfbfbf;
|
||||
$code-color: #f0f0f0;
|
||||
$code-border-color: darken($code-color, 10%);
|
||||
|
||||
$font-heading: "Lora", serif;
|
||||
$font-body: "Raleway", serif;
|
||||
$font-code: "Inconsolata", monospace;
|
||||
|
||||
$standard-border: $standard-border-width solid $border-color;
|
||||
$code-border: $standard-border-width solid $code-border-color;
|
||||
@@ -1,12 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ .Site.Language.Lang }}">
|
||||
{{- partial "head.html" . -}}
|
||||
<body>
|
||||
{{- partial "header.html" . -}}
|
||||
<div class="container"><hr class="header-divider"></div>
|
||||
<main class="container">
|
||||
{{- block "main" . }}{{- end }}
|
||||
</main>
|
||||
{{- block "after" . }}{{- end }}
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
{{- block "main" . }}{{- end }}
|
||||
@@ -1,9 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<h2>{{ .Title }}</h2>
|
||||
|
||||
<ul class="post-list">
|
||||
{{ range .Pages.ByDate.Reverse }}
|
||||
{{ partial "post.html" . }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
@@ -1,12 +0,0 @@
|
||||
[input]
|
||||
base_directory = "content/"
|
||||
title_boost = "Large"
|
||||
files = [
|
||||
{{ range $index , $e := .Site.RegularPages }}{{ if $index }}, {{end}}{ filetype = "PlainText", contents = {{ $e.Plain | jsonify }}, title = {{ $e.Title | jsonify }}, url = {{ $e.Permalink | jsonify }} }
|
||||
{{ end }}
|
||||
]
|
||||
|
||||
[output]
|
||||
filename = "index.st"
|
||||
excerpts_per_result = 2
|
||||
displayed_results_count = 5
|
||||
@@ -1,4 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<h2>{{ .Title }}</h2>
|
||||
{{ .Content }}
|
||||
{{ end }}
|
||||
@@ -1,3 +0,0 @@
|
||||
{{ define "main" }}
|
||||
{{ .Content }}
|
||||
{{ end }}
|
||||
@@ -1,42 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<h2>{{ .Title }}</h2>
|
||||
<div class="post-subscript">
|
||||
<p>
|
||||
{{ range .Params.tags }}
|
||||
<a class="button" href="{{ $.Site.BaseURL }}/tags/{{ . | urlize }}">{{ . }}</a>
|
||||
{{ end }}
|
||||
</p>
|
||||
<p>Posted on {{ .Date.Format "January 2, 2006" }}.</p>
|
||||
</div>
|
||||
|
||||
<div class="post-content">
|
||||
{{ if not (eq .TableOfContents "<nav id=\"TableOfContents\"></nav>") }}
|
||||
<div class="table-of-contents">
|
||||
<div class="wrapper">
|
||||
<em>Table of Contents</em>
|
||||
{{ .TableOfContents }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{ if .Draft }}
|
||||
<div class="draft-warning">
|
||||
<em>Warning!</em> This post is a draft. At best, it may contain grammar mistakes;
|
||||
at worst, it can include significant errors and bugs. Please
|
||||
use your best judgement!
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{ .Content }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ define "after" }}
|
||||
<hr class="container footer-divider">
|
||||
<footer class="container">
|
||||
Liked this article? I'm currently looking for Computer Science internships for the summer
|
||||
of 2021. Take a look at my <a href="/Resume-Danila-Fedorin.pdf">resume</a>,
|
||||
<a href="https://github.com/DanilaFe">GitHub profile</a>,
|
||||
and <a href="/favorites">my favorite articles from this blog</a>
|
||||
to learn more about me!
|
||||
</footer>
|
||||
{{ end }}
|
||||
@@ -1,10 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<h2>{{ .Title }} </h2>
|
||||
{{ .Content }}
|
||||
|
||||
<ul class="post-list">
|
||||
{{ range (where (where .Site.Pages.ByDate.Reverse "Section" "blog") ".Kind" "!=" "section") }}
|
||||
{{ if .Params.favorite }}{{ partial "post.html" . }}{{ end }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
@@ -1,11 +0,0 @@
|
||||
{{ define "main" }}
|
||||
{{ .Content }}
|
||||
|
||||
Recent posts:
|
||||
<ul class="post-list">
|
||||
{{ range first 10 (where (where .Site.Pages.ByDate.Reverse "Section" "blog") ".Kind" "!=" "section") }}
|
||||
{{ partial "post.html" . }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
{{ end }}
|
||||
@@ -1,23 +0,0 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#1dc868">
|
||||
{{ if .Description }}
|
||||
<meta name="description" content="{{ .Description }}">
|
||||
{{ end }}
|
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&family=Raleway&family=Lora&display=block" media="screen">
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css" media="screen">
|
||||
{{ $style := resources.Get "scss/style.scss" | resources.ToCSS | resources.Minify }}
|
||||
{{ $sidenotes := resources.Get "scss/sidenotes.scss" | resources.ToCSS | resources.Minify }}
|
||||
{{ $code := resources.Get "scss/code.scss" | resources.ToCSS | resources.Minify }}
|
||||
{{ $icon := resources.Get "img/favicon.png" }}
|
||||
{{- partial "sidenotes.html" . -}}
|
||||
<link rel="stylesheet" href="{{ $style.Permalink }}" media="screen">
|
||||
<link rel="stylesheet" href="{{ $sidenotes.Permalink }}" media="screen">
|
||||
<link rel="stylesheet" href="{{ $code.Permalink }}" media="screen">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous" media="screen">
|
||||
<link rel="icon" type="image/png" href="{{ $icon.Permalink }}">
|
||||
|
||||
<title>{{ .Title }}</title>
|
||||
</head>
|
||||
@@ -1,13 +0,0 @@
|
||||
<div class="container">
|
||||
<h1>Daniel's Blog</h1>
|
||||
</div>
|
||||
<nav>
|
||||
<div class="container">
|
||||
<a href="/">Home</a>
|
||||
<a href="/about">About</a>
|
||||
<a href="https://github.com/DanilaFe">GitHub</a>
|
||||
<a href="/Resume-Danila-Fedorin.pdf">Resume</a>
|
||||
<a href="/tags">Tags</a>
|
||||
<a href="/blog">All Posts</a>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -1,3 +0,0 @@
|
||||
<svg class="feather">
|
||||
<use xlink:href="/feather-sprite.svg#{{ . }}"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 81 B |
@@ -1,5 +0,0 @@
|
||||
<li>
|
||||
<a href="{{ .Permalink }}" class="post-title">{{ if .Params.favorite }}{{ partial "icon.html" "star" }}{{ end }} {{ .Title }}</a>
|
||||
<p class="post-wordcount">{{ .WordCount }} words, about {{ .ReadingTime }} minutes to read.</p>
|
||||
<p class="post-preview">{{ .Summary }} . . .</p>
|
||||
</li>
|
||||
@@ -1,5 +0,0 @@
|
||||
<style>
|
||||
.sidenote-checkbox {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -1,39 +0,0 @@
|
||||
{{- $pctx := . -}}
|
||||
{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}}
|
||||
{{- $pages := slice -}}
|
||||
{{- if or $.IsHome $.IsSection -}}
|
||||
{{- $pages = $pctx.RegularPages -}}
|
||||
{{- else -}}
|
||||
{{- $pages = $pctx.Pages -}}
|
||||
{{- end -}}
|
||||
{{- $limit := .Site.Config.Services.RSS.Limit -}}
|
||||
{{- if ge $limit 1 -}}
|
||||
{{- $pages = $pages | first $limit -}}
|
||||
{{- end -}}
|
||||
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}</description>
|
||||
<generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
|
||||
<language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
|
||||
<managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
|
||||
<webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
|
||||
<copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
|
||||
<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
|
||||
{{ with .OutputFormats.Get "RSS" }}
|
||||
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
|
||||
{{ end }}
|
||||
{{ range $pages }}
|
||||
<item>
|
||||
<title>{{ .Title }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
|
||||
{{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
|
||||
<guid>{{ .Permalink }}</guid>
|
||||
<description>{{ .Content | html }}</description>
|
||||
</item>
|
||||
{{ end }}
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1 +0,0 @@
|
||||
{{ highlight (readFile (printf "code/%s" (.Get 1))) (.Get 0) "" }}
|
||||
@@ -1,32 +0,0 @@
|
||||
{{ $source := (readFile (printf "code/%s" (.Get 1))) }}
|
||||
{{ $allLines := split $source "\n" }}
|
||||
{{ if not (eq (int (.Get 2)) 1) }}
|
||||
{{ .Scratch.Set "remLines" (after (sub (int (.Get 2)) 1) $allLines) }}
|
||||
{{ else }}
|
||||
{{ .Scratch.Set "remLines" $allLines }}
|
||||
{{ end }}
|
||||
{{ $lines := first (add (sub (int (.Get 3)) (int (.Get 2))) 1) (.Scratch.Get "remLines") }}
|
||||
|
||||
{{ if (.Get 4) }}
|
||||
{{ .Scratch.Set "opts" (printf ",%s" (.Get 4)) }}
|
||||
{{ else }}
|
||||
{{ .Scratch.Set "opts" "" }}
|
||||
{{ end }}
|
||||
|
||||
{{ .Scratch.Set "bestLength" -1 }}
|
||||
{{ .Scratch.Set "bestUrl" (printf "https://dev.danilafe.com/Web-Projects/blog-static/src/branch/master/code/%s" (.Get 1)) }}
|
||||
{{ $filePath := (.Get 1) }}
|
||||
{{ $scratch := .Scratch }}
|
||||
{{ range $module, $props := .Site.Params.submoduleLinks }}
|
||||
{{ $path := index $props "path" }}
|
||||
{{ $bestLength := $scratch.Get "bestLength" }}
|
||||
{{ if and (le $bestLength (len $path)) (hasPrefix $filePath $path) }}
|
||||
{{ $scratch.Set "bestLength" (len $path) }}
|
||||
{{ $scratch.Set "bestUrl" (printf "%s%s" (index $props "url") (strings.TrimPrefix $path $filePath)) }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<div class="highlight-group">
|
||||
<div class="highlight-label">From <a href="{{ .Scratch.Get "bestUrl" }}">{{ path.Base (.Get 1) }}</a>,
|
||||
{{ if eq (.Get 2) (.Get 3) }}line {{ .Get 2 }}{{ else }} lines {{ .Get 2 }} through {{ .Get 3 }}{{ end }}</div>
|
||||
{{ highlight (delimit $lines "\n") (.Get 0) (printf "linenos=table,linenostart=%d%s" (.Get 2) (.Scratch.Get "opts")) }}
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
$$
|
||||
{{ .Inner }}
|
||||
$$
|
||||
@@ -1,11 +0,0 @@
|
||||
{{ .Page.Scratch.Add "numbernote-id" 1 }}
|
||||
{{ $id := .Page.Scratch.Get "numbernote-id" }}
|
||||
<span class="sidenote">
|
||||
<label class="sidenote-label" for="numbernote-{{ $id }}">({{ $id }})</label>
|
||||
<input class="sidenote-checkbox" type="checkbox" id="numbernote-{{ $id }}"></input>
|
||||
<span class="sidenote-content sidenote-{{ .Get 0 }}">
|
||||
<span class="sidenote-delimiter">[note:</span>
|
||||
{{ .Inner }}
|
||||
<span class="sidenote-delimiter">]</span>
|
||||
</span>
|
||||
</span>
|
||||
@@ -1 +0,0 @@
|
||||
<pre><code>{{ readFile (printf "code/%s" (.Get 0)) }}</code></pre>
|
||||
@@ -1,9 +0,0 @@
|
||||
<span class="sidenote">
|
||||
<label class="sidenote-label" for="{{ .Get 1 }}">{{ .Get 2 }}</label>
|
||||
<input class="sidenote-checkbox" type="checkbox" id="{{ .Get 1 }}"></input>
|
||||
<span class="sidenote-content sidenote-{{ .Get 0 }}">
|
||||
<span class="sidenote-delimiter">[note:</span>
|
||||
{{ .Inner }}
|
||||
<span class="sidenote-delimiter">]</span>
|
||||
</span>
|
||||
</span>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div style="background-color: tomato; color: white; padding: 10px;">
|
||||
<em>TODO: </em>{{ .Inner }}
|
||||
</div>
|
||||
@@ -1,9 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<h2>Tagged "{{ .Title }}"</h2>
|
||||
|
||||
<ul class="post-list">
|
||||
{{ range .Pages.ByDate.Reverse }}
|
||||
{{ partial "post.html" . }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
@@ -1,10 +0,0 @@
|
||||
{{ define "main" }}
|
||||
<h2>{{ .Title }}</h2>
|
||||
Below is a list of all the tags ever used on this site.
|
||||
|
||||
<ul>
|
||||
{{ range sort .Pages "Title" }}
|
||||
<li><a href="{{ .Permalink }}">{{ .Title }}</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 53 KiB |
@@ -1,21 +0,0 @@
|
||||
# theme.toml template for a Hugo theme
|
||||
# See https://github.com/gohugoio/hugoThemes#themetoml for an example
|
||||
|
||||
name = "Vanilla"
|
||||
license = "MIT"
|
||||
# licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE"
|
||||
# description = ""
|
||||
# homepage = "http://example.com/"
|
||||
# tags = []
|
||||
# features = []
|
||||
min_version = "0.41"
|
||||
|
||||
[author]
|
||||
name = "Danila Fedorin"
|
||||
homepage = "https://danilafe.com"
|
||||
|
||||
# If porting an existing theme
|
||||
# [original]
|
||||
# name = ""
|
||||
# homepage = ""
|
||||
# repo = ""
|
||||
Reference in New Issue
Block a user