pandocomatic 0.0.2 → 0.0.4

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
  SHA1:
3
- metadata.gz: 9bb00b9f3b336ff545db723e8148c4328f31523f
4
- data.tar.gz: 5efa1bc50a8f98269467ef14b72e41715f4f4706
3
+ metadata.gz: 270f53bbe40f85d3e270da8512c8c43b24b4f433
4
+ data.tar.gz: 9d637b18ad586b9513a8eae8d5e6ed9f0d08df0b
5
5
  SHA512:
6
- metadata.gz: a0c11901a985c60c0103cd53796fb884c180568cabb35ce001b476c661f07553c9c14bd027603a0cc66f21b233294f60fc46cfd8944ec758b7fe0c8e5596ce7d
7
- data.tar.gz: a19731270d23f2ca21acf6fdf5fe017fe8a629aff100661669c69f758396ff59ba0fe33dcd25d7f40aafe853645a7f328860aaaf335b6105f605c7c6ce42135d
6
+ metadata.gz: c6ce8bb13042c452f0087ab30435c1ea72e76f509f31b475fdbd1f50f041829ff49e5b2d68efee5b731e41de397dd5694287fc3216369f9fa5503df877a5e1db
7
+ data.tar.gz: a1c5c4f72999edf47d31a4afbb02285d8aab3f8b6199f0bb42a46037e81e9c6c5533e30ae671e08b78c3aa7c1abf2fc87215690aab51c1d136e270782792a48f
data/bin/pandocomatic CHANGED
@@ -1,74 +1,76 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'trollop'
4
- require 'yaml'
4
+ require 'fileutils'
5
5
 
6
6
  require_relative '../lib/pandocomatic/dir_converter.rb'
7
7
  require_relative '../lib/pandocomatic/file_converter.rb'
8
8
  require_relative '../lib/pandocomatic/configuration.rb'
9
9
 
10
- def convert_file input, opts
11
- puts "converting file"
12
- end
13
-
14
- def convert_dir input, opts
15
- puts "converting dir"
16
- end
17
-
18
- def convert_tree input, opts
19
- puts "Converting tree"
20
- end
21
-
22
10
  opts = Trollop::options do
23
- version "pandocomatic 0.0.1"
11
+ version "pandocomatic 0.0.3"
24
12
  banner <<-EOB
25
13
 
