Ignore:
Timestamp:
04/01/06 16:28:20 (8 years ago)
Author:
xi
Message:

Add block styles.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pyyaml/branches/working-on-emitter/lib/yaml/emitter.py

    r127 r129  
    2121        self.states = [] 
    2222        self.state = self.expect_stream_start 
    23         self.levels = [] 
    24         self.level = 0 
    25         self.soft_space = False 
     23        self.indents = [] 
     24        self.indent = None 
     25        self.flow_level = 0 
     26        self.key_context = False 
     27        self.space = True 
     28        self.line = True 
     29        self.allow_inline_collection = False 
     30        self.allow_indentless_sequence = False 
     31        self.simple_key = False 
     32        self.event_queue = [] 
    2633 
    2734    def emit(self, event): 
     35        if self.event_queue: 
     36            self.event_queue.append(event) 
     37            event = self.event_queue.pop(0) 
    2838        self.state(event) 
     39 
     40    def push_back(self, event): 
     41        self.event_queue.insert(0, event) 
    2942 
    3043    def expect_stream_start(self, event): 
     
    3952            self.states.append(self.expect_document_end) 
    4053            self.state = self.expect_root_node 
     54            self.allow_inline_collection = False 
     55            self.allow_indentless_sequence = False 
    4156        elif isinstance(event, StreamEndEvent): 
    4257            self.writer.flush() 
     
    4964            self.write_document_end() 
    5065            self.state = self.expect_document_start 
     66            self.allow_inline_collection = False 
     67            self.allow_indentless_sequence = False 
    5168        else: 
    5269            raiseEmitterError("expected DocumentEndEvent, but got %s" % event.__class__.__name__) 
     
    5673 
    5774    def expect_node(self, event): 
     75        empty = None 
     76        if isinstance(event, (SequenceEvent, MappingEvent)): 
     77            if not self.event_queue: 
     78                return self.push_back(event) 
     79            empty = isinstance(self.event_queue[0], CollectionEndEvent) 
    5880        if isinstance(event, AliasEvent): 
    59             self.write_anchor("*", event.anchor) 
    60             self.state = self.states.pop() 
    61         elif isinstance(event, NodeEvent): 
     81            self.expect_alias(event) 
     82        elif isinstance(event, (ScalarEvent, SequenceEvent, MappingEvent)): 
    6283            if event.anchor: 
    6384                self.write_anchor("&", event.anchor) 
    64             if event.tag: 
     85                self.allow_inline_collection = False 
     86            if event.tag not in [None, u'!']: 
    6587                self.write_tag(event.tag) 
     88                self.allow_inline_collection = False 
    6689            if isinstance(event, ScalarEvent): 
    67                 self.write_scalar(event.value) 
    68                 self.state = self.states.pop() 
     90                self.expect_scalar(event) 
    6991            elif isinstance(event, SequenceEvent): 
    70                 self.write_collection_start("[") 
    71                 self.level += 1 
    72                 self.state = self.expect_first_sequence_item 
     92                self.expect_sequence(event, empty) 
    7393            elif isinstance(event, MappingEvent): 
    74                 self.write_collection_start("{") 
    75                 self.level += 1 
    76                 self.state = self.expect_first_mapping_key 
     94                self.expect_mapping(event, empty) 
    7795        else: 
    7896            raise EmitterError("Expected NodeEvent, but got %s" % event.__class__.__name__) 
    7997 
    80     def expect_first_sequence_item(self, event): 
    81         if isinstance(event, CollectionEndEvent): 
    82             self.write_collection_end("]") 
    83             self.state = self.states.pop() 
    84         else: 
    85             self.write_indent() 
    86             self.states.append(self.expect_sequence_item) 
    87             self.expect_node(event) 
    88  
    89     def expect_sequence_item(self, event): 
    90         if isinstance(event, CollectionEndEvent): 
    91             self.level -= 1 
    92             self.write_indent() 
    93             self.write_collection_end("]") 
    94             self.state = self.states.pop() 
    95         else: 
     98    def expect_alias(self, event): 
     99        self.write_anchor("*", event.anchor) 
     100        self.state = self.states.pop() 
     101 
     102    def expect_scalar(self, event): 
     103        self.indents.append(self.indent) 
     104        if self.indent is None: 
     105            self.indent = 2 
     106        else: 
     107            self.indent += 2 
     108        self.write_scalar(event.value, event.implicit, event.style) 
     109        self.indent = self.indents.pop() 
     110        self.state = self.states.pop() 
     111        self.allow_inline_collection = False 
     112        self.allow_indentless_sequence = False 
     113 
     114    def expect_sequence(self, event, empty): 
     115        if self.flow_level or event.flow or empty: 
     116            self.write_indicator("[", need_space=True, provide_space=True) 
     117            self.flow_level += 1 
     118            self.indents.append(self.indent) 
     119            if self.indent is None: 
     120                self.indent = 2 
     121            else: 
     122                self.indent += 2 
     123            self.state = self.expect_first_flow_sequence_item 
     124        else: 
     125            self.indents.append(self.indent) 
     126            if self.indent is None: 
     127                self.indent = 0 
     128            else: 
     129                self.indent += 2 
     130            self.state = self.expect_first_block_sequence_item 
     131 
     132    def expect_mapping(self, event, empty): 
     133        if self.flow_level or event.flow or empty: 
     134            self.write_indicator("{", need_space=True, provide_space=True) 
     135            self.flow_level += 1 
     136            self.indents.append(self.indent) 
     137            if self.indent is None: 
     138                self.indent = 2 
     139            else: 
     140                self.indent += 2 
     141            self.state = self.expect_first_flow_mapping_key 
     142        else: 
     143            self.indents.append(self.indent) 
     144            if self.indent is None: 
     145                self.indent = 0 
     146            else: 
     147                self.indent += 2 
     148            self.state = self.expect_first_block_mapping_key 
     149 
     150    def expect_first_flow_sequence_item(self, event): 
     151        if isinstance(event, CollectionEndEvent): 
     152            self.indent = self.indents.pop() 
     153            self.write_indicator("]", provide_space=True) 
     154            self.flow_level -= 1 
     155            self.state = self.states.pop() 
     156        else: 
     157            self.write_indent() 
     158            self.states.append(self.expect_flow_sequence_item) 
     159            self.state = self.expect_node 
     160            self.expect_node(event) 
     161 
     162    def expect_flow_sequence_item(self, event): 
     163        if isinstance(event, CollectionEndEvent): 
    96164            self.write_indicator(",") 
    97             self.write_indent() 
    98             self.states.append(self.expect_sequence_item) 
    99             self.expect_node(event) 
    100          
    101     def expect_first_mapping_key(self, event): 
    102         if isinstance(event, CollectionEndEvent): 
    103             self.write_collection_end("}") 
    104             self.state = self.states.pop() 
    105         else: 
    106             self.write_indent() 
    107             self.write_indicator("?") 
    108             self.states.append(self.expect_mapping_value) 
    109             self.expect_node(event) 
    110  
    111     def expect_mapping_key(self, event): 
    112         if isinstance(event, CollectionEndEvent): 
    113             self.level -= 1 
    114             self.write_indent() 
    115             self.write_collection_end("}") 
     165            self.indent = self.indents.pop() 
     166            self.write_indent() 
     167            self.write_indicator("]") 
     168            self.flow_level -= 1 
    116169            self.state = self.states.pop() 
    117170        else: 
    118171            self.write_indicator(",") 
    119172            self.write_indent() 
    120             self.write_indicator("?") 
    121             self.states.append(self.expect_mapping_value) 
    122             self.expect_node(event) 
    123  
    124     def expect_mapping_value(self, event): 
    125         self.write_indent() 
    126         self.write_indicator(":") 
    127         self.states.append(self.expect_mapping_key) 
     173            self.states.append(self.expect_flow_sequence_item) 
     174            self.state = self.expect_node 
     175            self.expect_node(event) 
     176 
     177    def expect_first_block_sequence_item(self, event): 
     178        assert not isinstance(event, CollectionEndEvent) 
     179        if not self.allow_inline_collection: 
     180            if self.allow_indentless_sequence: 
     181                self.indent = self.indents.pop() 
     182                self.indents.append(self.indent) 
     183            self.write_indent() 
     184        self.write_indicator("-", need_space=True) 
     185        self.allow_indentless_sequence = False 
     186        self.allow_inline_collection = True 
     187        self.states.append(self.expect_block_sequence_item) 
     188        self.state = self.expect_node 
     189        self.expect_node(event) 
     190 
     191    def expect_block_sequence_item(self, event): 
     192        if isinstance(event, CollectionEndEvent): 
     193            self.indent = self.indents.pop() 
     194            self.state = self.states.pop() 
     195        else: 
     196            self.write_indent() 
     197            self.write_indicator("-", need_space=True) 
     198            self.allow_indentless_sequence = False 
     199            self.allow_inline_collection = True 
     200            self.states.append(self.expect_block_sequence_item) 
     201            self.state = self.expect_node 
     202            self.expect_node(event) 
     203 
     204    def expect_first_flow_mapping_key(self, event): 
     205        if isinstance(event, CollectionEndEvent): 
     206            self.indent = self.indents.pop() 
     207            self.write_indicator("}") 
     208            self.flow_level -= 1 
     209            self.state = self.states.pop() 
     210        else: 
     211            self.write_indent() 
     212            if self.is_simple(event): 
     213                self.simple_key = True 
     214            else: 
     215                self.write_indicator("?", need_space=True) 
     216            self.states.append(self.expect_flow_mapping_value) 
     217            self.state = self.expect_node 
     218            self.expect_node(event) 
     219 
     220    def expect_flow_mapping_key(self, event): 
     221        if isinstance(event, CollectionEndEvent): 
     222            self.indent = self.indents.pop() 
     223            self.write_indent() 
     224            self.write_indicator("}") 
     225            self.flow_level -= 1 
     226            self.state = self.states.pop() 
     227        else: 
     228            self.write_indicator(",") 
     229            self.write_indent() 
     230            if self.is_simple(event): 
     231                self.simple_key = True 
     232            else: 
     233                self.write_indicator("?", need_space=True) 
     234            self.states.append(self.expect_flow_mapping_value) 
     235            self.state = self.expect_node 
     236            self.expect_node(event) 
     237 
     238    def expect_flow_mapping_value(self, event): 
     239        if self.simple_key: 
     240            self.write_indicator(":", need_space=False) 
     241            self.simple_key = False 
     242        else: 
     243            self.write_indent() 
     244            self.write_indicator(":", need_space=True) 
     245        self.states.append(self.expect_flow_mapping_key) 
     246        self.state = self.expect_node 
     247        self.expect_node(event) 
     248 
     249    def expect_first_block_mapping_key(self, event): 
     250        assert not isinstance(event, CollectionEndEvent) 
     251        simple = self.is_simple(event) 
     252        if simple is None: 
     253            return self.push_back(event) 
     254        if not self.allow_inline_collection: 
     255            self.write_indent() 
     256        if self.is_simple(event): 
     257            self.allow_indentless_sequence = True 
     258            self.allow_inline_collection = False 
     259            self.simple_key = True 
     260        else: 
     261            self.write_indicator("?", need_space=True) 
     262            self.allow_indentless_sequence = True 
     263            self.allow_inline_collection = True 
     264        self.states.append(self.expect_block_mapping_value) 
     265        self.state = self.expect_node 
     266        self.expect_node(event) 
     267 
     268    def expect_block_mapping_key(self, event): 
     269        if isinstance(event, CollectionEndEvent): 
     270            self.indent = self.indents.pop() 
     271            self.state = self.states.pop() 
     272        else: 
     273            self.write_indent() 
     274            if self.is_simple(event): 
     275                self.allow_indentless_sequence = True 
     276                self.allow_inline_collection = False 
     277                self.simple_key = True 
     278            else: 
     279                self.write_indicator("?", need_space=True) 
     280                self.allow_indentless_sequence = True 
     281                self.allow_inline_collection = True 
     282            self.states.append(self.expect_block_mapping_value) 
     283            self.state = self.expect_node 
     284            self.expect_node(event) 
     285 
     286    def expect_block_mapping_value(self, event): 
     287        if self.simple_key: 
     288            self.write_indicator(":", need_space=False) 
     289            self.allow_indentless_sequence = True 
     290            self.allow_inline_collection = False 
     291            self.simple_key = False 
     292        else: 
     293            self.write_indent() 
     294            self.write_indicator(":", need_space=True) 
     295            self.allow_indentless_sequence = True 
     296            self.allow_inline_collection = True 
     297        self.states.append(self.expect_block_mapping_key) 
     298        self.state = self.expect_node 
    128299        self.expect_node(event) 
    129300 
     
    132303 
    133304    def write_document_start(self): 
    134         self.writer.write("%YAML 1.1\n") 
     305        self.writer.write("%YAML 1.1") 
     306        self.write_line_break() 
    135307        self.writer.write("---") 
    136         self.soft_space = True 
     308        self.space = False 
     309        self.line = False 
    137310 
    138311    def write_document_end(self): 
    139         self.writer.write("\n...\n") 
    140         self.soft_space = False 
    141  
    142     def write_collection_start(self, indicator): 
    143         if self.soft_space: 
    144             self.writer.write(" ") 
    145         self.writer.write(indicator) 
    146         self.soft_space = False 
    147  
    148     def write_collection_end(self, indicator): 
    149         self.writer.write(indicator) 
    150         self.soft_space = True 
     312        if not self.line: 
     313            self.write_line_break() 
     314        self.writer.write("...") 
     315        self.write_line_break() 
     316 
     317    def write_line_break(self): 
     318        self.writer.write('\n') 
     319        self.space = True 
     320        self.line = True 
    151321 
    152322    def write_anchor(self, indicator, name): 
    153         if self.soft_space: 
     323        if not self.space: 
    154324            self.writer.write(" ") 
    155325        self.writer.write("%s%s" % (indicator, name)) 
    156         self.soft_space = True 
     326        self.space = False 
     327        self.line = False 
    157328 
    158329    def write_tag(self, tag): 
    159         if self.soft_space: 
     330        if not self.space: 
    160331            self.writer.write(" ") 
    161332        if tag.startswith("tag:yaml.org,2002:"): 
     
    163334        else: 
    164335            self.writer.write("!<%s>" % tag) 
    165         self.soft_space = True 
    166  
    167     def write_scalar(self, value): 
    168         if self.soft_space: 
     336        self.space = False 
     337        self.line = False 
     338 
     339    def is_simple(self, event): 
     340        if not isinstance(event, ScalarEvent): 
     341            return False 
     342        if '\n' in event.value or len(event.value) > 128: 
     343            return False 
     344        if event.style and event.style in '|>': 
     345            return False 
     346        return True 
     347 
     348    def write_scalar(self, value, implicit, style): 
     349        if implicit: 
     350            if not self.space: 
     351                self.writer.write(" ") 
     352            self.writer.write(value.encode('utf-8')) 
     353            self.space = False 
     354            self.line = False 
     355        elif style in ['>', '|'] and not self.flow_level and not self.simple_key: 
     356            if not self.space: 
     357                self.writer.write(" ") 
     358            self.writer.write("|-") 
     359            self.write_line_break() 
     360            self.write_indent() 
     361            self.writer.write(value.encode('utf-8')) 
     362            self.write_line_break() 
     363        else: 
     364            if not self.space: 
     365                self.writer.write(" ") 
     366            self.writer.write("\"%s\"" % value.encode('utf-8')) 
     367            self.space = False 
     368            self.line = False 
     369 
     370    def write_indicator(self, indicator, need_space=False, provide_space=False): 
     371        if need_space and not self.space: 
    169372            self.writer.write(" ") 
    170         self.writer.write("\"%s\"" % value.encode('utf-8')) 
    171         self.soft_space = True 
    172  
    173     def write_indicator(self, indicator): 
    174373        self.writer.write(indicator) 
    175         self.soft_space = True 
     374        self.space = provide_space 
     375        self.line = False 
    176376 
    177377    def write_indent(self): 
    178         self.writer.write("\n"+" "*(self.level*2)) 
    179         self.soft_space = False 
    180  
     378        if not self.line: 
     379            self.write_line_break() 
     380        if self.indent: 
     381            self.writer.write(" "*self.indent) 
     382            self.line = False 
     383        self.space = True 
     384 
Note: See TracChangeset for help on using the changeset viewer.