diff --git a/tools/nimweb.nim b/tools/nimweb.nim
index 27e843fde4..c5d510eacc 100644
--- a/tools/nimweb.nim
+++ b/tools/nimweb.nim
@@ -8,7 +8,8 @@
#
import
- os, strutils, times, parseopt, parsecfg, streams, strtabs, tables
+ os, strutils, times, parseopt, parsecfg, streams, strtabs, tables,
+ re, htmlgen, macros, md5
type
TKeyValPair = tuple[key, id, val: string]
@@ -19,6 +20,8 @@ type
vars: PStringTable
nimrodArgs: string
quotations: TTable[string, tuple[quote, author: string]]
+ TRssItem = object
+ year, month, day, title: string
proc initConfigData(c: var TConfigData) =
c.tabs = @[]
@@ -59,6 +62,38 @@ Compile_options:
will be passed to the Nimrod compiler
"""
+ rYearMonthDayTitle = r"(\d{4})-(\d{2})-(\d{2})\s+(.*)"
+ rssUrl = "http://nimrod-code.org/news.xml"
+ rssNewsUrl = "http://nimrod-code.org/news.html"
+ validAnchorCharacters = Letters + Digits
+
+
+macro id(e: expr): expr {.immediate.} =
+ ## generates the rss xml ``id`` element.
+ let e = callsite()
+ result = xmlCheckedTag(e, "id")
+
+macro updated(e: expr): expr {.immediate.} =
+ ## generates the rss xml ``updated`` element.
+ let e = callsite()
+ result = xmlCheckedTag(e, "updated")
+
+proc updatedDate(year, month, day: string): string =
+ ## wrapper around the update macro with easy input.
+ result = updated("$1-$2-$3T00:00:00Z" % [year,
+ repeatStr(2 - len(month), "0") & month,
+ repeatStr(2 - len(day), "0") & day])
+
+macro entry(e: expr): expr {.immediate.} =
+ ## generates the rss xml ``entry`` element.
+ let e = callsite()
+ result = xmlCheckedTag(e, "entry")
+
+macro content(e: expr): expr {.immediate.} =
+ ## generates the rss xml ``content`` element.
+ let e = callsite()
+ result = xmlCheckedTag(e, "content", reqAttr = "type")
+
proc parseCmdLine(c: var TConfigData) =
var p = initOptParser()
while true:
@@ -207,6 +242,85 @@ proc buildAddDoc(c: var TConfigData, destPath: string) =
Exec("nimrod doc $# -o:$# $#" %
[c.nimrodArgs, destPath / changeFileExt(splitFile(d).name, "html"), d])
+proc parseNewsTitles(inputFilename: string): seq[TRssItem] =
+ # parses the file for titles and returns them as TRssItem blocks.
+ let reYearMonthDayTitle = re(rYearMonthDayTitle)
+ var
+ input: TFile
+ line = ""
+
+ result = @[]
+ if not open(input, inputFilename):
+ quit("Could not read $1 for rss generation" % [inputFilename])
+ finally: input.close()
+ while input.readline(line):
+ if line =~ reYearMonthDayTitle:
+ result.add(TRssItem(year: matches[0], month: matches[1], day: matches[2],
+ title: matches[3]))
+
+proc genUUID(text: string): string =
+ # Returns a valid RSS uuid, which is basically md5 with dashes and a prefix.
+ result = getMD5(text)
+ result.insert("-", 20)
+ result.insert("-", 16)
+ result.insert("-", 12)
+ result.insert("-", 8)
+ result.insert("urn:uuid:")
+
+proc genNewsLink(title: string): string =
+ # Mangles a title string into an expected news.html anchor.
+ result = title
+ result.insert("Z")
+ for i in 1..len(result)-1:
+ let letter = result[i].toLower()
+ if letter in validAnchorCharacters:
+ result[i] = letter
+ else:
+ result[i] = '-'
+ result.insert(rssNewsUrl & "#")
+
+proc generateRss(outputFilename: string, news: seq[TRssItem]) =
+ # Given a list of rss items generates an rss overwriting destination.
+ var
+ output: TFile
+
+ if not open(output, outputFilename, mode = fmWrite):
+ quit("Could not write to $1 for rss generation" % [outputFilename])
+ finally: output.close()
+
+ output.write("""
+