hiki2md 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b4d6cfffb000735e6110b7f97177fed422bd998b1ea8d07672ee0965f0232f8
4
- data.tar.gz: 92ac94a769691e6bd4a7662bb0b33adcc7b6036d720f5d7171b21c08511a6954
3
+ metadata.gz: 4fc18ad51b63a8dde11dfe5ea4c04e4e8347e21457670edc8200acdaa125e8e9
4
+ data.tar.gz: f0bf7d53ac1bfd7a71a643ae9354f781fab199a29a07ea8225399831808ab2fb
5
5
  SHA512:
6
- metadata.gz: fc77e072352a1a301871154af34120ccf5a32bb0857019e92132a0867a972c7ff918f53915a062fc3317b1c702b1512dfdc25889f9f590c0b18f28c883c80820
7
- data.tar.gz: 3c6df53740b623b39bb5f20e11d314a6f6de3f251cfced2e7f7bb596d98f2a67d4cf04573bb58f3179510ee80d1ac1f018489fc7bc6ed81cc9ae3d82084a66be
6
+ metadata.gz: 147c40644b389860b2f9b0868235571ebd95ab005d6873910a4c54849d6a6f625619bf439e1679da0894a7908c9766fcc05d11f14f571d283492206bb19750b8
7
+ data.tar.gz: 61dd0a68d793fafa4c5320e72c3bd9c4f5f88288e5566686d2abbf56fe9bc734861de8bf75b70556f6d6477bda01ceda9f14a7d7830d4d6e1d5534774f7cc6e3
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hiki2md (0.3.0)
4
+ hiki2md (0.3.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -57,6 +57,16 @@ Options:
57
57
  - `--[no-]wiki-name`: enable or disable automatic WikiName links.
58
58
  - `--preserve-plugins`: retain plugins as escaped Markdown text instead of
59
59
  removing them.
60
+ - `-E`, `--input-encoding ENCODING`: override the detected source encoding.
61
+
62
+ The command writes UTF-8 Markdown. It automatically recognizes BOM-marked
63
+ Unicode input and the common Hiki encodings UTF-8, EUC-JP, Windows-31J, and
64
+ ISO-2022-JP. Since legacy encodings can be ambiguous, use
65
+ `--input-encoding` to specify the source explicitly when needed:
66
+
67
+ ```console
68
+ $ hiki2md --input-encoding EUC-JP TextFormattingRules.ja
69
+ ```
60
70
 
61
71
  ### Supported Hiki syntax
62
72
 
data/exe/hiki2md CHANGED
@@ -3,9 +3,88 @@ require 'hiki2md'
3
3
  require 'optparse'
4
4
  require 'yaml'
5
5
 
6
+ module Hiki2mdCommand
7
+ class InputEncodingError < StandardError; end
8
+
9
+ BOM_ENCODINGS = [
10
+ [[0x00, 0x00, 0xfe, 0xff].pack('C*'), Encoding::UTF_32],
11
+ [[0xff, 0xfe, 0x00, 0x00].pack('C*'), Encoding::UTF_32],
12
+ [[0xfe, 0xff].pack('C*'), Encoding::UTF_16],
13
+ [[0xff, 0xfe].pack('C*'), Encoding::UTF_16],
14
+ [[0xef, 0xbb, 0xbf].pack('C*'), Encoding::UTF_8]
15
+ ].freeze
16
+ AUTO_ENCODINGS = [
17
+ Encoding::UTF_8,
18
+ Encoding::EUC_JP,
19
+ Encoding::Windows_31J
20
+ ].freeze
21
+
22
+ module_function
23
+
24
+ def read_source(path, requested_encoding = nil)
25
+ bytes = File.binread(path)
26
+ encoding = if requested_encoding.nil? || requested_encoding.casecmp('auto').zero?
27
+ detect_encoding(bytes)
28
+ else
29
+ find_encoding(requested_encoding)
30
+ end
31
+
32
+ unless encoding
33
+ raise InputEncodingError,
34
+ "#{path}: unable to detect input encoding; " \
35
+ "use --input-encoding ENCODING"
36
+ end
37
+
38
+ source = bytes.dup.force_encoding(encoding)
39
+ unless source.valid_encoding?
40
+ raise InputEncodingError,
41
+ "#{path}: invalid byte sequence in #{encoding.name}"
42
+ end
43
+
44
+ source.encode(Encoding::UTF_8).sub(/\A\uFEFF/, '')
45
+ rescue Encoding::InvalidByteSequenceError,
46
+ Encoding::UndefinedConversionError => error
47
+ raise InputEncodingError,
48
+ "#{path}: cannot convert #{encoding.name} to UTF-8: #{error.message}"
49
+ end
50
+
51
+ def detect_encoding(bytes)
52
+ bom = BOM_ENCODINGS.find { |marker, _encoding| bytes.start_with?(marker) }
53
+ return bom[1] if bom
54
+
55
+ if iso_2022_jp?(bytes) && decodable_as?(bytes, Encoding::ISO_2022_JP)
56
+ return Encoding::ISO_2022_JP
57
+ end
58
+
59
+ AUTO_ENCODINGS.find { |encoding| decodable_as?(bytes, encoding) }
60
+ end
61
+
62
+ def iso_2022_jp?(bytes)
63
+ bytes.include?("\e$") || bytes.include?("\e(")
64
+ end
65
+
66
+ def decodable_as?(bytes, encoding)
67
+ source = bytes.dup.force_encoding(encoding)
68
+ source.valid_encoding? && begin
69
+ source.encode(Encoding::UTF_8)
70
+ true
71
+ rescue Encoding::InvalidByteSequenceError,
72
+ Encoding::UndefinedConversionError
73
+ false
74
+ end
75
+ end
76
+
77
+ def find_encoding(name)
78
+ Encoding.find(name)
79
+ rescue ArgumentError
80
+ raise InputEncodingError, "unknown input encoding: #{name}"
81
+ end
82
+ end
83
+
6
84
  interwiki_map = {}
7
85
  use_wiki_name = true
8
86
  preserve_plugins = false
87
+ input_encoding = nil
9
88
 
10
89
  OptionParser.new do |opts|
11
90
  opts.banner = "Usage: hiki2md [options] <file>"
@@ -25,6 +104,14 @@ OptionParser.new do |opts|
25
104
  opts.on("--preserve-plugins", "Keep Hiki plugins as escaped Markdown text") do
26
105
  preserve_plugins = true
27
106
  end
107
+
108
+ opts.on(
109
+ "-E",
110
+ "--input-encoding ENCODING",
111
+ "Source encoding (default: auto)"
112
+ ) do |encoding|
113
+ input_encoding = encoding
114
+ end
28
115
  end.parse!
29
116
 
30
117
  if ARGV.size != 1
@@ -42,4 +129,12 @@ hiki2md = Hiki2md.new(
42
129
  use_wiki_name: use_wiki_name,
43
130
  preserve_plugins: preserve_plugins
44
131
  )
45
- puts hiki2md.convert(File.read(input_file))
132
+
133
+ begin
134
+ source = Hiki2mdCommand.read_source(input_file, input_encoding)
135
+ rescue Hiki2mdCommand::InputEncodingError => error
136
+ warn "hiki2md: #{error.message}"
137
+ exit 1
138
+ end
139
+
140
+ puts hiki2md.convert(source)
@@ -1,3 +1,3 @@
1
1
  class Hiki2md
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hiki2md
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masanori Kado
@@ -88,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  requirements: []
91
- rubygems_version: 4.0.13
91
+ rubygems_version: 4.0.19
92
92
  specification_version: 4
93
93
  summary: Converter of Hiki to Markdown
94
94
  test_files: []