代码之家  ›  专栏  ›  技术社区  ›  August Lilleaas

向这个解析器添加nowiki标签可行吗?

  •  0
  • August Lilleaas  · 技术社区  · 16 年前

    here's the implementation I ended up using .

    class Markup
      def initialize(markup)
        @markup = markup
      end
    
      def to_html
        @html ||= @markup.split(/(\r\n){2,}|\n{2,}/).map {|p| Paragraph.new(p).to_html }.join("\n")
      end
    
      class Paragraph
        def initialize(paragraph)
          @p = paragraph
        end
    
        def to_html
          @p.gsub!(/'{3}([^']+)'{3}/, "<strong>\\1</strong>")
          @p.gsub!(/'{2}([^']+)'{2}/, "<em>\\1</em>")
          @p.gsub!(/`([^`]+)`/, "<code>\\1</code>")
    
          case @p
          when /^=/
            level = (@p.count("=") / 2) + 1 # Starting on h2
            @p.gsub!(/^[= ]+|[= ]+$/, "")
            "<h#{level}>" + @p + "</h#{level}>"
          when /^(\*|\#)/
            # I'm parsing lists here. Quite a lot of code, and not relevant, so
            # I'm leaving it out.
          else
            @p.gsub!("\n", "\n<br/>")
            "<p>" + @p + "</p>"
          end
        end
      end
    end
    
    p Markup.new("Here is `code` and ''emphasis'' and '''bold'''!
    
    Baz").to_html
    
    # => "<p>Here is <code>code</code> and <em>emphasis</em> and <strong>bold</strong>!</p>\n<p>Baz</p>"
    

    为这样的解析器添加对nowiki标签的支持(其中<nowiki></nowiki>之间的所有内容都没有被解析)是否可行?请随意回答“否”,并建议创建解析器的替代方法:)

    markup.rb paragraph.rb

    1 回复  |  直到 16 年前
        1
  •  3
  •   tadman    16 年前

    如果你使用一个简单的标记器,管理这类事情会容易得多。一种方法是创建一个可以捕获整个语法的单个正则表达式,但这可能会被证明是有问题的。另一种方法是将文档分为需要重写的部分和应该跳过的部分,这可能是这里更容易的方法。

    这里有一个简单的框架,你可以根据需要进行扩展:

    def wiki_subst(string)
      buffer = string.dup
      result = ''
    
      while (m = buffer.match(/<\s*nowiki\s*>.*?<\s*\/\s*nowiki\s*>/i))
        result << yield(m.pre_match)
        result << m.to_s
        buffer = m.post_match
      end
    
      result << yield(buffer)
    
      result
    end
    
    example = "replace me<nowiki>but not me</nowiki>replace me too<NOWIKI>but not me either</nowiki>and me"
    
    puts wiki_subst(example) { |s| s.upcase }
    # => REPLACE ME<nowiki>but not me</nowiki>REPLACE ME TOO<NOWIKI>but not me either</nowiki>AND ME