Start a wiki-like notepad. Features currently: list and interpret the content of the notepad directory.

This commit is contained in:
Feufochmar 2021-05-03 18:47:22 +02:00
parent 71e8fbf083
commit 6e5b6320f5
2 changed files with 183 additions and 1 deletions

View File

@ -17,7 +17,8 @@
"src/pages/yggdrasil.rkt"
"src/pages/flag.rkt"
"src/pages/road-map.rkt"
"src/pages/island.rkt")
"src/pages/island.rkt"
"src/pages/notepad.rkt")
; Website
(define *website*
(website
@ -75,6 +76,11 @@
("vraie" weblet pages:arnytron-real)
("vraie/{date}" matching-weblet pages:arnytron-real)
)
; Notepad
("notes" symlink "/notes/list"
("list" weblet pages:notepad:page-list)
("show/{page}" matching-weblet pages:notepad:page-show)
)
))
; Sitemap
(sitemap
@ -110,6 +116,8 @@
("Vraie citation" "/ArnYtron3000/vraie" #t)
("À propos d'ArnYtron3000" "/ArnYtron3000/About" #t)
)
("Bloc-Note" "/notes" #t
)
)
; Webcontainer
(define *webcontainer* (make-webcontainer))

174
src/pages/notepad.rkt Normal file
View File

@ -0,0 +1,174 @@
#lang racket/base
; Notepad application
(require
"templates.rkt"
"../webcontainer/weblets.rkt"
"../webcontainer/weblet-parameter.rkt"
(prefix-in scrib: scribble/reader)
)
(provide
pages:notepad:page-list
pages:notepad:page-show
)
; Notepad directory
(define notepad-dir "notepad")
; Page not found
(define (not-found page)
(make-immutable-hash
'((error-code . 404)
(author . "404")
(title . "Not found")
(content . (article "Sorry, there is nothing here."))
)))
; Notepad pages
; /notes/list
; Lists all the pages of the notepad.
(define pages:notepad:page-list
(pages:template
#:title "Pages du bloc-note."
#:author "feuforeve.fr"
#:content
(lambda (param)
(define notes (map path->string (directory-list notepad-dir)))
(if (null? notes)
'(article "Pas de notes.")
`(article
,@(map
(lambda (x)
`(div (a ((href ,(string-append "/notes/show/" x))) ,x)))
notes))))
))
; /notes/show/xxx
; Show a given page of the notepad. A page is stored under a scribble-like format.
; If the page does not exists and user is logged in, redirect to the /notes/edit/xxx page.
(define pages:notepad:page-show
(pages:adaptable-template
(lambda (param)
(define page (weblet-parameter-ref param 'page #f))
(define file (and page (string-append notepad-dir "/" page)))
(define has-page? (file-exists? file))
(cond
(has-page?
; Read the file and parse it into a list structure with scribble
(define parsed
(call-with-input-file file
(lambda (in) (scrib:read-inside in))))
; Collect metadata and transform the structure into the content
(define (collect-result parsed hsh)
; Recursively apply the parsing:
; - filter out #f values (metadata tags)
; - Two successive "\n" (i.e a blank line) are replaced by a '(br)
(define (recur lst)
(filter
values
(map
(lambda (x) (collect-result x hsh))
(reverse
(foldl
(lambda (val res)
(if (and (not (null? res))
(equal? "\n" val)
(equal? "\n" (car res)))
(cons '(br) res)
(cons val res)))
'()
lst)))))
; Parse and transform the content
(cond
; Not a list => output as is
((not (list? parsed)) parsed)
(#t
(case (car parsed)
; @title{Title} : metadata: title of the page
; @author{Author} : metadata: author of the page
; @date{Date} : metadata: date of the page
((title author date)
(hash-set! hsh (car parsed) (apply string-append (cdr parsed)))
#f)
; @link["path"]{Text} : content: link to another page
((link)
`(a ((href ,(cadr parsed)))
,@(recur (cddr parsed))))
; @image["path"]{Alt text} : content: image
((image)
(define alt (apply string-append (cddr parsed)))
`(img ((src ,(cadr parsed))
(alt ,alt)
(title ,alt))))
; @strong{Text} : content : strong
; @str{Text} : content : strong
((strong str)
`(strong ,@(recur (cdr parsed))))
; @emphase{Text} : content : emphase
; @emp{Text} : content : emphase
((emphase emp)
`(em ,@(recur (cdr parsed))))
; @section{Text} : content : title and start of section
((section)
`(h2 ,@(recur (cdr parsed))))
; @subsection{Text} : content : title and start of subsection
((subsection)
`(h3 ,@(recur (cdr parsed))))
; @subsubsection{Text} : content : title and start of subsubsection
((subsubsection)
`(h4 ,@(recur (cdr parsed))))
; @paragraph[justify]{Text} : content : paragraph with an optional justification
; @para[justify]{Text} : content : paragraph with an optional justification
((paragraph para)
(if (not (null? (cdr parsed)))
(case (cadr parsed)
((left) `(p ((style "text-align: left;")) ,@(recur (cddr parsed))))
((right) `(p ((style "text-align: right;")) ,@(recur (cddr parsed))))
((center centered) `(p ((style "text-align: center;")) ,@(recur (cddr parsed))))
(else `(p ,@(recur (cdr parsed)))))
#f))
; Other kind of lists: recursed on them
(else
(recur parsed))
))))
(define result (make-hash))
(hash-set! result 'content `(article ,@(collect-result parsed result)))
result)
(#t
(not-found page))))))
; /notes/new
; Create a new page. User must be logged in.
; /notes/edit/xxx
; Edit an existing page, or create a new page with a given title. User must be logged in.
; /notes/delete/xxx
; Remove an existing page. User must be logged in.
; /media/list
; Lists all medias of the notepad.
; /media/show/xxx
; Show a given media of the notepad, with its metadata.
; /media/get/xxx
; Get a given media of the notepad. Direct link.
; /media/new
; Add a media. User must be logged in.
; /media/delete/xxx
; Remove an existing media. User must be logged in.
; /user/list
; Lists all the users of the notepad.
; /user/show/xxx
; Show the page of user xxx.
; /user/login
; Login page.
; /user/logout
; Logout page.