Skip to content

Commit 19881ca

Browse files
committed
Add a thoroughly revised About Me page
1 parent 3ea8e22 commit 19881ca

File tree

6 files changed

+196
-39
lines changed

6 files changed

+196
-39
lines changed

blog/build.rkt

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,35 @@
9393
(display "<?xml version=\"1.0\" encoding=\"utf-8\"?>" out)
9494
(write-xexpr xexpr out))
9595

96+
(define (render-scribble render% main-part out-path
97+
#:dest-dir [dest-dir (path-only out-path)]
98+
#:xref-out [xref-out-path #f])
99+
(define main-parts (list main-part))
100+
(define out-paths (list out-path))
101+
(define renderer (new render% [dest-dir dest-dir]))
102+
103+
(define traverse-info (send renderer traverse main-parts out-paths))
104+
(define collect-info (send renderer collect main-parts out-paths traverse-info))
105+
(xref-transfer-info renderer collect-info (load-collections-xref))
106+
(define resolve-info (send renderer resolve main-parts out-paths collect-info))
107+
108+
(match-define (list render-result)
109+
(send renderer render main-parts out-paths resolve-info))
110+
111+
(when xref-out-path
112+
(define out-info (send renderer serialize-info resolve-info))
113+
(call-with-output-file* #:exists 'truncate/replace
114+
xref-out-path
115+
(λ~>> (write out-info))))
116+
117+
(define undefined-tags (send renderer get-undefined resolve-info))
118+
(unless (empty? undefined-tags)
119+
(eprintf "Warning: some cross references may be broken due to undefined tags:\n")
120+
(for ([tag (in-list undefined-tags)])
121+
(eprintf " ~s\n" tag)))
122+
123+
render-result)
124+
96125
(define (build-post-body dep)
97126
(define src-mod-time (file-or-directory-modify-seconds (post-dep-src-path dep) #f (λ () #f)))
98127
(define info-mod-time (file-or-directory-modify-seconds (post-dep-info-path dep) #f (λ () #f)))
@@ -101,30 +130,10 @@
101130
(deserialize (call-with-input-file* (post-dep-info-path dep) read))]
102131
[else
103132
(eprintf "~a running <posts>/~a\n" (timestamp-string) (find-relative-path posts-dir (post-dep-src-path dep)))
104-
(define renderer (new blog-post-render% [dest-dir build-dir]))
105-
(define main-parts (list (post-dep-main-part dep)))
106-
(define out-paths (list (post-dep-info-path dep)))
107-
108-
(define traverse-info (send renderer traverse main-parts out-paths))
109-
(define collect-info (send renderer collect main-parts out-paths traverse-info))
110-
(xref-transfer-info renderer collect-info (load-collections-xref))
111-
(define resolve-info (send renderer resolve main-parts out-paths collect-info))
112-
113-
(match-define (list (? rendered-post? post-info))
114-
(send renderer render main-parts out-paths resolve-info))
115-
116-
(define out-info (send renderer serialize-info resolve-info))
117-
(call-with-output-file* #:exists 'truncate/replace
118-
(post-dep-xref-path dep)
119-
(λ~>> (write out-info)))
120-
121-
(define undefined-tags (send renderer get-undefined resolve-info))
122-
(unless (empty? undefined-tags)
123-
(eprintf "Warning: some cross references may be broken due to undefined tags:\n")
124-
(for ([tag (in-list undefined-tags)])
125-
(eprintf " ~s\n" tag)))
126-
127-
post-info]))
133+
(render-scribble blog-post-render%
134+
(post-dep-main-part dep)
135+
(post-dep-info-path dep)
136+
#:xref-out (post-dep-xref-path dep))]))
128137

129138
(define (build-post-page dep info)
130139
(define site-path (rendered-post-path info #:file? #t))
@@ -157,13 +166,22 @@
157166
out-path
158167
(λ~>> (write-xml (feed type posts #:tag tag)))))
159168

169+
(define (build-about-me)
170+
(define site-path "/about.html")
171+
(eprintf "~a rendering <output>~a\n" (timestamp-string) site-path)
172+
(local-require (only-in "posts/about-me.scrbl" [doc main-part]))
173+
(render-scribble (blog-standalone-page-render% standalone-page)
174+
main-part
175+
(reroot-path site-path output-dir)))
176+
160177
(define (build-sitemap posts)
161178
(define site-path "/sitemap.txt")
162179
(eprintf "~a rendering <output>~a\n" (timestamp-string) site-path)
163180
(call-with-output-file*
164181
#:exists 'truncate/replace
165182
(reroot-path site-path output-dir)
166183
(λ (out)
184+
(displayln (full-url "/about.html") out)
167185
(for ([post (in-list posts)])
168186
(displayln (full-url (rendered-post-path post)) out)))))
169187

@@ -195,6 +213,7 @@
195213
(build-index-page total-pages page-number posts #:tag tag))
196214
(build-feeds posts #:tag tag))
197215

216+
(build-about-me)
198217
(build-sitemap all-posts))
199218

200219
(module+ main

blog/build/render/page.rkt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
(provide (contract-out
1717
[page (->* [#:title string? #:body xexpr/c] [#:tag (or/c string? #f)] xexpr/c)]
18+
[standalone-page (-> #:title string? #:body (listof xexpr/c) xexpr/c)]
1819
[post-page (-> rendered-post? xexpr/c)]
1920
[index-page-title (->* [] [#:tag (or/c string? #f)] string?)]
2021
[index-page (->i ([total-pages exact-positive-integer?]
@@ -46,7 +47,7 @@
4647
(ul ([class "navigation-items center"]))
4748
(ul ([class "navigation-items right"])
4849
(li (a ([href "/"]) "Home"))
49-
(li (a ([href "/resume.html"]) "About Me")))))
50+
(li (a ([href "/about.html"]) "About Me")))))
5051
(section ([role "main"]) ,body)
5152
(footer
5253
(div ([class "copyright-notice"]) "© " ,(~a (date-year (current-date))) ", Alexis King")
@@ -56,6 +57,11 @@
5657
(div "Feeds are available via " (a ([href ,(feed-path 'atom)]) "Atom")
5758
" or " (a ([href ,(feed-path 'rss)]) "RSS") "."))))))
5859

60+
(define (standalone-page #:title title #:body body)
61+
(page #:title title
62+
#:body `(div ([class "content"])
63+
(article ([class "main"]) ,@body))))
64+
5965
(define (post-page info)
6066
(match-define (rendered-post title-str title date tags body) info)
6167
(page #:title title-str

blog/build/render/scribble.rkt

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
setup/dirs
2222
syntax/parse/define
2323
threading
24-
(only-in xml write-xexpr)
24+
(only-in xml write-xexpr xexpr/c)
2525

2626
"../../lang/post-language.rkt"
2727
"../metadata.rkt"
@@ -30,6 +30,10 @@
3030

3131
(provide base-render%
3232
blog-post-render%
33+
(contract-out
34+
[blog-standalone-page-render%
35+
(-> (-> #:title string? #:body (listof xexpr/c) xexpr/c)
36+
(implementation?/c render<%>))])
3337

3438
blog-render-mixin
3539
footnotes-render-mixin
@@ -212,6 +216,18 @@
212216
(current-output-file)
213217
(tag->anchor-name (add-current-tag-prefix key)))))
214218

219+
(define/override (resolve-content i d ri)
220+
(cond
221+
[(and external-tag-path
222+
(link-element? i)
223+
(style? (element-style i))
224+
(memq 'indirect-link (style-properties (element-style i))))
225+
; Don’t resolve indirect links, or else we’ll get spurious warnings
226+
; about undefined tags.
227+
(resolve-content (element-content i) d ri)]
228+
[else
229+
(super resolve-content i d ri)]))
230+
215231
;; -------------------------------------------------------------------------
216232
;; render
217233

@@ -306,7 +322,7 @@
306322
['()
307323
(if (hash-empty? attrs)
308324
'()
309-
(cons 'span attrs))]
325+
(list (cons 'span attrs)))]
310326
; Otherwise, add the attributes to the outermost wrapper.
311327
[(cons (cons outer-tag outer-attrs) wraps)
312328
(cons (cons outer-tag (attributes-union outer-attrs attrs)) wraps)]))
@@ -327,14 +343,15 @@
327343
(wrap-for-style #:attrs (hasheq) `[(a ,(attributes->list attrs*) ,@rendered)])]
328344

329345
[(link-element _ _ tag)
330-
(define dest (resolve-get part ri tag))
331-
(unless dest
346+
(define indirect? (memq 'indirect-link (style-properties style)))
347+
(define dest (and (not indirect?) (resolve-get part ri tag)))
348+
(unless (or dest indirect?)
332349
(error 'render "unknown link destination\n tag: ~e" tag))
333350

334351
(define href
335352
(match dest
336353
; racket doc reference
337-
[(? vector?)
354+
[(or #f (? vector?))
338355
(define redirect-query
339356
(cons (cons 'tag (tag->local-redirect-query-string tag))
340357
(url-query external-tag-path)))
@@ -457,6 +474,20 @@
457474

458475
(super-new)))
459476

477+
(define (blog-standalone-page-render% page-template)
478+
(class (pygments-render-mixin (blog-render-mixin base-render%))
479+
(inherit render-part)
480+
481+
(define/override (render-one part ri output-file)
482+
(define xexpr
483+
(page-template
484+
#:title (content->string (strip-aux (part-title-content part)) this part ri)
485+
#:body (render-part part ri)))
486+
(write-xexpr xexpr)
487+
xexpr)
488+
489+
(super-new)))
490+
460491
;; The renderer used for actual blog posts, with all the bells and whistles.
461492
(define blog-post-render%
462493
(class (pygments-render-mixin (footnotes-render-mixin (blog-render-mixin base-render%)))

blog/lang/post-language.rkt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
[footnote-flow (-> symbol? (listof block?) block?)]
3737

3838
[wikipedia (-> pre-content? ... element?)]
39+
[github-repo (-> string? element?)]
40+
[github-repo* (-> string? pre-content? ... element?)]
3941
[hackage-package (-> string? element?)]
4042
[hackage-package* (-> string? pre-content? ... element?)]
4143
[hackage-module (-> string? string? element?)]
@@ -108,6 +110,16 @@
108110
['() '()]))
109111
(hyperlink (string-append "https://en.wikipedia.org/wiki/" (string-join words "_")) content))
110112

113+
(define (github-repo user+repo)
114+
(match user+repo
115+
[(regexp #px"^[^/]+/(.+)$" (list _ repo))
116+
(github-repo* user+repo repo)]
117+
[repo
118+
(github-repo* repo repo)]))
119+
(define (github-repo* repo . pre-content)
120+
(define user+repo (if (string-contains? repo "/") repo (string-append "lexi-lambda/" repo)))
121+
(apply hyperlink (string-append "https://github.com/" user+repo) pre-content))
122+
111123
;; -----------------------------------------------------------------------------
112124
;; hackage
113125

blog/posts/about-me.scrbl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#lang scribble/base
2+
@(begin
3+
(require racket/list
4+
scribble/core
5+
scribble/html-properties
6+
threading
7+
"../lang/post-language.rkt")
8+
9+
(define Scribble @seclink["top" #:doc '(lib "scribblings/scribble/scribble.scrbl")]{Scribble}))
10+
11+
@title{About me}
12+
13+
My name is Alexis King, and I write @hyperlink["https://github.com/lexi-lambda?tab=repositories"]{a lot of software}. I currently live in Chicago.
14+
15+
I’m interested in functional programming, static types, and programming language research, and I try to spend as much time as I can writing Haskell and Racket. I write about some of the things I do @hyperlink["/"]{on this blog}, and I sometimes tweet about them and other things @hyperlink["https://twitter.com/lexi_lambda"]{on Twitter}. I work on a @emph{lot} of open-source projects @hyperlink["https://github.com/lexi-lambda"]{on GitHub}, and you can email me at @hyperlink["mailto:lexi.lambda@gmail.com" "lexi.lambda@gmail.com"].
16+
17+
@section{Things I’ve worked on}
18+
19+
This list is just a smattering of the cooler things I’ve worked on over the past few years. It is neither exhaustive nor particularly scientific in its curation.
20+
21+
@(define separator @elem[#:style "about-me-year-separator" ""])
22+
@(define (year-events year . items)
23+
@para[#:style "about-me-year-events"]{@elem[#:style "about-me-year-label" year] @separator
24+
@(~> (map (λ (item) @elem[#:style "about-me-year-entry" item]) items)
25+
(add-between (list " " separator " ") #:splice? #t))})
26+
27+
@year-events["2021"
28+
@list{Reimplemented @github-repo*["lexi-lambda.github.io"]{this blog} on top of @Scribble, replacing @github-repo{greghendershott/frog}.}
29+
@list{Released @github-repo{megaparsack} v1.5, adding support for user-defined parser state and parser lookahead.}]
30+
31+
@year-events["2020"
32+
@list{Published @hyperlink["https://dl.acm.org/doi/abs/10.1145/3428297"]{“Macros for DSLs”} with Michael Ballantyne and Matthias Felleisen at OOPSLA.}
33+
@list{Presented @hyperlink["https://www.youtube.com/watch?v=0jI-AlWEwYI"]{“Effects for Less”} at ZuriHac 2020 on the design of @github-repo{hasura/eff} and its accompanying @hyperlink["https://github.com/ghc-proposals/ghc-proposals/pull/313"]{GHC proposal} to add delimited continuations to the RTS.}
34+
@list{Led a large-scale refactoring effort to statically rule out several classes of bugs in @github-repo{hasura/graphql-engine}.}
35+
@list{Opened @hyperlink["https://github.com/ghc-proposals/ghc-proposals/pull/303"]{a GHC proposal} for improving arrow notation.}
36+
@list{Started contributing to GHC, including some @hyperlink["https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3041"]{performance fixes} and @hyperlink["https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3115"]{improvements to arrow notation}.}]
37+
38+
@year-events["2019"
39+
@list{Published @hyperlink["https://dl.acm.org/doi/abs/10.1145/3371133"]{“Does blame shifting work?”} with Lukas Lazarek, Samanvitha Sundar, Robby Findler, and Christos Dimoulas at POPL.}
40+
@list{Released @hackage-package{monad-validate} based on work done for Hasura.}
41+
@list{Started working at @hyperlink["https://hasura.io/"]{Hasura}.}]
42+
43+
@year-events["2018"
44+
@list{Presented @hyperlink["https://www.youtube.com/watch?v=g6UCeHiKodo"]{“Hackett: a metaprogrammable Haskell”} at Curry On, and again a few months later @hyperlink["https://www.youtube.com/watch?v=5QQdI3P7MdY"]{at Strange Loop}.}
45+
@list{Started working on contract systems with Christos Dimoulas at Northwestern University.}]
46+
47+
@year-events["2017"
48+
@list{Released the @hackage-package{freer-simple} package.}
49+
@list{Presented @hyperlink["https://www.youtube.com/watch?v=bOUgXd9XlJ4"]{“Hackett, a Haskell for Racketeers”} at RacketCon.}
50+
@list{Started working on @github-repo*["hackett"]{Hackett}, a Haskell-like language embedded in Racket.}]
51+
52+
@year-events["2016"
53+
@list{Started learning about type systems to explore ideas inspired by @seclink["top" #:doc '(lib "turnstile/scribblings/turnstile.scrbl") #:indirect? #t]{Turnstile}.}
54+
@list{Presented @hyperlink["https://www.youtube.com/watch?v=TfehOLha-18"]{“Languages in an Afternoon”} at RacketCon.}
55+
@list{Released the @github-repo{megaparsack} and @github-repo{scripty} Racket libraries.}
56+
@list{Started writing Haskell professionally for the first time.}]
57+
58+
@section{About this blog}
59+
60+
This blog is powered by @Scribble, an unusually flexible document preparation system written in @hyperlink["https://racket-lang.org/"]{Racket}. Unlike most markup languages, every Scribble document is a @emph{program} that evaluates to a document, which can then be rendered using one of a number of different backends. Scribble provides a TeX-like notation for writing such programs, but unlike TeX—which is essentially an overgrown macro preprocessor—Scribble is a full-fledged functional programming language. In fact, the Scribble syntax is really just an alternate notation for Racket itself, so all the libraries and abstractions available in Racket can be used more or less directly in a Scribble document.
61+
62+
This makes Scribble a remarkably powerful tool for writing prose documents, and indeed, it serves as the foundation for Racket’s @hyperlink["https://docs.racket-lang.org/"]{best-in-class documentation system}, among other things. Using it to power a blog is perhaps a bit overkill, but it gives me the wonderful ability to define whatever abstractions I desire to make blogging as effortless as possible. For example, after finding myself linking to Hackage packages quite frequently, I decided to define a one-line function:
63+
64+
@pygments-block[#:language "racket"]{
65+
(define (hackage-package package-name)
66+
(hyperlink (string-append "https://hackage.haskell.org/package/" package-name) package-name))}
67+
68+
Now all I have to do is write @code["@hackage-package{lens}"] and I get @hackage-package{lens}. Sure, it’s not exactly mind-blowing, but it’s certainly convenient… and of course, the most significant advantages involve abstractions too elaborate to describe here.
69+
70+
This site is, naturally, open source, so if you’d like to see how all the pieces fit together for yourself, feel free to clone @github-repo*["lexi-lambda.github.io"]{the GitHub repository}. And if you’re interested in a simple example of what Scribble looks like to use, you might as well take a peek at @hyperlink["https://github.com/lexi-lambda/lexi-lambda.github.io/blob/source/blog/posts/about-me.scrbl"]{the source code for this page in particular}.

scss/application.scss

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ a {
7676
transition: color 0.15s ease-in-out;
7777
}
7878

79+
p, article li, blockquote {
80+
margin-bottom: 1.2em;
81+
82+
@media (min-width: 800px) {
83+
margin-bottom: 2em;
84+
}
85+
}
86+
7987
body > section[role=main] {
8088
$content-padding: 30px;
8189

@@ -140,22 +148,14 @@ body > section[role=main] {
140148
width: fit-content;
141149
}
142150

143-
// On large screens they can spill into the margins ton, since we really
151+
// On large screens they can spill into the margins a ton, since we really
144152
// don’t want them to have to scroll.
145153
@media (min-width: $content-width-max + $content-padding * 2) {
146154
max-width: $content-width-max;
147155
}
148156
}
149157
}
150158

151-
p, article li, blockquote {
152-
margin-bottom: 1.2em;
153-
154-
@media (min-width: 800px) {
155-
margin-bottom: 2em;
156-
}
157-
}
158-
159159
// Subscripts and superscripts should not disrupt line spacing.
160160
sup, sub {
161161
line-height: 0;
@@ -415,3 +415,22 @@ div.figure, article.main > p > a {
415415
.no-line-wrapping {
416416
white-space: nowrap;
417417
}
418+
419+
// -----------------------------------------------------------------------------
420+
// styles for the About Me page
421+
422+
.about-me-year-events {
423+
margin-bottom: 0.35em;
424+
margin-top: 0em;
425+
padding-left: 1.2em;
426+
text-indent: -1.2em;
427+
}
428+
429+
.about-me-year-label {
430+
font-weight: bold;
431+
font-size: 1.1em;
432+
}
433+
434+
.about-me-year-separator {
435+
margin: 0.25em;
436+
}

0 commit comments

Comments
 (0)