You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Asciidoctor移除包含Java文件指定注释后tags属性失效问题

解决Asciidoctor自定义IncludeProcessor后tags属性失效的问题

问题分析

你编写的RemoveFormatterIncludeProcessor直接读取整个Java文件并过滤注释,但完全跳过了Asciidoctor内置的tags筛选逻辑——默认情况下,Asciidoctor会解析文件中的// tag::xxx[]和// end::xxx[]标记,只引入指定tags范围内的内容。你的自定义处理器没有处理tags属性,导致无论指定什么tags,都会引入整个文件内容。

解决方案1:复用内置IncludeProcessor处理tags

最简单的方式是先让默认的IncludeProcessor完成tags筛选,再对筛选后的内容移除formatter注释。这样既保留了原有tags功能,又实现了注释过滤。

require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'

include Asciidoctor

# Removes //@formatter:off and //@formatter:on comments from java source code, preserving tags functionality.
class RemoveFormatterIncludeProcessor < Extensions::IncludeProcessor
  include Asciidoctor::Logging

  def initialize
    # 初始化默认的IncludeProcessor,用于处理tags筛选
    @default_processor = Asciidoctor::IncludeProcessor.new
  end

  def handles? target
    target.end_with? '.java'
  end

  def process doc, reader, target, attributes
    # 创建临时Reader,让默认处理器处理tags筛选
    temp_reader = Reader.new
    @default_processor.process(doc, temp_reader, target, attributes)
    
    # 获取经过tags筛选后的内容,再过滤formatter注释
    filtered_content = temp_reader.lines.reject { |l| l.include? "@formatter:" }
    
    # 将最终处理后的内容推送到原Reader
    reader.push_include filtered_content, File.expand_path(target), target, 1, attributes
  end
end

Extensions.register do
  include_processor RemoveFormatterIncludeProcessor
end

解决方案2:自行实现tags解析逻辑

如果需要完全自定义tags处理逻辑,可以手动解析文件中的tag标记,筛选指定范围内的内容后再移除注释。这种方式不依赖内置处理器,灵活性更高。

require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'

include Asciidoctor

# Removes //@formatter:off and //@formatter:on comments from java source code, with custom tag handling.
class RemoveFormatterIncludeProcessor < Extensions::IncludeProcessor
  include Asciidoctor::Logging

  def handles? target
    target.end_with? '.java'
  end

  def process doc, reader, target, attributes
    file_path = File.join(doc.base_dir, target)
    source_lines = File.readlines(file_path).map(&:chomp)
    # 解析tags属性,得到需要保留的tag列表
    target_tags = attributes['tags']&.split(',')&.map(&:strip) || []

    filtered_content = if target_tags.empty?
      # 无指定tags时,处理整个文件
      source_lines.reject { |l| l.include? "@formatter:" }
    else
      in_target_block = false
      result = []

      source_lines.each do |line|
        # 匹配tag开始标记:// tag::xxx[]
        if (tag_match = line.match(%r{//\s*tag::([^\[\]]+)\[\]}))
          in_target_block = target_tags.include?(tag_match[1])
          next # 跳过tag标记行
        # 匹配tag结束标记:// end::xxx[]
        elsif line.match?(%r{//\s*end::[^\[\]]+\[\]})
          in_target_block = false
          next # 跳过tag结束标记行
        end

        # 仅保留目标tag块内且非formatter注释的行
        result << line if in_target_block && !line.include?("@formatter:")
      end

      result
    end

    reader.push_include filtered_content, File.expand_path(target), target, 1, attributes
  end
end

Extensions.register do
  include_processor RemoveFormatterIncludeProcessor
end

说明

  • 方案1复用了Asciidoctor内置的tags处理逻辑,代码更简洁,且能兼容Asciidoctor对tags的所有原生支持(比如多个tag、嵌套tag等)。
  • 方案2适合需要对tag解析做特殊定制的场景,比如修改tag标记格式、添加额外过滤规则等。

内容的提问来源于stack exchange,提问作者Kehrlann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 21:33:20