818a0bd6f1b3305351d482eeab4e9e64c2af3a18 — Nguyễn Gia Phong 7 months ago c9409b7
Migrate *the rest* of the math blogs
8 files changed, 116 insertions(+), 210 deletions(-)

M _css/basic.css
M _css/franklin.css
M _layout/header.html
R fun/conseq.md => blog/conseq.md
A blog/index.md
A blog/system.md
D menu2.md
D menu3.md
M _css/basic.css => _css/basic.css +1 -1
@@ 59,7 59,7 @@ header li a:hover {
 * narrow display: collapse the header (don't show the menu items)
 * instead, display a burger menu.
@media (max-width: 480px) {
@media (max-width: 320px) {
  nav {
    display: inline-block;

M _css/franklin.css => _css/franklin.css +12 -8
@@ 22,7 22,7 @@ html {
/* Keep minimum font size to the usual default of 16px */
@media (min-width: 800px) {
  html {
    font-size: 2vw;
    font-size: min(23px, 2vw);
    margin-left: auto;
    margin-right: auto;

@@ 150,6 150,7 @@ td {

.franklin-content p {
  hyphens: auto;
  line-height: 1.4rem;
  text-align: justify;

@@ 247,13 248,16 @@ body { counter-reset: eqnum; }
  white-space: normal;

.katex-display::after {
  counter-increment: eqnum;
  content: "(" counter(eqnum) ")";
  position: relative;
  float: right;
  padding-right: 5px;
 * No numbering, for now
 * .katex-display::after {
 *   counter-increment: eqnum;
 *   content: "(" counter(eqnum) ")";
 *   position: relative;
 *   float: right;
 *   padding-right: 5px;
 * }

/* ==================================================================

M _layout/header.html => _layout/header.html +1 -2
@@ 3,8 3,7 @@
    <li><a href=/works>Portfolio</a></li>
    <li><a href=/menu2>Life</a></li>
    <li><a href=/menu3>Tags</a></li>
    <li><a href=/blog>Blog</a></li>
  <img src=/assets/hamburger.svg id=menu-icon>

R fun/conseq.md => blog/conseq.md +1 -3
@@ 1,8 1,6 @@
title = "Infinite Sequences: A Case Study in Functional Python"
hascode = true
date = Date(2019, 2, 28)
rss = "SICP subsection 3.5.2 in Python"
date = Date(2019, 2, 28)
@def tags = ["sicp", "fun", "python", "calculus"]

A blog/index.md => blog/index.md +5 -0
@@ 0,0 1,5 @@
# Web Logs

I occasionally blog about functional programming, lambda calculus
and other computational stuff, or anything related to computers in general.
They are tagged as [`fun`](/tag/fun).

A blog/system.md => blog/system.md +96 -0
@@ 0,0 1,96 @@
rss = "Properties of cascade connected systems analyzed via anonymous functions"
date = Date(2020, 4, 15)
@def tags = ["system", "fun", "anonymous"]

# System Cascade Connection

Given two discrete-time systems $A$ and $B$ connected in cascade
to form a new system $C = x \mapsto B(A(x))$.

## Linearity

If $A$ and $B$ are linear, i.e. for all signals $x_i$ and scalars $a_i$,

  A\left(n \mapsto \sum_i a_i x_i[n]\right) = n \mapsto \sum_i a_i A(x_i)[n]\\
  B\left(n \mapsto \sum_i a_i x_i[n]\right) = n \mapsto \sum_i a_i B(x_i)[n]

then $C$ is also linear

  C\left(n \mapsto \sum_i a_i x_i[n]\right)
  &= B\left(A\left(n \mapsto \sum_i a_i x_i[n]\right)\right)\\
  &= B\left(n \mapsto \sum_i a_i A(x_i)[n]\right)\\
  &= n \mapsto \sum_i a_i B(A(x_i))[n]\\
  &= n \mapsto \sum_i a_i C(x_i)[n]

## Time Invariance

If $A$ and $B$ are time invariant,
i.e. for all signals $x$ and integers $k$,

  A(n \mapsto x[n - k]) &= n \mapsto A(x)[n - k]\\
  B(n \mapsto x[n - k]) &= n \mapsto B(x)[n - k]

then $C$ is also time invariant

  C(n \mapsto x[n - k])
  &= B(A(n \mapsto x[n - k]))\\
  &= B(n \mapsto A(x)[n - k])\\
  &= n \mapsto B(A(x))[n - k]\\
  &= n \mapsto C(x)[n - k]

## LTI Ordering

If $A$ and $B$ are linear and time-invariant, there exists
signals $g$ and $h$ such that for all signals $x$,
$A = x \mapsto x * g$ and $B = x \mapsto x * h$, thus 

\[B(A(x)) = B(x * g) = x * g * h = x * h * g = A(x * h) = A(B(x))\]

or interchanging $A$ and $B$ order does not change $C$.

## Causality

If $A$ and $B$ are causal,
i.e. for all signals $x$, $y$ and any choise of integer $k$,

  \forall n < k, x[n] = y[n]\quad
  \Longrightarrow &\;\begin{cases}
  \forall n < k, A(x)[n] = A(y)[n]\\
  \forall n < k, B(x)[n] = B(y)[n]
  \Longrightarrow &\;\forall n < k, B(A(x))[n] = B(A(y))[n]\\
  \Longleftrightarrow &\;\forall n < k, C(x)[n] = C(y)[n]

then $C$ is also causal.

## BIBO Stability

If $A$ and $B$ are stable, i.e. there exists a signal $x$
and scalars $a$ and $b$ that for all integers $n$,

  |x[n]| < a &\Longrightarrow |A(x)[n]| < b\\
  |x[n]| < a &\Longrightarrow |B(x)[n]| < b

then $C$ is also stable, i.e. there exists a signal $x$
and scalars $a$, $b$ and $c$ that for all integers $n$,

  |x[n]| < a\quad
  \Longrightarrow &\;|A(x)[n]| < b\\
  \Longrightarrow &\;|B(A(x))[n]| < c\\
  \Longleftrightarrow &\;|C(x)[n]| < c

D menu2.md => menu2.md +0 -97
@@ 1,97 0,0 @@
@def title = "More goodies"
@def hascode = true
@def rss = "A short description of the page which would serve as **blurb** in a `RSS` feed; you can use basic markdown here but the whole description string must be a single line (not a multiline string). Like this one for instance. Keep in mind that styling is minimal in RSS so for instance don't expect maths or fancy styling to work; images should be ok though: ![](https://upload.wikimedia.org/wikipedia/en/b/b0/Rick_and_Morty_characters.jpg)"
@def rss_title = "More goodies"
@def rss_pubdate = Date(2019, 5, 1)

@def tags = ["syntax", "code", "image"]

# More goodies


## More markdown support

The Julia Markdown parser in Julia's stdlib is not exactly complete and Franklin strives to bring useful extensions that are either defined in standard specs such as Common Mark or that just seem like useful extensions.

* indirect references for instance [like so]

[like so]: http://existentialcomics.com/

or also for images

![][some image]

some people find that useful as it allows referring multiple times to the same link for instance.

[some image]: https://upload.wikimedia.org/wikipedia/commons/9/90/Krul.svg

* un-qualified code blocks are allowed and are julia by default, indented code blocks are not supported by default (and there support will disappear completely in later version)

a = 1
b = a+1

you can specify the default language with `@def lang = "julia"`.
If you actually want a "plain" code block, qualify it as `plaintext` like

so this is plain-text stuff.

## A bit more highlighting

Extension of highlighting for `pkg` an `shell` mode in Julia:

(v1.4) pkg> add Franklin
shell> blah
julia> 1+1
(Sandbox) pkg> resolve

you can tune the colouring in the CSS etc via the following classes:

* `.hljs-meta` (for `julia>`)
* `.hljs-metas` (for `shell>`)
* `.hljs-metap` (for `...pkg>`)

## More customisation

Franklin, by design, gives you a lot of flexibility to define how you want stuff be done, this includes doing your own parsing/processing and your own HTML generation using Julia code.

In order to do this, you can define two types of functions in a `utils.jl` file which will complement your `config.md` file:

* `hfun_*` allow you to plug custom-generated HTML somewhere
* `lx_*` allow you to do custom parsing of markdown and generation of HTML

The former (`hfun_*`) is most likely to be useful.

### Custom "hfun"

For instance you can use it to customise how [tag pages look like](/menu3/#customising_tag_pages).

A nice example of what you can do is in the [SymbolicUtils.jl manual](https://juliasymbolics.github.io/SymbolicUtils.jl/api/) where they use a `hfun_` to generate HTML encapsulating the content of code docstrings, in a way doing something similar to what Documenter does. See [how they defined it](https://github.com/JuliaSymbolics/SymbolicUtils.jl/blob/website/utils.jl).

**Note**: the  output **will not** be reprocessed by Franklin, if you want to generate markdown which should be processed by Franklin, then use `return fd2html(markdown, internal=true)` at the end.

### Custom "lx"

These commands will look the same as latex commands but what they do with their content is now entirely controlled by your code.
You can use this to do your own parsing of specific chunks of your content if you so desire.

The definition of `lx_*` commands **must** look like this:

function lx_baz(com, _)
  # keep this first line
  brace_content = Franklin.content(com.braces[1]) # input string
  # do whatever you want here
  return uppercase(brace_content)

You can call the above with `\baz{some string}`: \baz{some string}.

**Note**: the output **will be** reprocessed by Franklin, if you want to avoid this, then escape the output by using `return "~~~" * s * "~~~"` and it will be plugged  in as is in the HTML.

D menu3.md => menu3.md +0 -99
@@ 1,99 0,0 @@
@def title = "Menu 3"

# Working with tags


* page with tag [`syntax`](/tag/syntax/)
* page with tag [`image`](/tag/image/)
* page with tag [`code`](/tag/code/)


## Indicating tags

To mark a page with tags, add:

@def tags = ["tag1", "tag2"]

then that page, along with all others that have the tag `tag1` will be listed at `/tag/tag1/`.

## Customising tag pages

You can change how a `/tag/...` page looks like by modifying the `_layout/tag.html`. An important note is that you can **only** use **global** page variables (defined in `config.md`).

There are three "exceptions":

1. you can still use `{{ispage /tag/tagname/}} ... {{end}}` (or `{{isnotpage ...}}`) to have a different layout depending on the tag,
1. you can use the `fd_tag` variable which contains the  name of the tag so `{{fill fd_tag}}` will input the tag string as is,
1. you can use `{{fill varname path/to/page}}` to exploit a page variable defined in a specific page.

## Customising tag lists

By default the tag list is very simple: it just collects all pages that match the tags and it shows them in a simple list by anti-chronological order (more recent at the top).

You can customise this by defining your own `hfun_custom_taglist` function in the `utils.jl` file. The commented blueprint for the simple default setting is below and should give you an idea of how to  write your own generator.

Assuming you've defined such a function, don't forget to use `{{custom_taglist}}` in the `_layout/tag.html` instead of the default `{{taglist}}`.

function hfun_custom_taglist()::String
    # -----------------------------------------
    # Part1: Retrieve all pages associated with
    #  the tag & sort them
    # -----------------------------------------
    # retrieve the tag string
    tag = locvar(:fd_tag)
    # recover the relative paths to all pages that have that
    # tag, these are paths like /blog/page1
    rpaths = globvar("fd_tag_pages")[tag]
    # you might want to sort these pages by chronological order
    # you could also only show the most recent 5 etc...
    sorter(p) = begin
        # retrieve the "date" field of the page if defined, otherwise
        # use the date of creation of the file
        pvd = pagevar(p, :date)
        if isnothing(pvd)
            return Date(Dates.unix2datetime(stat(p * ".md").ctime))
        return pvd
    sort!(rpaths, by=sorter, rev=true)

    # --------------------------------
    # Part2: Write the HTML to plug in
    # --------------------------------
    # instantiate a buffer in which we will write the HTML
    # to plug in the tag page
    c = IOBuffer()
    write(c, "...1...")
    # go over all paths
    for rpath in rpaths
        # recover the url corresponding to the rpath
        url = get_url(rpath)
        # recover the title of the page if there is one defined,
        # if there isn't, fallback on the path to the page
        title = pagevar(rpath, "title")
        if isnothing(title)
            title = "/$rpath/"
        # write some appropriate HTML
        write(c, "...2...")
    # finish the HTML
    write(c, "...3...")
    # return the HTML string
    return String(take!(c))

For instance the default uses:

<!-- 1, 3: simple list-->
<!-- 2: simple list item plugging in path + title -->
<li><a href="/$rpath/">$title</a></li>