You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
1.9KB

  1. #lang racket
  2. (require
  3. (for-syntax
  4. racket/base
  5. syntax/parse))
  6. (define (tag-start name attrs)
  7. (string-append
  8. (format "<~a" name)
  9. (apply
  10. string-append
  11. (map (lambda (x)
  12. (let ([t (car x)]
  13. [v (cdr x)])
  14. (format " ~a=\"~a\"" t v)))
  15. attrs))))
  16. (define (single-tag-end)
  17. "/>")
  18. (define (tag-end name content)
  19. (string-append
  20. ">"
  21. (if (list? content)
  22. (apply string-append content)
  23. content)
  24. (format "</~a>" name)))
  25. (define (tag name attrs content)
  26. (string-append
  27. (tag-start name attrs)
  28. (tag-end name content)))
  29. (define (single-tag name attrs)
  30. (string-append
  31. (tag-start name attrs)
  32. (single-tag-end)))
  33. (define-syntax (mtag stx)
  34. (syntax-parse stx
  35. [(_ name:id
  36. ([t:id v:expr] ...)
  37. content:expr ...)
  38. #'(tag
  39. (symbol->string 'name)
  40. (list
  41. (cons
  42. (symbol->string 't)
  43. (if (number? v)
  44. (number->string v)
  45. v)) ...)
  46. (apply string-append
  47. (flatten
  48. (list content ...))))]))
  49. (define-syntax (msingle-tag stx)
  50. (syntax-parse stx
  51. [(_ name:id
  52. ([t:id v:expr] ...))
  53. #'(single-tag
  54. (symbol->string 'name)
  55. (list
  56. (cons
  57. (symbol->string 't)
  58. (if (number? v)
  59. (number->string v)
  60. v)) ...))]))
  61. (define-syntax (define-tag stx)
  62. (syntax-parse stx
  63. [(_ name:id)
  64. #'(define-syntax (name stx)
  65. (syntax-parse stx
  66. [(_ attrs:expr content:expr (... ...))
  67. #'(mtag name attrs content (... ...))]))]))
  68. (define-syntax (define-single-tag stx)
  69. (syntax-parse stx
  70. [(_ name:id)
  71. #'(define-syntax (name stx)
  72. (syntax-parse stx
  73. [(_ attrs:expr)
  74. #'(msingle-tag name attrs)]))]))
  75. (provide (all-defined-out))