gdritter repos gunpowder_treason / master
Separate out xml module Getty Ritter 5 years ago
2 changed file(s) with 85 addition(s) and 53 deletion(s). Collapse all Expand all
22 use std::fs::{self, OpenOptions};
33 use std::io::{self, Write};
44 use std::path::Path;
5
6 mod xml;
7 use xml::XMLWriter;
58
69 const MAX_OUTPUT_FILES: u32 = 500;
710
2326 }
2427
2528 fn inches(amt: f64) -> Inches { Inches { amt } }
26
27 pub struct XMLWriter<'a>{
28 writer: &'a mut Write,
29 }
30
31 impl<'a> XMLWriter<'a> {
32 pub fn start(buf: &'a mut Write) -> io::Result<XMLWriter<'a>> {
33 writeln!(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>")?;
34 Ok(XMLWriter { writer: buf })
35 }
36
37 /// create an entire closed tag with the given attributes
38 pub fn tag(&mut self, name: &str, attrs: &[(&str, &Display)]) -> io::Result<()> {
39 write!(self.writer, "<{}", name)?;
40 for &(k, v) in attrs {
41 write!(self.writer, " {}=\"{}\"", k, v)?;
42 }
43 writeln!(self.writer, "/>")?;
44 Ok(())
45 }
46
47 /// create an open tag with the given attributes
48 pub fn open(&mut self, name: &str, attrs: &[(&str, &Display)]) -> io::Result<()> {
49 write!(self.writer, "<{}", name)?;
50 for &(k, v) in attrs {
51 write!(self.writer, " {}=\"{}\"", k, v)?;
52 }
53 writeln!(self.writer, ">")?;
54 Ok(())
55 }
56
57 /// close a tag with the given attributes
58 pub fn close(&mut self, name: &str) -> io::Result<()> {
59 write!(self.writer, "</{}>", name)?;
60 Ok(())
61 }
62
63 pub fn block<F>(&mut self, name: &str, attrs: &[(&str, &Display)], cb: F) -> io::Result<()>
64 where F: FnOnce(&mut XMLWriter<'a>) -> io::Result<()>
65 {
66 write!(self.writer, "<{}", name)?;
67 for &(k, v) in attrs {
68 write!(self.writer, " {}=\"{}\"", k, v)?;
69 }
70 writeln!(self.writer, ">")?;
71 cb(self)?;
72 write!(self.writer, "</{}>", name)?;
73 Ok(())
74 }
75
76 }
7729
7830 /// Create a new empty SVG document of the specified width and height
7931 pub fn svg(w: f64, h: f64) -> SVG {
251203 ("width", &w),
252204 ("height", &h),
253205 ("stroke", &"black"),
254 ("fill", &"white"),
206 ("fill", &"none"),
255207 ]
256208 )
257209 }
281233 ("cy", &y),
282234 ("r", &r),
283235 ("stroke", &"black"),
284 ("fill", &"white"),
236 ("fill", &"none"),
285237 ]
286238 )
287239 }
1 use std::fmt::{Display};
2 use std::io::{self, Write};
3 use std::iter::repeat;
4
5
6 /// An `XMLWriter` is a wrapper over a `Write` value that provides
7 /// helper functions for generating (mostly) well-formed XML.
8 pub struct XMLWriter<'a>{
9 writer: &'a mut Write,
10 indent: usize,
11 }
12
13 impl<'a> XMLWriter<'a> {
14 /// Create a new XMLWriter and add an XML version/encoding header
15 /// on top
16 pub fn start(buf: &'a mut Write) -> io::Result<XMLWriter<'a>> {
17 writeln!(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>")?;
18 Ok(XMLWriter { writer: buf, indent: 0, })
19 }
20
21 fn indent(&mut self) -> io::Result<()> {
22 write!(self.writer, "{}", repeat(' ').take(self.indent).collect::<String>())?;
23 Ok(())
24 }
25
26 /// create an complete tag with the given attributes
27 pub fn tag(&mut self, name: &str, attrs: &[(&str, &Display)]) -> io::Result<()> {
28 self.indent()?;
29 write!(self.writer, "<{}", name)?;
30 for &(k, v) in attrs {
31 write!(self.writer, " {}=\"{}\"", k, v)?;
32 }
33 writeln!(self.writer, "/>")?;
34 Ok(())
35 }
36
37 /// create an open tag with the given attributes; you must close
38 /// it manually later
39 pub fn open(&mut self, name: &str, attrs: &[(&str, &Display)]) -> io::Result<()> {
40 self.indent()?;
41 write!(self.writer, "<{}", name)?;
42 for &(k, v) in attrs {
43 write!(self.writer, " {}=\"{}\"", k, v)?;
44 }
45 writeln!(self.writer, ">")?;
46 Ok(())
47 }
48
49 /// close a tag with the given attributes
50 pub fn close(&mut self, name: &str) -> io::Result<()> {
51 self.indent()?;
52 write!(self.writer, "</{}>", name)?;
53 Ok(())
54 }
55
56 /// create an open-close tag pair with the given attributes,
57 /// calling the provided function in order to fill in the interior
58 /// tags as well
59 pub fn block<F>(
60 &mut self,
61 name: &str,
62 attrs: &[(&str, &Display)],
63 cb: F
64 ) -> io::Result<()>
65 where F: FnOnce(&mut XMLWriter<'a>) -> io::Result<()>
66 {
67 self.indent()?;
68 write!(self.writer, "<{}", name)?;
69 for &(k, v) in attrs {
70 write!(self.writer, " {}=\"{}\"", k, v)?;
71 }
72 writeln!(self.writer, ">")?;
73 self.indent += 2;
74 cb(self)?;
75 self.indent -= 2;
76 write!(self.writer, "</{}>", name)?;
77 Ok(())
78 }
79
80 }