Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Allow to quote every single posts as comma separated values. Deduplicate regex code |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | origin/master | trunk |
Files: | files | file ages | folders |
SHA3-256: |
a47867c42f34156ae332979bf512c17e |
User & Date: | ben.bitdiddle@protonmail.com 2020-06-11 01:29:38 |
Context
2020-06-11
| ||
11:42 | display the list of boards on top of pages check-in: c5926fd0ab user: ben.bitdiddle@protonmail.com tags: origin/master, trunk | |
01:29 | Allow to quote every single posts as comma separated values. Deduplicate regex code check-in: a47867c42f user: ben.bitdiddle@protonmail.com tags: origin/master, trunk | |
2020-06-10
| ||
21:51 | add board list check-in: 079fd1a4a6 user: ben.bitdiddle@protonmail.com tags: origin/master, trunk | |
Changes
Changes to bbs.scm.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 .. 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 ... 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 ... 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 ... 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
(load-option 'format) (load "lib/utils") (load "deps/irregex") (load "deps/srfi-26") (load "deps/httpio") (load "deps/server") (load "lib/html") (load "lib/parameters") (load "lib/markup") (load "templates") (define *sexp* "data/sexp") (define *html* "data/html") (define *frontpage-threads* 10) (define *max-headline-size* 78) (define *max-post-size* 8192) (define *max-posts* 300) (define *board-list* (map pathname-name (cddr (directory-read "data/sexp/*")))) (define (get-form-hash) "TODO" (call-with-input-file "hash" read)) ;;; helpers ................................................................................ (define (route req) (let* ((fullpath (uri->string (http-request-uri req))) (path (string-split (ignore-qstring fullpath) #\/)) (query-string (get-query-string fullpath)) (method (http-request-method req)) (headers (http-request-headers req)) (ip (http-header 'x-forwarded-for headers #f))) ;(pp ip) (pp req) ;(pp headers) (pp (http-header 'x-forwarded-for headers #f)) ;(pp (http-header 'host headers #f)) (cond ((equal? method "GET") (match path (() () '(200 () "site root")) ((,board) () (view-index board)) ((,board "list") () (view-list board)) ((,board "preferences") () (set-preferences board query-string)) ((,board ,thread) (integer? (string->number thread)) (view-thread board thread)) ((,board ,thread ,posts) (and (integer? (string->number thread)) (range? posts) (< (string-length posts) 40)) (view-thread board thread posts)) (_ () not-found))) ((equal? method "POST") (match path ((,board "post") () (post-thread board req query-string)) ((,board ,thread "post") (integer? (string->number thread)) (post-message board thread req query-string)) (_ () method-not-allowed))) (else method-not-allowed)))) ;;; errors (define bad-request `(400 () "Bad Request")) (define not-found `(404 () "Not found")) (define method-not-allowed '(405 () "Method not allowed")) (define (title board) (string-append "/" board "/ - SchemeBBS")) ;;; views (define (thread-template board thread posts headline filter-func) (main-template (title board) (thread-view board thread posts headline filter-func) "thread")) (define (list-template board threads) (main-template (title board) (list-view board threads))) ................................................................................ (rangeonce (if norange "unused" (posts-range range))) (filter-func (if norange (lambda (e) #t) (lambda (e) (vector-ref rangeonce (car e)))))) (cond (norange (if (not (file-exists? cache)) (write-and-serve cache (thread-template board thread posts headline filter-func)) (serve-file cache))) ;; we shouldn't go here, reverse proxy fetches the page itself ((and (string->number range) (> (string->number range) (length posts))) not-found) (else (make-response (thread-template board thread posts headline filter-func)))))) (else not-found)))) (define (range? posts) (irregex-match "[1-9][0-9]{0,2}(-[1-9][0-9]{0,2})?(,[1-9][0-9]{0,2}(-[1-9][0-9]{0,2})?){0,20}" posts)) (define (posts-range range) (define (expand-range x) (cond ((> (length x) 1) (let* ((a (string->number (car x))) (b (string->number (cadr x))) (low (if (> a *max-posts*) *max-posts* a)) ................................................................................ (define (view-list board) (let* ((path (make-path *sexp* board "list")) (cache (make-path *html* board "list")) (threads (if (file-exists? path) (call-with-input-file path read) '()))) (cond ((file-exists? path) (if (not (file-exists? cache)) (write-and-serve cache (list-template board threads)) (serve-file cache))) ;; we shouldn't go there with a reverse proxy (else not-found)))) (define (view-index board) (let* ((path (make-path *sexp* board "index")) (cache (make-path *html* board "index")) (threads (if (file-exists? path) (call-with-input-file path read) ................................................................................ (cons thread threads) (cons thread (take threads (dec *frontpage-threads*))))))))) (define (get-next-thread-number threads) (if (null? threads) 1 (inc (apply max (map car threads))))) (define (validate-form params message #!optional headline) (let ((fake-message (lookup-def 'message params "")) (fake-name (lookup-def 'name params "")) (hash (lookup-def 'ornamentum params ""))) (cond ((and (not (default-object? headline)) (string-null? headline)) '(empty-headline . "New threads must have a headline")) |
> > > > > > > > > < < < < < < < < > > | > > > > > | > | | | | < |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 .. 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 ... 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 ... 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 ... 374 375 376 377 378 379 380 381 382 383 384 385 386 387 |
(define *sexp* "data/sexp") (define *html* "data/html") (define *frontpage-threads* 10) (define *max-headline-size* 78) (define *max-post-size* 8192) (define *max-posts* 300) (define *board-list* (map pathname-name (cddr (directory-read "data/sexp/*")))) (define *range-regex* "[1-9][0-9]{0,2}(-[1-9][0-9]{0,2})?(,[1-9][0-9]{0,2}(-[1-9][0-9]{0,2})?)") (load-option 'format) (load "lib/utils") (load "deps/irregex") (load "deps/srfi-26") (load "deps/httpio") (load "deps/server") (load "lib/html") (load "lib/parameters") (load "lib/markup") (load "templates") (define (get-form-hash) "TODO" (call-with-input-file "hash" read)) ;;; helpers ................................................................................ (define (route req) (let* ((fullpath (uri->string (http-request-uri req))) (path (string-split (ignore-qstring fullpath) #\/)) (query-string (get-query-string fullpath)) (method (http-request-method req)) (headers (http-request-headers req)) (ip (http-header 'x-forwarded-for headers #f))) ;TODO: logging ;(pp ip) (pp req) ;(pp headers) (pp (http-header 'x-forwarded-for headers #f)) ;(pp (http-header 'host headers #f)) (cond ((equal? method "GET") (match path (() () '(200 () "site root")) ((,board) () (view-index board)) ((,board "list") () (view-list board)) ((,board "preferences") () (set-preferences board query-string)) ((,board ,thread) (integer? (string->number thread)) (view-thread board thread)) ((,board ,thread ,posts) (and (integer? (string->number thread)) (range? posts) ; on slower hardware you should change (* *max-posts* 8) below to a lesser value ; see also the posts-range function and lib/markup.scm:quotelink (< (string-length posts) (* *max-posts* 8))) (view-thread board thread posts)) (_ () not-found))) ((equal? method "POST") (match path ((,board "post") () (post-thread board req query-string)) ((,board ,thread "post") (integer? (string->number thread)) (post-message board thread req query-string)) (_ () method-not-allowed))) (else method-not-allowed)))) ;;; errors (define bad-request `(400 () "Bad Request")) (define not-found `(404 () "Not found")) (define method-not-allowed '(405 () "Method not allowed")) (define (title board) (string-append "/" board "/ - SchemeBBS")) ;;; views (define (thread-template board thread posts headline filter-func) (main-template (title board) (thread-view board thread posts headline filter-func) "thread")) (define (list-template board threads) (main-template (title board) (list-view board threads))) ................................................................................ (rangeonce (if norange "unused" (posts-range range))) (filter-func (if norange (lambda (e) #t) (lambda (e) (vector-ref rangeonce (car e)))))) (cond (norange (if (not (file-exists? cache)) (write-and-serve cache (thread-template board thread posts headline filter-func)) (serve-file cache))) ((and (string->number range) (> (string->number range) (length posts))) not-found) ; TODO: doesn't return a 404 for ranges of inexistent posts (else (make-response (thread-template board thread posts headline filter-func)))))) (else not-found)))) (define (range? posts) (irregex-match (string-append *range-regex* "{0," (number->string *max-posts*) "}") posts)) (define (posts-range range) (define (expand-range x) (cond ((> (length x) 1) (let* ((a (string->number (car x))) (b (string->number (cadr x))) (low (if (> a *max-posts*) *max-posts* a)) ................................................................................ (define (view-list board) (let* ((path (make-path *sexp* board "list")) (cache (make-path *html* board "list")) (threads (if (file-exists? path) (call-with-input-file path read) '()))) (cond ((file-exists? path) (if (not (file-exists? cache)) (write-and-serve cache (list-template board threads)) (serve-file cache))) (else not-found)))) (define (view-index board) (let* ((path (make-path *sexp* board "index")) (cache (make-path *html* board "index")) (threads (if (file-exists? path) (call-with-input-file path read) ................................................................................ (cons thread threads) (cons thread (take threads (dec *frontpage-threads*))))))))) (define (get-next-thread-number threads) (if (null? threads) 1 (inc (apply max (map car threads))))) (define (validate-form params message #!optional headline) (let ((fake-message (lookup-def 'message params "")) (fake-name (lookup-def 'name params "")) (hash (lookup-def 'ornamentum params ""))) (cond ((and (not (default-object? headline)) (string-null? headline)) '(empty-headline . "New threads must have a headline")) |
Changes to lib/markup.scm.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 .. 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 ... 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 ... 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
;(load "utils/irregex/irregex") (define markup->sxml) (let () ;;; global vars, needed for quotelinks (define *board* #f) (define *thread* #f) ;;; utils (define (empty-line? line) (or (string-null? line) (irregex-match '(* white) line))) (define (add-line-to-block blocks line tag) (if (null? blocks) `((,tag ,line)) (let ((last-block-tag (caar blocks)) (last-block-content (cdar blocks)) (other-blocks (cdr blocks))) ................................................................................ (define (join l res) (if (null? l) res (join (cdr l) (string-append (car l) "\n" res)))) (let ((lines (cdr codeblock))) `(pre (code ,(join (cdr lines) (car lines)))))) ;;; (define (format-blockquote bq) (define (make-paragraphs l res) (cond ((null? l) (if (for-all? (cdar res) empty-line?) (cdr res) res)) ((and (empty-line? (car l)) (or (null? res) (null? (cdar res)))) (make-paragraphs (cdr l) res)) ((empty-line? (car l)) (make-paragraphs (cdr l) (add-empty-tag res 'p))) ................................................................................ (cond ((string? e) (string->sxml markup e)) ((eq? (car e) 'del) `(,(cons 'del (lines->sxml markup (cdr e))))) (else `(,e)))) l)) (define (transform-rule name regex transform) (define (dispatch op) (cond ((eq? op 'name) name) ((eq? op 'regex) regex) ((eq? op 'transform) transform))) dispatch) ................................................................................ 'del (irregex "~~[^ ].*?[^ ]~~|~~[^ ]~~") (lambda (sub) `(del ,(substring sub 2 (- (string-length sub) 2)))))) (define quotelink (transform-rule 'quotelink (irregex ">>[1-9][0-9]{0,2}(-[1-9][0-9]{0,2})?(,[1-9][0-9]{0,2}(-[1-9][0-9]{0,2})?){0,20}") (lambda (sub) `(a (@ (href ,(string-append "/" *board* "/" *thread* "/" (string-tail sub 2)))) ,sub)))) (define link (transform-rule 'link (irregex "https?:\/\/[^ \n]*") (lambda (sub) `(a (@ (href ,sub)) ,sub)))) (define line-scanner-order (list del code link quotelink bold italic)) (define (line-scanner l) ((apply compose (map (lambda (tr) (partial lines->sxml tr)) line-scanner-order)) l)) |
< < < < < < | < |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 .. 66 67 68 69 70 71 72 73 74 75 76 77 78 79 ... 134 135 136 137 138 139 140 141 142 143 144 145 146 147 ... 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
(define markup->sxml) (let () ;;; global vars, needed for quotelinks (define *board* #f) (define *thread* #f) ;;; utils (define (empty-line? line) (or (string-null? line) (irregex-match '(* white) line))) (define (add-line-to-block blocks line tag) (if (null? blocks) `((,tag ,line)) (let ((last-block-tag (caar blocks)) (last-block-content (cdar blocks)) (other-blocks (cdr blocks))) ................................................................................ (define (join l res) (if (null? l) res (join (cdr l) (string-append (car l) "\n" res)))) (let ((lines (cdr codeblock))) `(pre (code ,(join (cdr lines) (car lines)))))) (define (format-blockquote bq) (define (make-paragraphs l res) (cond ((null? l) (if (for-all? (cdar res) empty-line?) (cdr res) res)) ((and (empty-line? (car l)) (or (null? res) (null? (cdar res)))) (make-paragraphs (cdr l) res)) ((empty-line? (car l)) (make-paragraphs (cdr l) (add-empty-tag res 'p))) ................................................................................ (cond ((string? e) (string->sxml markup e)) ((eq? (car e) 'del) `(,(cons 'del (lines->sxml markup (cdr e))))) (else `(,e)))) l)) (define (transform-rule name regex transform) (define (dispatch op) (cond ((eq? op 'name) name) ((eq? op 'regex) regex) ((eq? op 'transform) transform))) dispatch) ................................................................................ 'del (irregex "~~[^ ].*?[^ ]~~|~~[^ ]~~") (lambda (sub) `(del ,(substring sub 2 (- (string-length sub) 2)))))) (define quotelink (transform-rule 'quotelink (irregex (string-append ">>" *range-regex* "{0," (number->string (- *max-posts* 1)) "}")) (lambda (sub) `(a (@ (href ,(string-append "/" *board* "/" *thread* "/" (string-tail sub 2)))) ,sub)))) (define link (transform-rule 'link (irregex "https?:\/\/[^ \n]*") (lambda (sub) `(a (@ (href ,sub)) ,sub)))) (define line-scanner-order (list del code link quotelink bold italic)) (define (line-scanner l) ((apply compose (map (lambda (tr) (partial lines->sxml tr)) line-scanner-order)) l)) |