利用者:Ef3/MarkdownToWikitext
表示
< 利用者:Ef3
- '
#!/usr/bin/env ruby # frozen_string_literal: true # Markdown to Wikitext converter class MarkdownToWikitext def initialize @in_table = false @in_code_block = false @code_language = nil @table_rows = [] @current_table_row = [] @table_header = false end def lang(lang_text) return "text" unless lang_text return "text" if lang_text == "" { "python" => "python3", "javascript" => "js", }[lang_text] || lang_text end def convert(markdown_text) result = [] lines = markdown_text.split("\n") i = 0 while i < lines.length line = lines[i] # Check for code blocks if line.strip.start_with?('```') if @in_code_block # End of code block @in_code_block = false result << '
else
# Start of code block
@in_code_block = true
language = line.strip.delete_prefix('```').strip
@code_language = lang(language)
result << ":
"
end
i += 1
next
end
# Check for tables
if line.strip.start_with?('|') && !@in_code_block
unless @in_table
@in_table = true
@table_rows = []
@table_header = true
end
# Parse table row
cells = line.split('|').map(&:strip)
cells.shift if cells.first.empty? # Remove leading empty cell
cells.pop if cells.last.empty? # Remove trailing empty cell
if @table_header && line.strip.match(/^\|(\s*[-:]+\s*\|)+/)
# This is the separator row, skip it
@table_header = false
i += 1
next
end
@table_rows << cells
i += 1
# Check if this is the end of the table
if i >= lines.length || !lines[i].strip.start_with?('|')
result << generate_wiki_table
@in_table = false
end
next
elsif @in_table
# End of table encountered
result << generate_wiki_table
@in_table = false
end
result << if @in_code_block
# Inside code block, add as is
line
else
# Process normal markdown
convert_line(line)
end
i += 1
end
# Handle any remaining table
result << generate_wiki_table if @in_table
result.join("\n")
end
private
def convert_line(line)
# Process headings
if line.match(/^(#+)(.+)$/)
equals = '=' * (1 + $1.size)
return "#{equals} #{$2.strip} #{equals}"
end
# Process bold and italic
line = line.gsub(/\*\*\*(.+?)\*\*\*/, "''''\\1''''") # Bold and italic
line = line.gsub(/\*\*(.+?)\*\*/, "'''\\1'''") # Bold
line = line.gsub(/\*(.+?)\*/, "''\\1''") # Italic
line = line.gsub(/__(.+?)__/, "'''\\1'''") # Bold (underscore)
line = line.gsub(/_(.+?)_/, "''\\1''") # Italic (underscore)
# Process links
line = line.gsub(/\[(.+?)\]\((.+?)\)/, '[\\2 \\1]') # External links
# Process inline code
line = line.gsub(/`(.+?)`/, '<code>\\1</code>')
# Process horizontal rule
line = '----' if line.match(/^[*\-_]{3,}$/)
# Process unordered lists
line = "*#{line.sub(/^[-*]\s+/, ' ')}" if line.strip.start_with?('- ', '* ')
# Process ordered lists
line = "##{line.sub(/^\d+\.\s+/, ' ')}" if line.match(/^\d+\.\s+/)
line
end
def generate_wiki_table
return '' if @table_rows.empty?
# Process cells for nested syntax highlighting
@table_rows.each_with_index do |row, i|
row.each_with_index do |cell, j|
# Check for inline code blocks within table cells
next unless cell.include?('```')
parts = cell.split('```')
processed_cell = parts[0]
if parts.length > 1
(1...parts.length).each do |k|
if k.odd? # Code block content
lng = parts[k].split("\n").first.strip
code = parts[k].split("\n")[1..].join("\n")
processed_cell += ":<syntaxhighlight lang=\"#{lang(lng)}\">\n#{code}\n</syntaxhighlight copy>"
else # Normal text
processed_cell += convert_line parts[k]
end
end
end
@table_rows[i][j] = processed_cell
end
end
# Generate the MediaWiki table
result = ['{|class="wikitable"']
# Add header row
if @table_rows.length.positive?
result << '|-'
header_row = @table_rows[0]
header_row.each do |cell|
result << "!#{convert_line cell}"
end
end
# Add data rows
(1...@table_rows.length).each do |i|
row = @table_rows[i]
result << '|-'
row.each do |cell|
result << "|#{convert_line cell}"
end
end
result << '|}'
result.join("\n")
end
end
markdown_text = File.read('text.md')
converter = MarkdownToWikitext.new
wikitext = converter.convert(markdown_text)
last = nil
wikitext.split("\n").each {
puts _1 if _1 != last && !(last && last[0] == '#' && _1 == '')
last = _1
}