Index: /pyyaml/branches/working-on-emitter/lib/yaml/__init__.py
===================================================================
--- /pyyaml/branches/working-on-emitter/lib/yaml/__init__.py	(revision 57)
+++ /pyyaml/branches/working-on-emitter/lib/yaml/__init__.py	(revision 122)
@@ -7,4 +7,6 @@
 from resolver import *
 from constructor import *
+
+from emitter import *
 
 from tokens import *
Index: /pyyaml/branches/working-on-emitter/lib/yaml/tokens.py
===================================================================
--- /pyyaml/branches/working-on-emitter/lib/yaml/tokens.py	(revision 121)
+++ /pyyaml/branches/working-on-emitter/lib/yaml/tokens.py	(revision 122)
@@ -1,5 +1,5 @@
 
 class Token:
-    def __init__(self, start_mark, end_mark):
+    def __init__(self, start_mark=None, end_mark=None):
         self.start_mark = start_mark
         self.end_mark = end_mark
@@ -17,5 +17,5 @@
 class DirectiveToken(Token):
     id = '<directive>'
-    def __init__(self, name, value, start_mark, end_mark):
+    def __init__(self, name, value, start_mark=None, end_mark=None):
         self.name = name
         self.value = value
@@ -70,5 +70,5 @@
 class AliasToken(Token):
     id = '<alias>'
-    def __init__(self, value, start_mark, end_mark):
+    def __init__(self, value, start_mark=None, end_mark=None):
         self.value = value
         self.start_mark = start_mark
@@ -77,5 +77,5 @@
 class AnchorToken(Token):
     id = '<anchor>'
-    def __init__(self, value, start_mark, end_mark):
+    def __init__(self, value, start_mark=None, end_mark=None):
         self.value = value
         self.start_mark = start_mark
@@ -84,5 +84,5 @@
 class TagToken(Token):
     id = '<tag>'
-    def __init__(self, value, start_mark, end_mark):
+    def __init__(self, value, start_mark=None, end_mark=None):
         self.value = value
         self.start_mark = start_mark
@@ -91,5 +91,5 @@
 class ScalarToken(Token):
     id = '<scalar>'
-    def __init__(self, value, plain, start_mark, end_mark):
+    def __init__(self, value, plain, start_mark=None, end_mark=None):
         self.value = value
         self.plain = plain
Index: /pyyaml/branches/working-on-emitter/lib/yaml/events.py
===================================================================
--- /pyyaml/branches/working-on-emitter/lib/yaml/events.py	(revision 121)
+++ /pyyaml/branches/working-on-emitter/lib/yaml/events.py	(revision 122)
@@ -1,11 +1,10 @@
 
 class Event:
-    def __init__(self, start_mark, end_mark):
+    def __init__(self, start_mark=None, end_mark=None):
         self.start_mark = start_mark
         self.end_mark = end_mark
     def __repr__(self):
-        attributes = [key for key in self.__dict__
-                if not key.endswith('_mark')]
-        attributes.sort()
+        attributes = [key for key in ['anchor', 'tag', 'value']
+                if hasattr(self, key)]
         arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
                 for key in attributes])
@@ -13,5 +12,5 @@
 
 class NodeEvent(Event):
-    def __init__(self, anchor, start_mark, end_mark):
+    def __init__(self, anchor, start_mark=None, end_mark=None):
         self.anchor = anchor
         self.start_mark = start_mark
@@ -22,5 +21,5 @@
 
 class ScalarEvent(NodeEvent):
-    def __init__(self, anchor, tag, value, start_mark, end_mark):
+    def __init__(self, anchor, tag, value, start_mark=None, end_mark=None):
         self.anchor = anchor
         self.tag = tag
@@ -30,5 +29,5 @@
 
 class CollectionEvent(NodeEvent):
-    def __init__(self, anchor, tag, start_mark, end_mark):
+    def __init__(self, anchor, tag, start_mark=None, end_mark=None):
         self.anchor = anchor
         self.tag = tag
