summaryrefslogtreecommitdiff
path: root/src/gizmo/wasp-combo.el
blob: 5e4d73384decbd9f208a698f0066c969c20f1c22 (plain)
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
;;; wasp-combo --- description -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:

(require 'cl-lib)
(require 'rx)
(require 'dash)
(require 's)
(require 'ht)
(require 'f)

(require 'wasp-utils)

(defvar w/combo-words (ht-create))
(defvar w/combo-word-phonemes (ht-create))
(defun w/combo-words-process-line (line)
  "Parse one LINE from the syllable table."
  (-let* ( ((word rest) (s-split-up-to "  " line 1))
           (phonemes (s-split " " rest)))
    (message "processing: %s" word)
    (ht-set! w/combo-word-phonemes word
      (--map (s-replace-regexp (rx digit) "" it) phonemes))
    (ht-set! w/combo-words
      word
      (-non-nil
        (--map (-some-> (s-match (rx digit) it) (car) (string-to-number))
          phonemes)))))
(defun w/combo-words-load ()
  "Populate `w/combo-words'."
  (let*
    ( (text (f-read-text (w/asset "syllables.txt")))
      (lines (s-lines text)))
    (--each lines
      (w/combo-words-process-line it))))
(w/combo-words-load)

(defun w/combo-split-words (sentence)
  "Split SENTENCE into uppercase words."
  (-map #'s-upcase
    (-filter #'s-present?
      (s-split (rx (not (or alnum "'"))) sentence))))

(defun w/combo-word-syllables (word)
  "Determine the pattern of syllables in WORD."
  (ht-get w/combo-words (s-upcase word)))

(defun w/combo-scansion (words)
  "Determine the pattern of syllables in WORDS."
  (-mapcat #'w/combo-word-syllables words))

(defun w/combo-alliteration? (words)
  "Determine if WORDS contain an alliterative pattern."
  (>
    (-max (cons 0 (--map (length (cdr it)) (--group-by (seq-elt it 0) words))))
    (max 1 (/ (length words) 2))))

(defun w/combo-palindrome? (words)
  "Determine if WORDS form a palindrome."
  (let ((joined (s-join "" words)))
    (s-equals? joined (s-reverse joined))))

(defun w/combo-assonance? (words)
  "Determine if WORDS have assonance."
  (>
    (-max
      (cons 0
        (--map (length (cdr it))
          (-group-by (lambda (x) x)
            (--mapcat (ht-get w/combo-word-phonemes it) words)))))
    (max 2 (/ (length words) 8))))

(defun w/combo-classify (sentence)
  "Return a list of tags indicating properties of SENTENCE."
  (let* ( (words (w/combo-split-words sentence))
          (scan (w/combo-scansion words)))
    (-concat
      (when (= (length scan) 17)
        '(haiku))
      (when (= (length scan) 10)
        '(pentameter))
      (when (w/combo-alliteration? words)
        '(alliteration))
      (when (w/combo-assonance? words)
        '(assonance))
      (when (w/combo-palindrome? words)
        '(palindrome))
      (when-let* ( (sexp (w/read-sexp sentence))
                   (_ (listp sexp)))
        '(sexp)))))

(provide 'wasp-combo)
;;; wasp-combo.el ends here