~kungtotte/dtt

d2036351163429a3aacb3aed6cf252b3a817e9c5 — Thomas Landin 2 months ago 4c4eaef
Remove unused code and slimline blog management

Now everything runs much smoother and the code is easier to follow
I think. There's still a few rough edges here and there but it's much
better now to build on this.
2 files changed, 39 insertions(+), 80 deletions(-)

M src/dtt.nim
M src/utils.nim
M src/dtt.nim => src/dtt.nim +7 -6
@@ 1,5 1,5 @@
import os, strutils, strformat
import unicode
import unicode, algorithm

import docopt
import mustache


@@ 115,7 115,7 @@ proc buildCmd(posts_per_page: int = 5) =

  var
    pages: seq[PageMeta]
    posts: seq[string]
    posts: seq[BlogPost]
    links: seq[Table[string, string]]
  for f in walkDirRec(content_dir, relative = true):
    let


@@ 131,9 131,9 @@ proc buildCmd(posts_per_page: int = 5) =
      setFilePermissions(output_file, outFilePerms)
    else:
      if isBlog(dir, name):
        let rendered = renderBlog(content_dir / f, tmpl_dir)
        posts.add(rendered)
        writeFile(savepath / name & ".html", rendered)
        let post = buildBlogPost(content_dir / f, tmpl_dir)
        posts.add(post)
        writeFile(savepath / name & ".html", post.content)
      else:
        var page: PageMeta
        page.title = name.title()


@@ 147,10 147,11 @@ proc buildCmd(posts_per_page: int = 5) =

  let
    num_blogs = min(posts.len - 1, posts_per_page)
  sort(posts, dateSort, Descending) # Sort blogs in reverse date order
  for page in pages:
    var context = newContext(searchDirs = @[tmpl_dir])
    context["blog_posts"] = posts[0..num_blogs]
    context["links"] = links
    context["blog_posts"] = postsToContext(posts[0..num_blogs])
    let
      rendered = context.renderTemplate(page.abs_path, page.tmpl, tmpl_dir)
      output_file = page.out_path / page.filename

M src/utils.nim => src/utils.nim +32 -74
@@ 1,7 1,6 @@
import os, strutils, strformat
import parsecfg, strscans
import unicode, times
import algorithm, tables
import unicode, tables, times

import markdown
import mustache


@@ 9,9 8,16 @@ import mustache
const
  blog_dirs = ["blog", "blogs", "post", "posts", "articles", "journal", "journals"]

proc dateSort(x, y: Table[string, string]): int =
  let xdate = x["date"].replace("-","").parseInt
  let ydate = y["date"].replace("-","").parseInt
type
  BlogPost* = tuple
    slug: string
    date: string
    content: string
    url: string

proc dateSort*(x, y: BlogPost): int =
  let xdate = x.date.replace("-","").parseInt
  let ydate = y.date.replace("-","").parseInt
  if xdate > ydate or xdate == ydate:
    1
  else:


@@ 25,35 31,6 @@ proc renderTemplate*(context: Context, file: string,
  context["content"] = markdown(readFile(file))
  result = tpl.render(context)


proc findLinks*(content_dir: string, excludes: seq[Table[string,string]]): seq[Table[string, string]] =
  var blog_ids: seq[string]
  for b in excludes:
    blog_ids.add(b["id"])

  for f in walkDirRec(content_dir, relative = true):
    let (dir, name, _) = splitFile(f)
    let
      target = if dir != "": dir & "/" & name else: name
      title = name.title()
    if not (name in blog_ids):
      result.add({"target": target, "title": title}.toTable)

proc findTemplate*(filename: string, tmpldir: string, isBlog: bool = false): string =
  let tmpl = case isBlog:
    of true:
      "post"
    of false:
      if existsFile(tmpldir / filename & ".mustache"): filename else: "page"

  result = tmpl

proc getSlug*(filename: string, hasYMD: bool): string =
  result = filename
  if hasYMD:
    result = result[11..^1]
  result = result.title().multiReplace(("-", " "), ("_", " "))

proc formatPaddedDate(year, month, day: int): string =
  # Return a zero-padded date string in the format YYYY-MM-DD
  # fmt uses parseInt behind the scenes which will kill leading


@@ 86,20 63,6 @@ proc renderBlog*(file: string, tmpl_dir: string): string =
  context["slug"] = header.slug
  context["date"] = header.date
  result = context.renderTemplate(file, "post", tmpl_dir)
proc getBlogDate*(file: string, datestring: tuple[year, month, day: int]): string =
  if datestring.year > 0:
    let
      # fmt will use parseInt and kill leading zeroes, and this is the easiest
      # way to get a proper yyyy-MM-dd format using format strings
      y = intToStr(datestring.year)
      m = intToStr(datestring.month, 2)
      d = intToStr(datestring.day, 2)
    result = fmt"{y}-{m}-{d}"
  else:
    # We guess that the creation time of the post is usually what you want as
    # the datestamp of the blog. If you don't want this, you can rename the file
    # using the yyyy-MM-dd-slug.md format.
    result = getCreationTime(file).format("yyyy-MM-dd")

proc isBlog*(path, name: string): bool =
  var


@@ 109,32 72,27 @@ proc isBlog*(path, name: string): bool =
  else:
    result = false

proc findBlogPosts*(directory: string, tmpldir: string): seq[Table[string, string]] =
  for f in walkDirRec(directory):
    let (dir, name, ext) = splitFile(f)
    if ext == ".md":
      var
        year, month, day: int
      discard scanf(name, "$i-$i-$i", year, month, day)
      let
        basedir = lastPathPart(dir)
        isBlog = if basedir in blog_dirs or year > 0: true else: false
      if isBlog:
        let
          date = getBlogDate(f, (year, month, day))
          tmpl = findTemplate(name, tmpldir, isBlog)
        var blogContext = newContext(searchDirs = @[tmpldir])
        let
          subdir = if dir != directory: lastPathPart(dir) else: ""
          target = if subdir != "": subdir & "/" & name & ".html" else: name & ".html"
        blogContext["slug"] = getSlug(name, year > 0)
        blogContext["date"] = date
        blogContext["blog_link"] = target
        let
          rendered = blogContext.renderTemplate(f, tmpl, tmpldir)
        let tbl = {"id": name, "post": rendered, "date": date}.toTable
        result.add(tbl)
  sort(result, dateSort, Descending)
proc postsToContext*(posts: seq[BlogPost]): seq[Table[string, string]] =
  for post in posts:
    result.add({"id": post.slug, "post": post.content, "date": post.date}.toTable)

proc buildBlogPost*(full_path: string, tmpl_dir: string): BlogPost =
  let
    (dir, name, _) = splitFile(full_path)
    target = if lastPathPart(dir) == "content": name & ".html" else: lastPathPart(dir) / name & ".html"
  var
    context = newContext(searchDirs = @[tmpl_dir])
    (slug, date) = findSlugAndDate(name)
  # Fixes posts where no datestring was part of the filename
  if date == "": date = getCreationTime(full_path).format("yyyy-MM-dd")
  context["slug"] = slug
  context["date"] = date
  context["blog_link"] = target
  let rendered = context.renderTemplate(full_path, "post", tmpl_dir)
  result.slug = slug
  result.date = date
  result.url = target
  result.content = rendered

proc findConfigFile*(full_path: string): tuple[cfg: Config, wd: string] =
  let (path, name) = splitPath(full_path)