Index: /pyyaml/branches/working-on-emitter/lib/yaml/emitter.py
===================================================================
--- /pyyaml/branches/working-on-emitter/lib/yaml/emitter.py	(revision 122)
+++ /pyyaml/branches/working-on-emitter/lib/yaml/emitter.py	(revision 122)
@@ -0,0 +1,180 @@
+
+# Events should obey the following grammar:
+# stream ::= STREAM-START document* STREAM-END
+# document ::= DOCUMENT-START node DOCUMENT-END
+# node ::= SCALAR | sequence | mapping
+# sequence ::= SEQUENCE-START node* SEQUENCE-END
+# mapping ::= MAPPING-START (node node)* MAPPING-END
+
+__all__ = ['Emitter', 'EmitterError']
+
+from error import YAMLError
+from events import *
+
+class EmitterError(YAMLError):
+    pass
+
+class Emitter:
+
+    def __init__(self, writer):
+        self.writer = writer
+        self.states = []
+        self.state = self.expect_stream_start
+        self.levels = []
+        self.level = 0
+        self.soft_space = False
+
+    def emit(self, event):
+        self.state(event)
+
+    def expect_stream_start(self, event):
+        if isinstance(event, StreamStartEvent):
+            self.state = self.expect_document_start
+        else:
+            raise EmitterError("expected StreamStartEvent, but got %s" % event.__class__.__name__)
+
+    def expect_document_start(self, event):
+        if isinstance(event, DocumentStartEvent):
+            self.write_document_start()
+            self.states.append(self.expect_document_end)
+            self.state = self.expect_root_node
+        elif isinstance(event, StreamEndEvent):
+            self.writer.flush()
+            self.state = self.expect_nothing
+        else:
+            raise EmitterError("expected DocumentStartEvent, but got %s" % event.__class__.__name__)
+
+    def expect_document_end(self, event):
+        if isinstance(event, DocumentEndEvent):
+            self.write_document_end()
+            self.state = self.expect_document_start
+        else:
+            raiseEmitterError("expected DocumentEndEvent, but got %s" % event.__class__.__name__)
+
+    def expect_root_node(self, event):
+        self.expect_node(event)
+
+    def expect_node(self, event):
+        if isinstance(event, AliasEvent):
+            self.write_anchor("*", event.anchor)
+            self.state = self.states.pop()
+        elif isinstance(event, NodeEvent):
+            if event.anchor:
+                self.write_anchor("&", event.anchor)
+            if event.tag:
+                self.write_tag(event.tag)
+            if isinstance(event, ScalarEvent):
+                self.write_scalar(event.value)
+                self.state = self.states.pop()
+            elif isinstance(event, SequenceEvent):
+                self.write_collection_start("[")
+                self.level += 1
+                self.state = self.expect_first_sequence_item
+            elif isinstance(event, MappingEvent):
+                self.write_collection_start("{")
+                self.level += 1
+                self.state = self.expect_first_mapping_key
+        else:
+            raise EmitterError("Expected NodeEvent, but got %s" % event.__class__.__name__)
+
+    def expect_first_sequence_item(self, event):
+        if isinstance(event, CollectionEndEvent):
+            self.write_collection_end("]")
+            self.state = self.states.pop()
+        else:
+            self.write_indent()
+            self.states.append(self.expect_sequence_item)
+            self.expect_node(event)
+
+    def expect_sequence_item(self, event):
+        if isinstance(event, CollectionEndEvent):
+            self.level -= 1
+            self.write_indent()
+            self.write_collection_end("]")
+            self.state = self.states.pop()
+        else:
+            self.write_indicator(",")
+            self.write_indent()
+            self.states.append(self.expect_sequence_item)
+            self.expect_node(event)
+        
+    def expect_first_mapping_key(self, event):
+        if isinstance(event, CollectionEndEvent):
+            self.write_collection_end("}")
+            self.state = self.states.pop()
+        else:
+            self.write_indent()
+            self.write_indicator("?")
+            self.states.append(self.expect_mapping_value)
+            self.expect_node(event)
+
+    def expect_mapping_key(self, event):
+        if isinstance(event, CollectionEndEvent):
+            self.level -= 1
+            self.write_indent()
+            self.write_collection_end("}")
+            self.state = self.states.pop()
+        else:
+            self.write_indicator(",")
+            self.write_indent()
+            self.write_indicator("?")
+            self.states.append(self.expect_mapping_value)
+            self.expect_node(event)
+
+    def expect_mapping_value(self, event):
+        self.write_indent()
+        self.write_indicator(":")
+        self.states.append(self.expect_mapping_key)
+        self.expect_node(event)
+
+    def expect_nothing(self, event):
+        raise EmitterError("expected nothing, but got %s" % event.__class__.__name__)
+
+    def write_document_start(self):
+        self.writer.write("%YAML 1.1\n")
+        self.writer.write("---")
+        self.soft_space = True
+
+    def write_document_end(self):
+        self.writer.write("\n...\n")
+        self.soft_space = False
+
+    def write_collection_start(self, indicator):
+        if self.soft_space:
+            self.writer.write(" ")
+        self.writer.write(indicator)
+        self.soft_space = False
+
+    def write_collection_end(self, indicator):
+        self.writer.write(indicator)
+        self.soft_space = True
+
+    def write_anchor(self, indicator, name):
+        if self.soft_space:
+            self.writer.write(" ")
+        self.writer.write("%s%s" % (indicator, name))
+        self.soft_space = True
+
+    def write_tag(self, tag):
+        if self.soft_space:
+            self.writer.write(" ")
+        if tag.startswith("tag:yaml.org,2002:"):
+            self.writer.write("!!%s" % tag[len("tag.yaml.org,2002:"):])
+        else:
+            self.writer.write("!<%s>" % tag)
+        self.soft_space = True
+
+    def write_scalar(self, value):
+        if self.soft_space:
+            self.writer.write(" ")
+        self.writer.write("\"%s\"" % value.encode('utf-8'))
+        self.soft_space = True
+
+    def write_indicator(self, indicator):
+        self.writer.write(indicator)
+        self.soft_space = True
+
+    def write_indent(self):
+        self.writer.write("\n"+" "*(self.level*4))
+        self.soft_space = False
+
Index: /pyyaml/branches/working-on-emitter/tests/test_emitter.py
===================================================================
--- /pyyaml/branches/working-on-emitter/tests/test_emitter.py	(revision 122)
+++ /pyyaml/branches/working-on-emitter/tests/test_emitter.py	(revision 122)
@@ -0,0 +1,19 @@
+
+import test_appliance, sys
+
+from yaml import *
+
+class TestEmitterOnCanonical(test_appliance.TestAppliance):
+
+    def _testEmitterOnCanonical(self, test_name, canonical_filename):
+        events = list(iter(Parser(Scanner(Reader(file(canonical_filename, 'rb'))))))
+        writer = sys.stdout
+        emitter = Emitter(writer)
+        print "-"*30
+        print "ORIGINAL DATA:"
+        print file(canonical_filename, 'rb').read()
+        for event in events:
+            emitter.emit(event)
+
+TestEmitterOnCanonical.add_tests('testEmitterOnCanonical', '.canonical')
+
Index: /pyyaml/branches/working-on-emitter/tests/test_yaml.py
===================================================================
--- /pyyaml/branches/working-on-emitter/tests/test_yaml.py	(revision 121)
+++ /pyyaml/branches/working-on-emitter/tests/test_yaml.py	(revision 122)
@@ -10,4 +10,5 @@
 from test_detector import *
 from test_constructor import *
+from test_emitter import *
 from test_syck import *
 
