diff options
Diffstat (limited to 'src/pls.fnl')
-rw-r--r-- | src/pls.fnl | 51 |
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 | |||