1
0
Fork 0

Compare commits

...

15 commits

Author SHA1 Message Date
cc4ce6cad4 Merge remote-tracking branch 'origin/master' into customizations 2023-09-06 15:17:33 -07:00
Andy Wingo
21793fb83e Allow \r in pre terminators 2022-12-10 21:41:13 +01:00
Andy Wingo
f290d7c2c7 Allow tt in comments, class in pre 2022-11-29 10:19:11 +01:00
Andy Wingo
17905ace44 Fix online classifier update 2022-11-29 10:16:30 +01:00
Andy Wingo
ba9a560f01 Fix html translation 2022-10-23 21:48:57 +02:00
Andy Wingo
304f8839ec Hopefully fix paragraph parsing 2022-10-23 21:45:43 +02:00
Andy Wingo
105873854c Fix list parsing 2022-10-23 17:30:36 +02:00
Andy Wingo
7652cb17cf Implement heading parsing 2022-10-23 09:45:52 +02:00
Andy Wingo
5f1620e0e7 Handle CR/LF in marxdown; fix trailing ! in paragraphs 2022-10-22 09:55:07 +02:00
Andy Wingo
4a9766c6c1 Fix emph lowering 2022-10-20 23:26:35 +02:00
d34a14b3d6 Merge branch 'initial-startup-fix' into customizations 2021-05-30 19:27:03 -07:00
6da1ed8fd2 Fix some “Numerical overflow” errors
When starting a new blog, or trying to run on some very old data, there is no
data available on any bogus or legitimate comments. When this happens Tekuti
will try to divide by 0 and divide 0 by other things in a few places, assuming
that there is at least _some_ data about bogus and legitimate comments.

I’m not 100% sure what the expectation is of these calculations, so I might have
chosen the wrong solution, but it seems to me that if there is no data
available, all we know is that there is nothing (0).

This fixes an issue with both trying to comment on a fresh new data set, or a
dataset that hasn’t been touched since 2014.
2021-05-30 01:21:47 -07:00
480c050275 Check that a revision has been provided before trying to parse it
When setting up Tekuti for the first time the ‘compute-bogus-comments’ will get
the current commit passed in and try to get the parent. Since there is only the
“initial commit” at this stage it will get ‘#f’ as the parent commit and pass it
in to ‘fold-commits’. Trying to parse revision ‘#f’ will surely fail.

The ‘fold-commits’ function already expects that ‘rev’ might be empty, so this
should work out fine.
2021-05-30 01:16:48 -07:00
a2c76e586e Reverse tag page posts order
So the newest post comes out on top.
2013-04-03 03:36:19 +02:00
ea8c3a5642 Make tag page look more like index
Blurr the distinction between the index page and a tag page so that
tag pages may be used as stand-alone pages.
2013-04-03 03:16:02 +02:00
6 changed files with 154 additions and 58 deletions

View file

