Asciidoctor移除包含Java文件指定注释后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
相关产品推荐
相关产品推荐

