| 67737 |      1 | /*  Title:      Pure/General/csv.scala
 | 
|  |      2 |     Author:     Makarius
 | 
|  |      3 | 
 | 
|  |      4 | Support for CSV: RFC 4180.
 | 
|  |      5 | */
 | 
|  |      6 | 
 | 
|  |      7 | package isabelle
 | 
|  |      8 | 
 | 
|  |      9 | 
 | 
| 75393 |     10 | object CSV {
 | 
|  |     11 |   def print_field(field: Any): String = {
 | 
| 67737 |     12 |     val str = field.toString
 | 
| 75606 |     13 |     if (str.exists("\",\r\n ".contains(_))) {
 | 
| 67737 |     14 |       (for (c <- str) yield { if (c == '"') "\"\"" else c.toString }).mkString("\"", "", "\"")
 | 
|  |     15 |     }
 | 
|  |     16 |     else str
 | 
|  |     17 |   }
 | 
|  |     18 | 
 | 
| 75393 |     19 |   sealed case class Record(fields: Any*) {
 | 
| 71601 |     20 |     override def toString: String = fields.iterator.map(print_field).mkString(",")
 | 
| 67737 |     21 |   }
 | 
|  |     22 | 
 | 
| 75393 |     23 |   sealed case class File(name: String, header: List[String], records: List[Record]) {
 | 
| 67737 |     24 |     override def toString: String = (Record(header:_*) :: records).mkString("\r\n")
 | 
|  |     25 | 
 | 
|  |     26 |     def file_name: String = name + ".csv"
 | 
| 73340 |     27 |     def write(dir: Path): Unit = isabelle.File.write(dir + Path.explode(file_name), toString)
 | 
| 67737 |     28 |   }
 | 
|  |     29 | }
 |