26
14
  Pandocomatic automates the use of pandoc (<http://www.pandoc.org>). It can be
27
- used to convert a file, a directory, or a directory tree.
15
+ used to convert one file or a whole directory (tree).
28
16
 
29
17
  Usage:
30
18
 
31
- Convert a file
32
-
33
- pandocomatic [--config file.yaml] --output output.file input.file
34
-
35
- Convert a directory or directory tree
36
-
37
- pandocomatic [--config file.yaml] [--recursive] --output output.dir input.dir
19
+ pandocomatic [--config pandocomatic.yaml] --output output input
38
20
 
39
21
  Options:
40
22
  EOB
41
- opt :config, "pandocomatic configuration file", :type => :string
42
- opt :recursive, "apply pandocomatic recursively"
43
- opt :target, "named conversion target", :type => :string
23
+
24
+ opt :config, "Pandocomatic configuration file, default is ./pandocomatic.yaml", :type => :string
44
25
  opt :output, "output file or directory", :type => :string
26
+
27
+
45
28
  end
46
29
 
47
30
  # input file/directory
48
31
  Trollop::die "Expect exactly one input file or directory" if ARGV.length != 1
49
32
  input = ARGV.first
50
33
 
34
+ # output file/directory
51
35
  Trollop::die "Expect an output file or directory" if opts[:output].nil?
52
36
  output = opts[:output]
53
37
 
54
38
  # Configuration
55
- if opts[:config].nil? then
56
- config = Pandocomatic::Configuration.new
39
+ if opts[:config].nil?
40
+ if Dir.entries(Dir.pwd).include? 'pandocomatic.yaml'
41
+ settings_file = File.join Dir.pwd, 'pandocomatic.yaml'
42
+ else
43
+ default_dir = File.join Dir.home, '.pandocomatic'
44
+ default_config = File.join default_dir, 'pandocomatic.yaml'
45
+ begin
46
+ if not Dir.exist? default_dir
47
+ Dir.mkdir default_dir
48
+ end
49
+
50
+ if not File.exist? default_config
51
+ config_template = File.absolute_path '../lib/pandocomatic/default_configuration.yaml', __dir__
52
+ FileUtils.cp config_template, default_config
53
+ end
54
+ rescue Exception => e
55
+ raise "Failed creating default pandocomatic file at #{default_config}: #{e.message}"
56
+ end
57
+ settings_file = default_config
58
+ end
57
59
  else
58
- if not File.exist? opts[:config] or not File.readable? opts[:config] then
59
- Trollop::die "Cannot read configuration file #{opts[:config]}" if File
60
- end
60
+ settings_file = opts[:config]
61
+ end
61
62
 
62
- config = Pandocomatic::Configuration.new YAML.load_file opts[:config]
63
+ if not File.exist? settings_file or not File.readable? settings_file then
64
+ Trollop::die "Cannot read configuration file #{settings_file}" if File
63
65
  end
64
66
 
67
+ config = Pandocomatic::Configuration.new settings_file
65
68
 
66
69
  if File.directory? input then
67
70
  if File.exist? output and not File.directory? output then
68
71
  Trollop::die "Expected an output directory, found a file instead"
69
72
  end
70
73
 
71
- config.configure({'recursive' => true}) if opts[:recursive]
72
74
  Pandocomatic::DirConverter.new(input, output, config).convert
73
75
 
74
76
  else
@@ -1,124 +1,160 @@
1
1
  module Pandocomatic
2
2
 
3
- require 'paru/pandoc'
4
-
5
- DEFAULT_CONFIG = {
6
- 'recursive' => true,
7
- 'follow_links' => false,
8
- 'skip' => ['.*', 'pandocomatic.yaml'],
9
- 'targets' => {
10
- 'markdown' => {
11
- 'pattern' => ['*.markdown', '*.md'],
12
- 'pandoc' => {
13
- 'from' => 'markdown',
14
- 'to' => 'html5'
15
- }
16
- }
17
- }
18
- }
19
-
20
- FORMAT_TO_EXT = {
21
- 'native' => 'hs',
22
- 'markdown_strict' => 'markdown',
23
- 'markdown_phpextra' => 'markdown',
24
- 'markdown_github' => 'markdown',
25
- 'html5' => 'html',
26
- 'docx' => 'docx',
27
- 'latex' => 'tex'
28
- }
29
-
30
- class Configuration
31
-
32
- def initialize hash = DEFAULT_CONFIG
33
- @config = {
34
- 'recursive' => true,
35
- 'follow_links' => false,
36
- 'skip' => ['.*'],
37
- 'targets' => {}
38
- }
39
- @convert_patterns = {}
40
- configure hash
41
- end
3
+ require 'yaml'
4
+ require 'paru/pandoc'
5
+
6
+ DEFAULT_CONFIG = YAML.load_file File.join(__dir__, 'default_configuration.yaml')
7
+
8
+ FORMAT_TO_EXT = {
9
+ 'native' => 'hs',
10
+ 'markdown_strict' => 'markdown',
11
+ 'markdown_phpextra' => 'markdown',
12
+ 'markdown_github' => 'markdown',
13
+ 'html5' => 'html',
14
+ 'docx' => 'docx',
15
+ 'latex' => 'tex'
16
+ }
17
+
18
+ class Configuration
19
+
20
+ def initialize filename
21
+ begin
22
+ path = File.absolute_path filename
23
+ settings = YAML.load_file path
24
+ if settings['settings'] and settings['settings']['data-dir'] then
25
+ data_dir = settings['settings']['data-dir']
26
+ src_dir = File.dirname filename
27
+ if data_dir.start_with? '.' then
28
+ @data_dir = File.absolute_path data_dir, src_dir
29
+ else
30
+ @data_dir = data_dir
31
+ end
32
+ else
33
+ @data_dir = File.join Dir.home, '.pandocomatic'
34
+ end
35
+ rescue Exception => e
36
+ raise "Unable to load configuration file #{settings}: #{e.message}"
37
+ end
38
+
39
+ @settings = {'skip' => ['.*', 'pandocomatic.yaml']} # hidden files will always be skipped, as will pandocomatic configuration files
40
+ @templates = {}
41
+ @convert_patterns = {}
42
+ configure settings
43
+ end
42
44
 
43
- def configure options
44
- options.each do |key, value|
45
- if key == 'targets' then
46
- update_targets value
47
- else
48
- @config[key] = value
45
+ def reconfigure filename
46
+ begin
47
+ settings = YAML.load_file filename
48
+ new_config = Marshal.load(Marshal.dump(self))
49
+ new_config.configure settings
50
+ new_config
51
+ rescue Exception => e
52
+ raise "Unable to load configuration file #{filename}: #{e.message}"
53
+ end
49
54
  end
50
- end
51
- end
52
55
 
53
- def reconfigure options
54
- new_config = Marshal.load(Marshal.dump(self))
55
- new_config.configure options
56
- new_config
57
- end
56
+ def configure settings
57
+ reset_settings settings['settings'] if settings.has_key? 'settings'
58
+ if settings.has_key? 'templates' then
59
+ settings['templates'].each do |name, template|
60
+ reset_template name, template
61
+ end
62
+ end
63
+ end
58
64
 
59
- def marshal_dump
60
- [@config, @convert_patterns]
61
- end
65
+ def marshal_dump
66
+ [@data_dir, @settings, @templates, @convert_patterns]
67
+ end
62
68
 
63
- def marshal_load array
64
- @config, @convert_patterns = array
65
- end
69
+ def marshal_load array
70
+ @data_dir, @settings, @templates, @convert_patterns = array
71
+ end
72
+
73
+ def skip? src
74
+ if @settings.has_key? 'skip' then
75
+ @settings['skip'].any? {|glob| File.fnmatch glob, File.basename(src)}
76
+ else
77
+ false
78
+ end
79
+ end
66
80
 
67
- def update_targets targets
68
- targets.each do |name, options|
69
- @config['targets'][name] = options
70
- @convert_patterns[name] = options['pattern']
71
- end
72
- end
81
+ def convert? src
82
+ @convert_patterns.values.flatten.any? {|glob| File.fnmatch glob, File.basename(src)}
83
+ end
73
84
 
74
- def skip? src
75
- @config['skip'].any? {|pattern| File.fnmatch pattern, File.basename(src)}
76
- end
85
+ def recursive?
86
+ @settings['recursive']
87
+ end
77
88
 
78
- def convert? src
79
- @convert_patterns.values.flatten.any? {|pattern| File.fnmatch pattern, File.basename(src)}
80
- end
89
+ def follow_links?
90
+ @settings['follow_links']
91
+ end
81
92
 
82
- def recursive?
83
- @config['recursive']
84
- end
93
+ def set_extension dst
94
+ dir = File.dirname dst
95
+ ext = File.extname dst
96
+ basename = File.basename dst, ext
97
+ File.join dir, "#{basename}.#{find_extension dst}"
98
+ end
85
99
 
86
- def follow_links?
87
- @config['follow_links']
88
- end
89
-
90
- def set_extension dst
91
- dir = File.dirname dst
92
- ext = File.extname dst
93
- basename = File.basename dst, ext
94
- File.join dir, "#{basename}.#{find_extension dst}"
95
- end
100
+ def find_extension dst
101
+ template = determine_template dst
102
+ if template.nil? then
103
+ extension = 'html'
104
+ else
105
+ to = @templates[template]['pandoc']['to']
106
+ extension = FORMAT_TO_EXT[to] || to
107
+ end
108
+ end
96
109
 
97
- def find_extension dst
98
- target = determine_target dst
99
- if target.nil? then
100
- extension = 'html'
101
- else
102
- to = @config['targets'][target]['pandoc']['to']
103
- extension = FORMAT_TO_EXT[to] || to
104
- end
105
- end
110
+ def get_template template_name
111
+ @templates[template_name]
112
+ end
106
113
 
107
-
108
- def get_target_config target
109
- @config['targets'][target]
110
- end
114
+ def determine_template src
115
+ @convert_patterns.select do |template_name, globs|
116
+ globs.any? {|glob| File.fnmatch glob, File.basename(src)}
117
+ end.keys.first
118
+ end
111
119
 
112
- def determine_target src
113
- @convert_patterns.select do |target, patterns|
114
- patterns.any? {|pattern| File.fnmatch pattern, File.basename(src)}
115
- end.keys.first
116
- end
120
+ def update_path path, src_dir
121
+ if path.start_with? './'
122
+ # refers to a local (to file) dir
123
+ File.join src_dir, path
124
+ elsif path.start_with? '/' then
125
+ path
126
+ else
127
+ # refers to data-dir
128
+ File.join @data_dir, path
129
+ end
130
+ end
117
131
 
118
- def to_s
119
- @config
120
- end
132
+ private
133
+
134
+ def reset_settings settings
135
+ settings.each do |setting, value|
136
+ case setting
137
+ when 'skip'
138
+ @settings['skip'] = @settings['skip'].concat(value).uniq
139
+ when 'data-dir'
140
+ next # skip data-dir setting; is set once in initialization
141
+ else
142
+ @settings[setting] = value
143
+ end
144
+ end
145
+ end
146
+
147
+ def reset_template name, template
148
+ if @templates.has_key? name then
149
+ @templates[name].merge! template
150
+ else
151
+ @templates[name] = template
152
+ end
153
+ if template.has_key? 'glob' then
154
+ @convert_patterns[name] = template['glob']
155
+ end
156
+ end
121
157
 
122
- end
158
+ end
123
159
 
124
160
  end
@@ -0,0 +1,13 @@
1
+ settings:
2
+ recursive: true
3
+ follow-symlinks: true
4
+ skip: ['.*', 'pandocomatic.yaml']
5
+ templates:
6
+ markdown-to-html:
7
+ glob: ['*.markdown', '*.md']
8
+ preprocessors: []
9
+ pandoc:
10
+ from: markdown
11
+ to: html5
12
+ standalone: true
13
+ postprocessors: []
@@ -1,7 +1,6 @@
1
1
  module Pandocomatic
2
2
 
3
3
  require 'fileutils'
4
-
5
4
  require_relative 'file_converter.rb'
6
5
 
7
6
  CONFIG_FILE = 'pandocomatic.yaml'
@@ -27,12 +26,15 @@ module Pandocomatic
27
26
 
28
27
  dst = File.join dst_dir, filename
29
28
 
30
- if File.directory? src and config.recursive?
29
+ if File.directory? src then
30
+ if config.recursive? then
31
31
 
32
- # Convert subdirectories only when the recursivity is set in the
33
- # configuration.
34
- convert src, dst, config
35
-
32
+ # Convert subdirectories only when the recursivity is set in the
33
+ # configuration.
34
+ convert src, dst, config
35
+ else
36
+ next # skip directories when not recursive
37
+ end
36
38
  elsif File.symlink? src and not config.follow_links
37
39
 
38
40
  recreate_link src, dst
@@ -68,8 +70,7 @@ module Pandocomatic
68
70
  def reconfigure current_config, src_dir
69
71
  config_file = File.join src_dir, CONFIG_FILE
70
72
  if File.exist? config_file then
71
- require 'yaml'
72
- current_config.reconfigure YAML.load_file config_file
73
+ current_config.reconfigure config_file
73
74
  else
74
75
  current_config
75
76
  end
@@ -101,7 +102,6 @@ module Pandocomatic
101
102
  end
102
103
  end
103
104
 
104
-
105
105
  end
106
106
 
107
107
  end
@@ -1,30 +1,31 @@
1
1
  module Pandocomatic
2
2
 
3
-
4
3
  require 'paru/pandoc'
5
4
  require_relative 'pandoc_metadata.rb'
5
+ require_relative 'processor.rb'
6
+ require_relative 'fileinfo_preprocessor'
6
7
 
7
8
  class FileConverter
8
9
 
9
- def initialize
10
- end
11
-
12
10
  def convert src, dst, current_config
11
+ @config = current_config
13
12
  metadata = PandocMetadata.load_file src
14
13
 
15
- if metadata.has_target? then
16
- target = metadata.target
14
+ if metadata.has_template? then
15
+ template_name = metadata.template_name
17
16
  else
18
- target = current_config.determine_target src
17
+ template_name = @config.determine_template src
19
18
  end
20
19
 
21
- config = current_config.get_target_config target
22
- pandoc_options = (config['pandoc'] || {}).merge(metadata.pandoc_options || {})
20
+ template = @config.get_template template_name
21
+
22
+ pandoc_options = (template['pandoc'] || {}).merge(metadata.pandoc_options || {})
23
23
 
24
24
  input = File.read src
25
- input = preprocess input, config
26
- input = pandoc input, pandoc_options
27
- output = postprocess input, config
25
+ input = FileInfoPreprocessor.run input, src
26
+ input = preprocess input, template
27
+ input = pandoc input, pandoc_options, File.dirname(src)
28
+ output = postprocess input, template
28
29
 
29
30
  if dst.to_s.empty? and metadata.pandoc_options.has_key? 'output'
30
31
  dst = metadata.pandoc_options['output']
@@ -37,9 +38,30 @@ module Pandocomatic
37
38
 
38
39
  private
39
40
 
40
- def pandoc input, options
41
+ PANDOC_OPTIONS_WITH_PATH = [
42
+ 'filter',
43
+ 'template',
44
+ 'css',
45
+ 'include-in-header',
46
+ 'include-before-body',
47
+ 'include-after-body',
48
+ 'reference-odt',
49
+ 'reference-docx',
50
+ 'epub-stylesheet',
51
+ 'epub-cover-image',
52
+ 'epub-metadata',
53
+ 'epub-embed-font',
54
+ 'bibliography',
55
+ 'csl'
56
+ ]
57
+
58
+ def pandoc input, options, src_dir
41
59
  converter = Paru::Pandoc.new
42
60
  options.each do |option, value|
61
+
62
+ value = @config.update_path value, src_dir if
63
+ PANDOC_OPTIONS_WITH_PATH.include? option
64
+
43
65
  converter.send option, value unless option == 'output'
44
66
  # don't let pandoc write the output to enable postprocessing
45
67
  end
@@ -61,14 +83,14 @@ module Pandocomatic
61
83
  processors = config[type]
62
84
  output = input
63
85
  processors.each do |processor|
64
- output = processor << output
86
+ output = Processor.run(@config.update_path(type, processor), output)
65
87
  end
88
+ output
66
89
  else
67
90
  input
68
91
  end
69
92
  end
70
93
 
71
-
72
94
  end
73
95
 
74
96
  end
@@ -0,0 +1,15 @@
1
+ module Pandocomatic
2
+ class FileInfoPreprocessor < Processor
3
+ def self.run input, path
4
+ created_at = File.stat(path).ctime
5
+ modified_at = File.stat(path).mtime
6
+ output = input
7
+ output << "\n---\n"
8
+ output << "fileinfo:\n"
9
+ output << " path: '#{path}'\n"
10
+ output << " created: #{created_at.strftime '%Y-%m-%d'}\n"
11
+ output << " modified: #{modified_at.strftime '%Y-%m-%d'}\n"
12
+ output << "..."
13
+ end
14
+ end
15
+ end
@@ -31,13 +31,15 @@ module Pandocomatic
31
31
  end
32
32
  end
33
33
 
34
- def has_target?
35
- has_key? 'pandocomatic' and self['pandocomatic'].has_key? 'target'
34
+ def has_template?
35
+ has_key? 'pandocomatic' and
36
+ self['pandocomatic'].has_key? 'use-template' and
37
+ not self['pandocomatic']['use-template'].empty?
36
38
  end
37
39
 
38
- def target
39
- if has_target? then
40
- self['pandocomatic']['target']
40
+ def template_name
41
+ if has_template? then
42
+ self['pandocomatic']['use-template']
41
43
  else
42
44
  ''
43
45
  end
@@ -0,0 +1,13 @@
1
+ module Pandocomatic
2
+
3
+ require 'open3'
4
+
5
+ class Processor
6
+
7
+ def self.run script, input
8
+ output, status = Open3.capture2(script, :stdin_data => input)
9
+ output
10
+ end
11
+
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pandocomatic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Huub de Beer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-14 00:00:00.000000000 Z
11
+ date: 2015-03-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: paru
@@ -56,16 +56,17 @@ description: 'Automate the use of pandoc <http://pandoc.org>: use pandocomatic a
56
56
  email: Huub@heerdebeer.org
57
57
  executables:
58
58
  - pandocomatic
59
- - pandoc2yaml
60
59
  extensions: []
61
60
  extra_rdoc_files: []
62
61
  files:
63
- - bin/pandoc2yaml
64
62
  - bin/pandocomatic
65
63
  - lib/pandocomatic/configuration.rb
64
+ - lib/pandocomatic/default_configuration.yaml
66
65
  - lib/pandocomatic/dir_converter.rb
67
66
  - lib/pandocomatic/file_converter.rb
67
+ - lib/pandocomatic/fileinfo_preprocessor.rb
68
68
  - lib/pandocomatic/pandoc_metadata.rb
69
+ - lib/pandocomatic/processor.rb
69
70
  homepage: https://github.com/htdebeer/pandocomatic
70
71
  licenses:
71
72
  - GPL3
data/bin/pandoc2yaml DELETED
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'trollop'
4
- require 'yaml'
5
-
6
- require_relative '../lib/pandocomatic/pandoc_metadata.rb'
7
-
8
- opts = Trollop::options do
9
- version "pandoc2yaml 1"
10
- banner <<-EOB
11
-
12
- pandoc2yaml collects the metadata in a pandoc markdown file and exports it to
13
- yaml.
14
-
15
- Usage:
16
-
17
- pandoc2yaml [-o output.yaml] input.markdown
18
-
19
- Options:
20
- EOB
21
-
22
- opt :output, "optional output file, use STDOUT as default", :type => :string
23
- end
24
-
25
- begin
26
- if ARGV.length != 1 then
27
- Trollop::die "pandoc2yaml expects one input file as argument"
28
- end
29
-
30
- input = ARGV.first
31
-
32
- Trollop::die "#{input} does not exist" if not File.exist? input
33
- Trollop::die "#{input} is not a file" if not File.file? input
34
- Trollop::die "#{input} is not readable" if not File.readable? input
35
-
36
- metadata = YAML.dump Pandocomatic::PandocMetadata.load_file input
37
-
38
- if opts[:output].nil? then
39
- $stdout << metadata
40
- else
41
- File.open(opts[:output], "w") do |file|
42
- file << metadata
43
- end
44
- end
45
-
46
- rescue Exception => e
47
- warn "Error while collecting metadata: #{e.message}"
48
- end