class Psych::Comments::Emitter
private_constant :NodeUtils
Constants
- DEFAULT_TAGMAP
- INDENT
Attributes
Public Class Methods
Source
# File lib/psych/comments/emitter.rb, line 76 def initialize @out = "" @state = :init @indent = 0 @flow = false @comment_lookahead = [] @tagmap = DEFAULT_TAGMAP end
Public Instance Methods
Source
# File lib/psych/comments/emitter.rb, line 283 def decompose_tag(tag) @tagmap.each do |handle, prefix| if tag.start_with?(prefix) suffix = tag.delete_prefix(prefix) if /\A(?:%[0-9a-fA-F]{2}|[-0-9a-z#;\/?:@&=+$_.~*'()])*\z/.match?(suffix) return [handle, suffix] end end end [nil, nil] end
@param tag [String]
Source
# File lib/psych/comments/emitter.rb, line 106 def emit(node) if node.equal?(@comment_lookahead[0]) @comment_lookahead.shift else node.leading_comments.each do |comment| emit_comment(comment) end end if has_anchor(node) print "&#{node.anchor}" space! end if node.tag handle, suffix = decompose_tag(node.tag) if suffix print "#{handle}#{suffix}" else print "!<#{node.tag}>" end space! end case node when Psych::Nodes::Scalar, Psych::Nodes::Alias if node.is_a?(Psych::Nodes::Alias) print "*#{node.anchor}" else print stringify_adjust_scalar(node, INDENT * @indent) end when Psych::Nodes::Mapping set_flow(flow?(node)) do if @flow print "{" cont = false node.children.each_slice(2) do |(key, value)| if cont print "," space! end emit(key) print ":" space! emit(value) cont = true end print "}" else newline! node.children.each_slice(2) do |(key, value)| emit(key) print ":" space! if single_line?(value) || has_bullet(value) emit(value) else indented do emit(value) end end newline! end end end when Psych::Nodes::Sequence set_flow(flow?(node)) do if @flow print "[" cont = false node.children.each do |subnode| if cont print "," space! end emit(subnode) cont = true end print "]" else newline! node.children.each do |subnode| emit_lookahead_comments(subnode) unless @flow print "- " @state = :pseudo_indent if single_line?(subnode) emit(subnode) else indented do emit(subnode) end end newline! end end end when Psych::Nodes::Document node.tag_directives.each do |(handle, prefix)| newline! print "%TAG #{handle} #{prefix}" newline! end unless node.implicit newline! print "---" space! end set_tagmap(node) do emit(node.root) end unless node.implicit_end newline! print "..." end newline! when Psych::Nodes::Stream node.children.each do |subnode| emit(subnode) end else raise TypeError, node end node.trailing_comments.each do |comment| emit_comment(comment) end end
Source
# File lib/psych/comments/emitter.rb, line 239 def emit_comment(comment) unless /\A#[^\r\n]*\z/.match?(comment) raise ArgumentError, "Invalid comment: #{comment.inspect}" end print comment newline! end
Source
# File lib/psych/comments/emitter.rb, line 230 def emit_lookahead_comments(node) return if node.equal?(@comment_lookahead[0]) node.leading_comments.each do |comment| emit_comment(comment) end @comment_lookahead.push(node) end
Source
# File lib/psych/comments/emitter.rb, line 269 def flow?(node) case node when Psych::Nodes::Scalar, Psych::Nodes::Alias true when Psych::Nodes::Mapping @flow || node.style == Psych::Nodes::Mapping::FLOW || node.children.empty? when Psych::Nodes::Sequence @flow || node.style == Psych::Nodes::Sequence::FLOW || node.children.empty? else false end end
Source
# File lib/psych/comments/emitter.rb, line 247 def indented(&block) @indent += 1 begin block.() ensure @indent -= 1 end end
Source
# File lib/psych/comments/emitter.rb, line 100 def newline! return if @state == :init || @state == :line_start || @state == :pseudo_indent @out << "\n" @state = :line_start end
Source
# File lib/psych/comments/emitter.rb, line 85 def print(text) case @state when :word_end @out << " " when :line_start @out << INDENT * @indent end @state = :in_line @out << text end
Source
# File lib/psych/comments/emitter.rb, line 256 def set_flow(new_flow, &block) old_flow, @flow = @flow, new_flow begin block.() ensure @flow = old_flow end end
Source
# File lib/psych/comments/emitter.rb, line 296 def set_tagmap(node, &block) new_tagmap = DEFAULT_TAGMAP.dup node.tag_directives.each do |(handle, prefix)| new_tagmap[handle] = prefix end old_tagmap, @tagmap = @tagmap, new_tagmap begin block.() ensure @tagmap = old_tagmap end end
@param node [Psych::Nodes::Document]
Source
# File lib/psych/comments/emitter.rb, line 265 def single_line?(node) flow?(node) && node.leading_comments.empty? && node.trailing_comments.empty? end