(setq debug-on-error t)
(defconst jc-repositoryPath "/Users/suzume/Documents/Repositories/brandelune.github.io/")
(defconst jc-dayTrackerPath (concat jc-repositoryPath "dayTracker.txt"))
(defconst jc-rssFile (concat jc-repositoryPath "adventuresintechland.xml"))
(defconst jc-indexPath (concat jc-repositoryPath "index.html"))
(defconst jc-tomorrowFile (concat jc-repositoryPath "tomorrow.html"))
(defconst jc-tomorrow "<a href=\"../../../tomorrow.html\" hreflang=\"en\" rel=\"next\">tomorrow</a>")
(defconst jc-ghPagesURL "https://github.com/brandelune/brandelune.github.io/commits/gh-pages")
(defconst jc-siteRoot "https://github.com/brandelune/brandelune.github.io/")
(defconst jc-faviconURL "https://brandelune.github.io/favicon/")
(defconst jc-rssReferences "<a href=\"https://brandelune.github.io/adventuresintechland.xml\"><img src=\"https://www.mozilla.org/media/img/trademarks/feed-icon-28x28.e077f1f611f0.png\" width=\"15px\" height=\"15px\" alt=\"rss feed\" /></a>")
(defconst jc-baseCSSLink "../../adventuresintechland.css")
(defconst jc-dailyCSSLink "./adventuresintechland.css")
(defconst jc-todayNavigationContents "<p class=\"navigation\">
<a href=\"%1$s\" hreflang=\"en\" rel=\"prev\">%2$s</a>
<a href=\"../../../index.html\" hreflang=\"en\">index</a>
<a href=\"%3$s\">gh-pages</a>
<a href=\"../../../adventuresintechland.html\" hreflang=\"en\">todo</a>
%4$s
</p>")
(defconst jc-todayHeaderContents "<html>
<head lang=\"en-us\">
<title>%1$s</title>
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />
<meta name=\"msapplication-TileColor\" content=\"#FFFFFF\" />
<meta name=\"msapplication-TileImage\" content=\"%4$sfavicon-144.png\" />
<meta name=\"msapplication-config\" content=\"%4$sbrowserconfig.xml\" />
<link rel=\"shortcut icon\" href=\"%4$sfavicon.ico\" />
<link rel=\"icon\" sizes=\"16x16 32x32 64x64\" href=\"%4$sfavicon.ico\" />
<link rel=\"icon\" type=\"image/png\" sizes=\"196x196\" href=\"%4$sfavicon-192.png\" />
<link rel=\"icon\" type=\"image/png\" sizes=\"160x160\" href=\"%4$sfavicon-160.png\" />
<link rel=\"icon\" type=\"image/png\" sizes=\"96x96\" href=\"%4$sfavicon-96.png\" />
<link rel=\"icon\" type=\"image/png\" sizes=\"64x64\" href=\"%4$sfavicon-64.png\" />
<link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"%4$sfavicon-32.png\" />
<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"%4$sfavicon-16.png\" />
<link rel=\"apple-touch-icon\" href=\"%4$sfavicon-57.png\" />
<link rel=\"apple-touch-icon\" sizes=\"114x114\" href=\"%4$sfavicon-114.png\" />
<link rel=\"apple-touch-icon\" sizes=\"72x72\" href=\"%4$sfavicon-72.png\" />
<link rel=\"apple-touch-icon\" sizes=\"144x144\" href=\"%4$sfavicon-144.png\" />
<link rel=\"apple-touch-icon\" sizes=\"60x60\" href=\"%4$sfavicon-60.png\" />
<link rel=\"apple-touch-icon\" sizes=\"120x120\" href=\"%4$sfavicon-120.png\" />
<link rel=\"apple-touch-icon\" sizes=\"76x76\" href=\"%4$sfavicon-76.png\" />
<link rel=\"apple-touch-icon\" sizes=\"152x152\" href=\"%4$sfavicon-152.png\" />
<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"%4$sfavicon-180.png\" />
<link rel=\"stylesheet\" type=\"text/css\" href=\"%2$s\" class=\"baseCSS\"/>
<link rel=\"stylesheet\" type=\"text/css\" href=\"%3$s\" class=\"dailyCSS\"/>
<meta charset=\"UTF-8\" />
</head>")
(defconst jc-todayTemplateContents "%1$s
<body>
%2$s
<p id=\"episode\"><em>Adventures in Tech Land. Season %7$s. Episode %8$s</em></p>
<h1>%4$s %9$s</h1>
<p id=\"title item\">%3$s, %10$sth day</p>
<h2>%5$s</h2>
<p id=\"first sub-title item\">%6$s</p>
%2$s
</body>
</html>")
(defconst jc-myRSSTemplate "<item>
<title>%1$s</title>
<link>https://brandelune.github.io/%2$s/index.html</link>
<guid>https://brandelune.github.io/%2$s/index.html</guid>
<pubDate>%3$s</pubDate>
<description>%4$s</description>
</item>
")
(defvar jc-lastdayList)
(defvar jc-lastdayLink)
(defvar jc-lastdayDate)
(defvar jc-todayList)
(defvar jc-todayHeader)
(defvar jc-todayTemplate)
(defvar jc-todayNavigation)
(defvar jc-todayPath)
(defvar jc-todayIndex)
(defvar jc-todayDate)
(defvar jc-seasonNumber)
(defvar jc-seasonEpisode)
(defvar jc-totalDays)
(defvar jc-newDayTracker)
(defvar monthMaxDay)
(defun dailyIndex (today lastday title subtitle firstpar)
"Create an html file for TODAY with LASTDAY TITLE SUBTITLE FIRSTPAR.
The contents has to be filled manually, later."
(save-current-buffer
(set-buffer (find-file-noselect jc-dayTrackerPath))
(goto-char (point-min))
(search-forward-regexp "\\([0-9]*\\.[0-9]*\\) \\([0-9]*\\) \\([0-9]*\\) \\([0-9]*\\)")
(setq jc-lastdayDate (cl-fourth (decode-time (string-to-number (match-string 1))))
seasonNumber (match-string 2)
totalDays (string-to-number (match-string 3))
newTotalDays (+ 1 totalDays)
currentEpisode (string-to-number (match-string 4))
newSeasonEpisode (+ 1 currentEpisode))
(kill-buffer))
(interactive (list
(read-number "Date: " (cl-fourth (decode-time (float-time))))
(read-number "Previous date: " jc-lastdayDate)
(read-string "Title: " )
(read-string "Sub-title: ")
(read-string "First paragraph: ")))
(setq jc-lastdayList (myDate lastday)
jc-lastday (concat (my0Padding (cl-second jc-lastdayList)) (my0Padding (cl-third jc-lastdayList)))
jc-lastdayLink (concat (file-name-as-directory "../../../")
(file-name-as-directory (number-to-string (cl-first jc-lastdayList)))
(file-name-as-directory (my0Padding (cl-second jc-lastdayList)))
(file-name-as-directory (my0Padding (cl-third jc-lastdayList)))
"index.html")
jc-lastdayIndex (concat (file-name-as-directory jc-repositoryPath)
(file-name-as-directory (number-to-string (cl-first jc-lastdayList)))
(file-name-as-directory (my0Padding (cl-second jc-lastdayList)))
(file-name-as-directory (my0Padding (cl-third jc-lastdayList)))
"index.html"))
(setq jc-todayList (myDate today)
jc-todaySubPath (concat (file-name-as-directory (number-to-string (cl-first jc-todayList)))
(file-name-as-directory (my0Padding (cl-second jc-todayList)))
(my0Padding (cl-third jc-todayList)))
jc-todayPath (concat (file-name-as-directory jc-repositoryPath)
(file-name-as-directory jc-todaySubPath))
jc-todayRelativeIndex (concat (file-name-as-directory "../../../")
(file-name-as-directory jc-todaySubPath)
"index.html")
jc-todayIndex (concat (file-name-as-directory jc-todayPath) "index.html")
jc-todayDate (concat (number-to-string (cl-first jc-todayList)) "/" (my0Padding (cl-second jc-todayList)) "/" (my0Padding (cl-third jc-todayList)))
jc-todayLinkName (concat (my0Padding (cl-second jc-todayList)) (my0Padding (cl-third jc-todayList))))
(setq jc-todayNavigation
(format jc-todayNavigationContents
jc-lastdayLink jc-lastday jc-ghPagesURL jc-tomorrow ))
(setq jc-todayHeader
(format jc-todayHeaderContents
title jc-baseCSSLink jc-dailyCSSLink jc-faviconURL ))
(setq jc-todayTemplate
(format jc-todayTemplateContents
jc-todayHeader jc-todayNavigation jc-todayDate title subtitle firstpar seasonNumber jc-seasonEpisode jc-rssReferences jc-totalDays ))
(make-directory jc-todayPath t)
(myInsert jc-todayTemplate "" jc-todayIndex)
(myInsert "" "" jc-dailyCSSLink)
(myDailyRSSItem title today firstpar)
(save-current-buffer
(set-buffer (find-file-noselect jc-dayTrackerPath))
(goto-char (point-min))
(insert (format "%s %s %s %s\n" (float-time) seasonNumber jc-totalDays jc-seasonEpisode))
(save-buffer)
(kill-buffer))
(setq jc-todayDayAnchor
(concat "<a href=\"" jc-todayRelativeIndex "\" hreflang=\"en\" rel=\"next\">" jc-todayLinkName "</a>"))
(myReplace
jc-tomorrow
jc-todayDayAnchor
jc-lastdayIndex)
(let* ((oldLastDayHref (concat "<a href=\"./"
(file-name-as-directory (number-to-string (cl-first jc-lastdayList)))
(file-name-as-directory (my0Padding (cl-second jc-lastdayList)))
(file-name-as-directory (my0Padding (cl-third jc-lastdayList)))
"index.html\" hreflang=\"en\" rel=\"prev\" id=\"update1\">last day</a>"))
(newLastDayHref (concat "<a href=\"./"
(file-name-as-directory (number-to-string (cl-first jc-todayList)))
(file-name-as-directory (my0Padding (cl-second jc-todayList)))
(file-name-as-directory (my0Padding (cl-third jc-todayList)))
"index.html\" hreflang=\"en\" rel=\"prev\" id=\"update1\">last day</a>")))
(myReplace
oldLastDayHref
newLastDayHref
jc-indexPath))
(let* ((oldTotaDaysH2 (format "<h2 id=\"update2\">Logbook, %1$s documented days</h2>"
(number-to-string totalDays)))
(newTotalDaysH2 (format "<h2 id=\"update2\">Logbook, %1$s documented days</h2>"
(number-to-string newTotalDays))))
(myReplace
oldTotaDaysH2
newTotalDaysH2
jc-indexPath))
(let* ((oldSeasonDataH3 (format "<h3 id=\"update3\">Season %1$s, %2$s episodes</h3>"
seasonNumber
currentEpisode))
(newSeasonDataH3 (format "<h3 id=\"update3\">Season %1$s, %2$s episodes</h3>"
seasonNumber
newSeasonEpisode)))
(myReplace
oldSeasonDataH3
newSeasonDataH3
jc-indexPath))
(let* ((update4Marker "<ul id=\"update4\">\n")
(mainIndexTodayLiHref (format "<ul id=\"update4\">
<li style=\"list-style-type:square;\"><a href=\"./%1$s/index.html\" hreflang=\"en\" id=\"%2$s\">%3$s</a> %4$s</li>
"
jc-todaySubPath
newTotalDays
(substring jc-todaySubPath 2)
title
)))
(myReplace
update4Marker
mainIndexTodayLiHref
jc-indexPath))
(let* ((oldLastDayHref (concat "<a href=\"./"
(file-name-as-directory (number-to-string (cl-first jc-lastdayList)))
(file-name-as-directory (my0Padding (cl-second jc-lastdayList)))
(file-name-as-directory (my0Padding (cl-third jc-lastdayList)))
"index.html\" hreflang=\"en\" rel=\"prev\" id=\"update1\">last day</a>"))
(newLastDayHref (concat "<a href=\"./"
(file-name-as-directory (number-to-string (cl-first jc-todayList)))
(file-name-as-directory (my0Padding (cl-second jc-todayList)))
(file-name-as-directory (my0Padding (cl-third jc-todayList)))
"index.html\" hreflang=\"en\" rel=\"prev\" id=\"update1\">last day</a>")))
(myReplace
oldLastDayHref
newLastDayHref
jc-tomorrowFile))
(find-file jc-todayIndex)
(find-file rootIndexFilePath)
(find-file jc-rssFile)
)
(defun myDailyRSSItem (title date desc)
"Insert the daily RSS feed with TITLE DATE and DESC."
(interactive (list
(read-string "Title: ")
(read-number "Date: " (cl-fourth (decode-time (float-time) t)))
(read-string "Description: ")))
(let* ((jc-myRSSTemplateContents (format jc-myRSSTemplate
title (cl-fifth (myDate date)) (cl-fourth (myDate date)) desc )))
(myInsert
jc-myRSSTemplateContents
"<!-- place new items above this line -->"
jc-rssFile)
))
(defun ManageDailyEntry ()
"Create the current page, update the main index, the RSS feed, the previous page."
)
(defun my0Padding (number)
"Add a 0 string to one digit NUMBER.
This is used here to represent dates as in 01/01/2021"
(string-pad (number-to-string number) 2 48 t))
(defun myDate (day)
"Create a plausible (year month DAY) list.
Since I only enter a date for the current entry, I must compute the
previous day and the next days according to what's plausible. It is
expected that I enter a possible date."
(let* (
(Today (decode-time (float-time)))
(thisMonth (cl-fifth Today))
(nextMonth (if (= 12 thisMonth)
1
(+ thisMonth 1)))
(lastMonth (if (= 1 thisMonth)
12
(- thisMonth 1)))
(thisYear (cl-sixth Today))
(nextYear (+ thisYear 1))
(lastYear (- thisYear 1))
(monthMaxDay
(cond
((member thisMonth '(1 3 5 7 8 10 12)) 31)
((member thisMonth '(4 6 9 11)) 30)
((and (= 2 thisMonth)
(= 0 (mod (cl-sixth (decode-time (float-time))) 4))) 29)
(t 28)))
(myDay (if (> day monthMaxDay) monthMaxDay day))
(dateDifference (- (cl-fourth Today) (abs myDay)))
(myMonth (cond ((> 24 (abs dateDifference)) thisMonth)
((natnump dateDifference) nextMonth)
(t lastMonth)))
(myYear (cond ((= myMonth thisMonth) thisYear)
((and (= myMonth nextMonth) (= myMonth 1)) nextYear)
(t lastYear)))
(rssDate (concat (format-time-string "%a, " (current-time) t)
(number-to-string myDay)
(format-time-string " %b %Y %H:%m:%S UT" (current-time) t)))
(linkDate (format "%1$s/%2$s/%3$s" myYear myMonth myDay)))
(list myYear myMonth myDay rssDate linkDate)))
(defun myInsert (myText myMarker myFile)
"Insert MYTEXT at MYMARKER in MYFILE.
This is used to insert the RSS part of the feed for that day
at the end of the file, before the closing headers."
(save-current-buffer
(set-buffer (find-file-noselect myFile))
(goto-char (point-min))
(if (not (search-forward myMarker nil t))
(progn
(kill-buffer)
(user-error (format "%s was not found" myMarker)))
(progn
(goto-char (point-min))
(goto-char (- (search-forward myMarker) (length myMarker)))
(insert myText)
(indent-region (point-min) (point-max))
(save-buffer)
(kill-buffer)))))
(defun myReplace (fromString toString myFile)
"Replace fromString with toString in MYFILE."
(save-current-buffer
(set-buffer (find-file-noselect myFile))
(goto-char (point-min))
(if (not (search-forward fromString nil t))
(progn
(kill-buffer)
(user-error (format "%s was not found" fromString)))
(progn
(goto-char (point-min))
(replace-string fromString toString)
(save-buffer)
(kill-buffer)))))
(defun narrowToEditZone ()
"Narrow the index page to the area to edit."
)
(provide 'adventuresintechland)