pandocomatic 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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