@ -114,16 +114,22 @@
(lambda (feature bogus-count) (lambda (feature bogus-count)
(let ((legit-count (hash-ref legit-features feature 0))) (let ((legit-count (hash-ref legit-features feature 0)))
(hash-set! log-bogosities feature (hash-set! log-bogosities feature
(if (and (> total-bogus-features 0)
(> total-legit-features 0))
(log (/ (/ (+ bogus-count 0.001) total-bogus-features) (log (/ (/ (+ bogus-count 0.001) total-bogus-features)
(/ (+ legit-count 0.001) total-legit-features)))))) (/ (+ legit-count 0.001) total-legit-features)))
0))))
bogus-features) bogus-features)
(hash-for-each (hash-for-each
(lambda (feature legit-count) (lambda (feature legit-count)
(let ((bogus-count (hash-ref bogus-features feature))) (let ((bogus-count (hash-ref bogus-features feature)))
(unless bogus-count (unless bogus-count
(hash-set! log-bogosities feature (hash-set! log-bogosities feature
(if (and (> total-bogus-features 0)
(> total-legit-features 0))
(log (/ (/ 0.01 total-bogus-features) (log (/ (/ 0.01 total-bogus-features)
(/ (+ legit-count 0.01) total-legit-features))))))) (/ (+ legit-count 0.01) total-legit-features)))
0)))))
legit-features) legit-features)
log-bogosities)) log-bogosities))
@ -256,7 +262,9 @@
(with-time-debugging (with-time-debugging
(let* ((legit-count (hash-count (const #t) legit-comments)) (let* ((legit-count (hash-count (const #t) legit-comments))
(bogus-count (hash-count (const #t) bogus-comments)) (bogus-count (hash-count (const #t) bogus-comments))
(legit-prior (/ legit-count (+ legit-count bogus-count 0.0))) (legit-prior (if (> legit-count 0)
(/ legit-count (+ legit-count bogus-count 0.0))
0))
(legit-features (count-features legit-comments)) (legit-features (count-features legit-comments))
(bogus-features (count-features bogus-comments)) (bogus-features (count-features bogus-comments))
(bogosities (compute-log-bogosities legit-features bogus-features))) (bogosities (compute-log-bogosities legit-features bogus-features)))
@ -283,13 +291,19 @@
(assq-ref index 'master)))) (assq-ref index 'master))))
(let ((removed-features (count-features removed)) (let ((removed-features (count-features removed))
(added-features (count-features added))) (added-features (count-features added)))
;; If a comment passes the spam filter, it gets added, and is
;; presumed legitimate. It could then be reverted, in which
;; case we should remove its features from the legitimate count
;; and add them to the bogus count.
(hash-for-each (lambda (k v) (hash-for-each (lambda (k v)
(remove-feature! legit-features k v) (remove-feature! legit-features k v)
(add-feature! bogus-features k v)) (add-feature! bogus-features k v))
removed-features) removed-features)
(hash-for-each (lambda (k v) (hash-for-each (lambda (k v)
(add-feature! legit-features k v) ;; Asymmetry with removed-features; the
(remove-feature! bogus-features k v)) ;; comment wasn't previously marked bogus, so
;; we just add its features to the legit set.
(add-feature! legit-features k v))
added-features) added-features)
(update-bogosities! bogosities removed-features (update-bogosities! bogosities removed-features
legit-features bogus-features) legit-features bogus-features)

View file

@ -94,6 +94,9 @@
(define (marxdown->sxml text) (define (marxdown->sxml text)
(smarxdown->shtml (call-with-input-string text marxdown->smarxdown))) (smarxdown->shtml (call-with-input-string text marxdown->smarxdown)))
(define (pre-class? class)
(string-prefix? "pre-" class))
(define *allowed-tags* (define *allowed-tags*
`((a (href . ,urlish?) title) `((a (href . ,urlish?) title)
(abbr title) (abbr title)
@ -105,9 +108,10 @@
(em) (em)
(i) (i)
(p) (p)
(pre) (pre (class . ,pre-class?))
(strike) (strike)
(strong))) (strong)
(tt)))
(define (compile-sxslt-rules tags) (define (compile-sxslt-rules tags)
(define (ok . body) (define (ok . body)

View file

@ -334,7 +334,7 @@
(cons (string->symbol k) v)))))) (cons (string->symbol k) v))))))
(define (fold-commits f rev seed) (define (fold-commits f rev seed)
(let lp ((rev (git-rev-parse rev)) (seed seed)) (let lp ((rev (and rev (git-rev-parse rev))) (seed seed))
(if rev (if rev
(let ((commit (parse-commit rev))) (let ((commit (parse-commit rev)))
(lp (assq-ref commit 'parent) (lp (assq-ref commit 'parent)

View file

@ -132,13 +132,28 @@
(unget chars)))) (unget chars))))
(define (next) (get-char port)) (define (next) (get-char port))
(define (peek) (peek-char port))
(define (next-not-eof ctx) (define (next-not-eof ctx)
(let ((ch (next))) (let ((ch (next)))
(if (eof-object? ch) (if (eof-object? ch)
(error "EOF while reading" ctx) (error "EOF while reading" ctx)
ch))) ch)))
(define (next-line-and-delim) (read-line port 'split)) (define (next-line-and-delim)
(define (peek) (peek-char port)) (let lp ((chars '()))
(define (finish delim)
(cons (reverse-list->string chars) delim))
(let ((ch (next)))
(cond
((eof-object? ch) (finish ch))
((eqv? ch #\return)
(if (eqv? (peek) #\newline)
(finish (next))
(lp (cons ch chars))))
((eqv? ch #\newline)
(finish ch))
(else
(lp (cons ch chars)))))))
(define (skip-whitespace k) (define (skip-whitespace k)
(let lp ((indent 0)) (let lp ((indent 0))
@ -212,7 +227,10 @@
(else (kt))))) (else (kt)))))
(#\newline (#\newline
;; Sure. Trailing whitespace can be any indent. ;; Sure. Trailing whitespace can be any indent.
(unget1 #\newline)
(kt)) (kt))
(#\return
(lp n))
(ch (ch
(unless (eof-object? ch) (unget1 ch)) (unless (eof-object? ch) (unget1 ch))
(kf))))))) (kf)))))))
@ -347,12 +365,14 @@
(let lp ((chars '())) (let lp ((chars '()))
(match (next-not-eof "backticks") (match (next-not-eof "backticks")
(#\` (continue `(code ,(reverse-list->string chars)))) (#\` (continue `(code ,(reverse-list->string chars))))
(#\return (lp chars))
(#\newline (#\newline
(consume-indent (consume-indent
indent indent
(lambda () (lambda ()
(match (next-not-eof "code") (match (next-not-eof "code")
(#\newline (error "end of block while reading code")) ((or #\return #\newline)
(error "end of block while reading code"))
(ch (unget1 ch) (lp (cons #\space chars))))) (ch (unget1 ch) (lp (cons #\space chars)))))
(lambda () (error "end of block while reading code")))) (lambda () (error "end of block while reading code"))))
(ch (lp (cons ch chars)))))) (ch (lp (cons ch chars))))))
@ -373,14 +393,25 @@
(lp elts (cons (list->string chars) out)))))) (lp elts (cons (list->string chars) out))))))
((elt . elts) ((elt . elts)
(lp elts (cons elt out)))))) (lp elts (cons elt out))))))
(define (consume-blank-lines-then-finish kdone)
(let lp ()
(match (next)
((? eof-object?) (finish kdone))
(#\return (lp))
(#\newline
(consume-indent indent lp (lambda () (finish kdone))))
(ch
(unget1 ch)
(finish kdone)))))
(match (next) (match (next)
((? eof-object?) (finish on-block-end)) ((? eof-object?) (finish on-block-end))
(#\return (lp elts))
(#\newline (#\newline
(consume-indent (consume-indent
indent indent
(lambda () (lambda ()
(cond (cond
((done? #\newline) => finish) ((done? #\newline) => consume-blank-lines-then-finish)
(else (lp (cons #\newline elts))))) (else (lp (cons #\newline elts)))))
(lambda () (lambda ()
(finish on-block-end)))) (finish on-block-end))))
@ -403,7 +434,9 @@
(match link (match link
(('link dest . alt) (('link dest . alt)
(continue `(image ,dest . ,alt))))))) (continue `(image ,dest . ,alt)))))))
(ch (lp (cons* ch #\! elts))))) (ch
(unget1 ch)
(lp (cons #\! elts)))))
(ch (lp (cons ch elts)))))) (ch (lp (cons ch elts))))))
(define (read-para indent kup knext) (define (read-para indent kup knext)
@ -414,7 +447,7 @@
(define (done? ch) (define (done? ch)
(match ch (match ch
(#\newline (#\newline
(let ((ch (next))) (let lp ((ch (next)))
(match ch (match ch
((? eof-object?) ((? eof-object?)
(lambda (para) (lambda (para)
@ -422,9 +455,13 @@
(ch (ch
(read-block-type ch #t (read-block-type ch #t
make-continuation make-continuation
(if (eqv? ch #\newline)
(lambda (chars) (lambda (chars)
(unget chars) (unget chars)
#f)))))) (make-continuation read-para))
(lambda (chars)
(unget chars)
#f)))))))
(_ #f))) (_ #f)))
(read-text 'para indent done? (make-continuation read-block-list))) (read-text 'para indent done? (make-continuation read-block-list)))
@ -432,10 +469,21 @@
(unget chars) (unget chars)
(read-para indent kup knext)) (read-para indent kup knext))
(define (read-heading level knext) (define (read-heading level indent continue)
(error "unimplemented")) (let ((continue (lambda (heading)
(match heading
(('heading . body)
(continue `(heading ,level . ,body)))))))
(read-text 'heading indent (lambda (ch)
(and (eqv? ch #\newline) continue))
continue)))
(define (read-li marker marker-indent marker-size kup knext) (define (read-li marker marker-indent marker-size kup knext)
(define list-tag
(match marker
((? number?) 'enumerate)
((? char?) 'itemize)))
(define (list-tag? tag) (eq? tag list-tag))
(read-indent (read-indent
(lambda (ch indent) (lambda (ch indent)
(match indent (match indent
@ -446,23 +494,19 @@
(append marker-outer (append marker-outer
(list (+ marker-inner marker-size outer)) (list (+ marker-inner marker-size outer))
inner))) inner)))
(pk 'hey marker marker-indent marker-size indent body-indent ch) (read-block
ch body-indent
(lambda (blocks ch next-indent)
(read-indented-block (read-indented-block
ch marker-indent body-indent ch marker-indent next-indent kup
(lambda (elt ch indent)
(pk ch marker-indent indent elt)
(read-indented-block ch marker-indent indent kup
(lambda (nodelist) (lambda (nodelist)
(knext (cons elt nodelist))))) (knext
(lambda (nodelist) (match nodelist
(cons* 'li marker nodelist))))))))))) ((((? list-tag?) . items) . nodelist)
`((,list-tag (item . ,blocks) . ,items) . ,nodelist))
(define (read-block ch indent kup knext) (_
(define (have-block read-block) `((,list-tag (item . ,blocks)) . ,nodelist)))))))
(read-block indent kup knext)) identity)))))))))
(define (have-text chars)
(read-para* chars indent kup knext))
(read-block-type ch #f have-block have-text))
(define (read-block-type ch in-text? kblock ktext) (define (read-block-type ch in-text? kblock ktext)
(define (make-continue indent kup knext) (define (make-continue indent kup knext)
@ -479,7 +523,8 @@
(#\space (#\space
(kblock (kblock
(lambda (indent kup knext) (lambda (indent kup knext)
(read-heading level (make-continue indent kup knext))))) (read-heading level indent (make-continue indent kup knext)))))
(#\return (lp level))
(#\newline (#\newline
(kblock (kblock
(lambda (indent kup knext) (lambda (indent kup knext)
@ -552,6 +597,8 @@
(match (parse-one-xml-element port) (match (parse-one-xml-element port)
(#f (read-block-list indent kup knext)) (#f (read-block-list indent kup knext))
(elt ((make-continue indent kup knext) `(block-xml ,elt)))))))) (elt ((make-continue indent kup knext) `(block-xml ,elt))))))))
(#\return
(read-block-type (next-not-eof "newline") in-text? kblock ktext))
(#\newline (#\newline
;; fixme: record loose li ;; fixme: record loose li
(kblock read-block-list)) (kblock read-block-list))
@ -562,16 +609,31 @@
(_ (_
(ktext (list ch))))) (ktext (list ch)))))
(define (read-block ch indent kup knext)
(define (have-block read-block)
(read-block indent kup knext))
(define (have-text chars)
(read-para* chars indent kup knext))
(read-block-type ch #f have-block have-text))
(define (finish-block-list blocks)
(match blocks
((block) block)
(_ `(begin . ,blocks))))
(define (finish-block-quote blocks)
(match blocks
((block) block)
(_ `(blockquote . ,blocks))))
(define (read-indented-block ch outer-indent indent kup knext) (define (read-indented-block ch outer-indent indent kup knext)
(define (recurse kind recurse-indent) (define (recurse finish recurse-indent)
(read-indented-block ch recurse-indent indent (read-indented-block ch recurse-indent indent
(lambda (nested ch indent) (lambda (nested ch indent)
(read-indented-block ch outer-indent indent (read-indented-block ch outer-indent indent
kup kup
(lambda (nodelist) (lambda (nodelist)
(knext (cons nested nodelist))))) (knext (cons nested nodelist)))))
(lambda (nodelist) finish))
(cons kind nodelist))))
(match (compare-indents outer-indent indent) (match (compare-indents outer-indent indent)
('same ('same
(read-block ch indent kup knext)) (read-block ch indent kup knext))
@ -580,9 +642,10 @@
'different-blockquote) 'different-blockquote)
(kup (knext '()) ch indent)) (kup (knext '()) ch indent))
('inner ('inner
(recurse 'begin indent)) (recurse finish-block-list indent))
('inner-blockquote ('inner-blockquote
(recurse 'blockquote (list-head indent (1+ (length outer-indent))))))) (recurse finish-block-quote
(list-head indent (1+ (length outer-indent)))))))
(define (parse-error reason) (define (parse-error reason)
(error reason)) (error reason))
@ -594,7 +657,7 @@
(read-block-list empty-indent (read-block-list empty-indent
(lambda (nodelist ch indent) nodelist) (lambda (nodelist ch indent) nodelist)
(lambda (nodelist) (cons 'top nodelist)))) finish-block-list))
(define* (smarxdown->shtml exp #:key (define* (smarxdown->shtml exp #:key
(heading-offset 0) (heading-offset 0)
@ -603,9 +666,9 @@
(define (transform-inline exp) (define (transform-inline exp)
(match exp (match exp
(('inline-xml xml) (handle-inline-xml xml)) (('inline-xml xml) (handle-inline-xml xml))
(('code . body) exp) (('code . body) `(tt . ,body))
(('emph . body) `(emph . ,(map transform-inline body))) (('emph . body) `(i . ,(map transform-inline body)))
(('strong . body) `(strong . ,(map transform-inline body))) (('strong . body) `(b . ,(map transform-inline body)))
(('link dest . body) `(a (@ (href ,dest)) . ,(map transform-inline body))) (('link dest . body) `(a (@ (href ,dest)) . ,(map transform-inline body)))
((? string? str) str))) ((? string? str) str)))
(define (transform-block exp) (define (transform-block exp)
@ -613,7 +676,14 @@
(('block-xml xml) (handle-block-xml xml)) (('block-xml xml) (handle-block-xml xml))
(('para . body) `(p . ,(map transform-inline body))) (('para . body) `(p . ,(map transform-inline body)))
(('blockquote . body) `(blockquote . ,(map transform-block body))) (('blockquote . body) `(blockquote . ,(map transform-block body)))
(('list-item . body) (error "fixme")) (('itemize ('item . item) ...)
`(ul . ,(map (lambda (blocks)
`(li . ,(map transform-block blocks)))
item)))
(('enumerate ('item . item) ...)
`(ol . ,(map (lambda (blocks)
`(li . ,(map transform-block blocks)))
item)))
(('pre #f . body) `(pre . ,body)) (('pre #f . body) `(pre . ,body))
(('pre info . body) `(pre (@ (class ,(string-append "pre-" info))) (('pre info . body) `(pre (@ (class ,(string-append "pre-" info)))
. ,body)) . ,body))
@ -627,5 +697,5 @@
(else 'h6)))) (else 'h6))))
`(,tag . ,(map transform-inline body)))))) `(,tag . ,(map transform-inline body))))))
(match exp (match exp
(('top exp ...) (('begin exp ...)
`(div . ,(map transform-block exp))))) `(div . ,(map transform-block exp)))))

View file

@ -45,7 +45,7 @@
post-url post-url
post-editing-form post-editing-form
sidebar-ul top-tags tag-cloud sidebar-ul top-tags tag-cloud
main-sidebar post-sidebar related-tag-cloud main-sidebar post-sidebar tag-sidebar related-tag-cloud
post-link admin-post-url admin-post-link post-link admin-post-url admin-post-link
show-post with-authentication show-post with-authentication
find-posts-matching find-posts-matching
@ -540,6 +540,17 @@ present."
,(post-link (car post-and-tags)))) ,(post-link (car post-and-tags))))
(take-max (compute-related-posts post index) 10))))))) (take-max (compute-related-posts post index) 10)))))))
(define (tag-sidebar tag index)
(sidebar-ul
`((li (h2 (a (@ (href ,(relurl '("feed" "atom")
#:query `(("with" . ,tag)))))
"subscribe "
(img (@ (src ,(relurl '("wp-content" "feed-icon-14x14.png")))
(alt "[feed]"))))))
(li (h2 "related tags " ,(rellink '("tags") ">>"))
(ul (li (@ (style "line-height: 150%"))
,@(tag-cloud (compute-related-tags tag index))))))))
(define (related-tag-cloud tag index) (define (related-tag-cloud tag index)
`(div (@ (id "tag-cloud")) `(div (@ (id "tag-cloud"))
(h2 "related tags") (h2 "related tags")

View file

@ -301,13 +301,10 @@
(post-from-key index key)) (post-from-key index key))
(hash-ref tags tag '())))) (hash-ref tags tag '()))))
(if (pair? posts) (if (pair? posts)
(respond `((h2 "posts tagged \"" ,tag "\" (" (respond `(,(tag-sidebar tag index)
,(rellink '("feed" "atom") "feed" (h2 "posts tagged \"" ,tag "\"")
#:query `(("with" . ,tag))) ,@(map (lambda (post) (show-post post #f))
")") (take-max (reverse posts) 10)))
,@(map (lambda (post) `(p ,(post-link post)))
posts)
,(related-tag-cloud tag index))
#:etag (assq-ref index 'master) #:etag (assq-ref index 'master)
#:title (string-append "posts tagged \"" tag "\"")) #:title (string-append "posts tagged \"" tag "\""))
(respond `((h2 "Unknown tag " ,tag) (respond `((h2 "Unknown tag " ,tag)