Created
August 14, 2018 23:58
-
-
Save otherjoel/eec9ac921ab9123ec3dcfe17118d4bfa to your computer and use it in GitHub Desktop.
Example module that replaces the last space in a tagged X-expression with the HTML nbsp entity
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang racket | |
(require txexpr) | |
(define (string-reverse str) | |
(list->string (reverse (string->list str)))) | |
(define (replace-first-space str) | |
(string-replace str " " " " #:all? #f)) | |
(define (replace-last-space str) | |
(string-reverse (string-replace (string-reverse str) " " ";psbn&" #:all? #f))) | |
(define (nbsp xpr [found? #f]) | |
(cond | |
[found? (values xpr found?)] | |
[(and (string? xpr) (string-contains? xpr " ")) | |
(values (replace-last-space xpr) #t)] | |
[(txexpr? xpr) | |
(define-values (result-elements found-within?) | |
(for/fold ([result-xprs null] | |
[found-yet? #f]) | |
([this-expr (in-list (reverse (get-elements xpr)))]) | |
(define-values (this-result found-this-time?) (nbsp this-expr found-yet?)) | |
(values (cons this-result result-xprs) found-this-time?))) | |
(values (txexpr (get-tag xpr) (get-attrs xpr) result-elements) found-within?)] | |
[else (values xpr found?)])) | |
(define (last-nbsp xpr) | |
(let-values ([(result _) (nbsp xpr)]) result)) | |
(module+ test | |
(require rackunit) | |
(check-equal? (last-nbsp '(p "This is my only number")) | |
'(p "This is my only number")) | |
;; What if we break up the x-expression? | |
(check-equal? (last-nbsp '(p "This is my " (em "only") " number")) | |
'(p "This is my " (em "only") " number")) | |
;; Hide the space in the middle tag | |
(check-equal? (last-nbsp '(p "This is my " (em "only ") "number")) | |
'(p "This is my " (em "only ") "number")) | |
;; Hide the space in between two tags | |
(check-equal? (last-nbsp '(p "This is my " (em "only") " " (strong "number"))) | |
'(p "This is my " (em "only") " " (strong "number"))) | |
;; Doesn't mess with attributes | |
(check-equal? (last-nbsp '(p "This is my " (em "only") " " (strong [[class "c1 c2"]] "number"))) | |
'(p "This is my " (em "only") " " (strong ((class "c1 c2")) "number")))) | |
;; Doesn't properly handle multiple spaces | |
;; such as: | |
;; '(p "This is my only number") | |
;; OR: | |
;; '(p "This is my " (em "only ") " number") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment