blob: b3bc57530ac93432d2af97e11d9f7ac8ba43a0ae (
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
|
;;; PLS.fnl
;; a parser for *.pls files
;; Copyright (C) 2022 Case Duckworth <acdw@acdw.net>
;; License: Good Choices (https://acdw.casa/gcl)
;; https://en.wikipedia.org/wiki/PLS_(file_format)
(fn split-lines [str]
"Split STR into a list of lines."
(icollect [ln (: str :gmatch "([^\n]*)\n?")]
ln))
(fn parse [str]
"Parse a list of LINES into a playlist."
;; This /maybe/ should take a string, I suppose.
(let [t []]
(each [_ l (ipairs (split-lines str))]
(let [(ltype num title) (: l :match "^(.*)([0-9]+)=(.*)")]
(when (and ltype num title)
(let [ltype (string.lower ltype)
num (tonumber num)]
(if (. t num)
(tset t num ltype title)
(tset t num {ltype title}))))))
t))
(fn read [file]
"Read a .pls FILE into a playlist."
(with-open [p (io.open file)]
(parse (: p :read :*a))))
(fn serialize [playlist]
"Serialize a PLAYLIST into a .pls-formatted string."
(let [s (icollect [n i (ipairs playlist)]
(.. (string.format "File%d=%s\n" n (. i :file))
(if (. i :title)
(string.format "Title%d=%s\n" n (. i :title))
"")
(if (. i :length)
(string.format "Length%d=%s\n" n (. i :length))
"")))]
(.. "[playlist]\n\n" (table.concat s "\n") "\n\n" :NumberOfEntries=
(length s) "\n" "Version=2\n")))
(fn write [playlist file]
"Write PLAYLIST to FILE."
(with-open [p (io.open file :w)]
(: p :write (serialize playlist))))
{: parse : read : serialize : write}
|