about summary refs log tree commit diff stats
path: root/src/pls.fnl
diff options
context:
space:
mode:
Diffstat (limited to 'src/pls.fnl')
-rw-r--r--src/pls.fnl51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/pls.fnl b/src/pls.fnl new file mode 100644 index 0000000..b3bc575 --- /dev/null +++ b/src/pls.fnl
@@ -0,0 +1,51 @@
1;;; PLS.fnl
2;; a parser for *.pls files
3;; Copyright (C) 2022 Case Duckworth <acdw@acdw.net>
4;; License: Good Choices (https://acdw.casa/gcl)
5
6;; https://en.wikipedia.org/wiki/PLS_(file_format)
7
8(fn split-lines [str]
9 "Split STR into a list of lines."
10 (icollect [ln (: str :gmatch "([^\n]*)\n?")]
11 ln))
12
13(fn parse [str]
14 "Parse a list of LINES into a playlist."
15 ;; This /maybe/ should take a string, I suppose.
16 (let [t []]
17 (each [_ l (ipairs (split-lines str))]
18 (let [(ltype num title) (: l :match "^(.*)([0-9]+)=(.*)")]
19 (when (and ltype num title)
20 (let [ltype (string.lower ltype)
21 num (tonumber num)]
22 (if (. t num)
23 (tset t num ltype title)
24 (tset t num {ltype title}))))))
25 t))
26
27(fn read [file]
28 "Read a .pls FILE into a playlist."
29 (with-open [p (io.open file)]
30 (parse (: p :read :*a))))
31
32(fn serialize [playlist]
33 "Serialize a PLAYLIST into a .pls-formatted string."
34 (let [s (icollect [n i (ipairs playlist)]
35 (.. (string.format "File%d=%s\n" n (. i :file))
36 (if (. i :title)
37 (string.format "Title%d=%s\n" n (. i :title))
38 "")
39 (if (. i :length)
40 (string.format "Length%d=%s\n" n (. i :length))
41 "")))]
42 (.. "[playlist]\n\n" (table.concat s "\n") "\n\n" :NumberOfEntries=
43 (length s) "\n" "Version=2\n")))
44
45(fn write [playlist file]
46 "Write PLAYLIST to FILE."
47 (with-open [p (io.open file :w)]
48 (: p :write (serialize playlist))))
49
50{: parse : read : serialize : write}
51