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

如何用Ruby将带格式标记的纯文本转换为指定格式的Docx?

Turning Parameterized TXT into Styled DOCX with Ruby

Hey there! Great question—since you already have Ruby generating your core content as TXT, adding format markers and converting to DOCX is totally straightforward. Here are two solid approaches tailored to your needs:

Option 1: Use Markdown as Your Formatting Marker Language

Markdown is perfect here because it has built-in syntax for exactly the styles you need (bold, italic, indentation, lists) and there are robust Ruby libraries to parse it into DOCX.

Step 1: Generate TXT with Markdown Syntax

When building your output TXT, use standard Markdown tags:

  • Bold text: Wrap with **double asterisks**
  • Italic text: Wrap with *single asterisks*
  • Indented/block quote text: Prefix with >
  • Bulleted lists: Start lines with -

Example TXT content (after parameter replacement):

**Contract ID**: C-2024-{{client_id}}
*Effective Date*: {{date}}

> Core Terms:
- Client Responsibility: {{client_duty}}
- Vendor Responsibility: {{vendor_duty}}

Step 2: Ruby Code to Convert Markdown TXT to DOCX

Use the ruby-docx gem for DOCX manipulation and commonmarker for parsing Markdown.

First install the gems:

gem install ruby-docx commonmarker

Then the code:

require 'docx'
require 'commonmarker'

# Load your generated parameterized TXT
raw_content = File.read('output_content.txt')

# Parse Markdown into an abstract syntax tree (AST) for easy processing
markdown_doc = Commonmarker.render_doc(raw_content, :DEFAULT)

# Initialize a new DOCX document
docx = Docx::Document.new

# Traverse the Markdown AST and map nodes to DOCX styles
markdown_doc.walk do |node|
  case node.type
  when :paragraph
    para = docx.add_paragraph
    node.each_child do |child|
      next unless child.type == :text
      # Apply bold/italic based on parent node type
      style = {}
      style[:bold] = true if child.parent.type == :strong
      style[:italic] = true if child.parent.type == :emph
      para.add_run(child.string_content, style)
    end
  when :list_item
    para = docx.add_paragraph
    # Add 0.5-inch left indent (DOCX uses twips: 1 inch = 1440 twips)
    para.indentation.left = 72
    node.each_child do |child|
      para.add_run("- #{child.string_content}") if child.type == :text
    end
  when :block_quote
    para = docx.add_paragraph
    # Add 1-inch left indent for block quotes
    para.indentation.left = 144
    node.each_child do |child|
      para.add_run(child.string_content) if child.type == :text
    end
  end
end

# Save the final styled DOCX
docx.save('final_contract.docx')

Option 2: Custom Formatting Markers (For Unique Needs)

If you need full control over custom tags (instead of using Markdown), define your own simple markers and use regex to map them to DOCX styles.

Step 1: Generate TXT with Custom Markers

Example custom tags:

  • Bold: {{b}}your text{{/b}}
  • Italic: {{i}}your text{{/i}}
  • Indented text: {{indent}}your text{{/indent}}

Step 2: Ruby Code to Process Custom Markers

require 'docx'

raw_content = File.read('output_content.txt')
docx = Docx::Document.new

# Split content into paragraphs (double newlines as separators)
raw_content.split("\n\n").each do |para_text|
  para = docx.add_paragraph

  # Process bold tags first
  para_text.gsub!(/({{b}})(.*?)({{\/b}})/) do
    para.add_run($2, bold: true)
    '' # Clear the matched tag to avoid duplicate text
  end

  # Process italic tags
  para_text.gsub!(/({{i}})(.*?)({{\/i}})/) do
    para.add_run($2, italic: true)
    ''
  end

  # Process indent tags
  if para_text.match?(/{{indent}}(.*?){{\/indent}}/)
    para.indentation.left = 72
    para_text = para_text.gsub(/{{indent}}(.*?){{\/indent}}/, '\1')
  end

  # Add any remaining plain text to the paragraph
  para.add_run(para_text) unless para_text.empty?
end

docx.save('final_contract.docx')

Recommendation

Stick with Markdown if possible—it's a standard, well-documented syntax that reduces the need to maintain custom regex. The commonmarker library handles edge cases (like nested styles) far better than custom code would.

内容的提问来源于stack exchange,提问作者Andres Pérez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:01:20