code_rippa 0.0.6 → 0.0.7

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.
Files changed (81) hide show
  1. data/.gitignore +2 -0
  2. data/README.md +35 -32
  3. data/bin/code_rippa +59 -79
  4. data/code_rippa.gemspec +4 -1
  5. data/lib/code_rippa.rb +321 -303
  6. data/lib/code_rippa/render/latex/all_hallows_eve_custom.render +96 -0
  7. data/lib/code_rippa/render/latex/argonaut.render +120 -0
  8. data/lib/code_rippa/render/latex/bbedit.render +132 -0
  9. data/lib/code_rippa/render/latex/black_pearl.render +123 -0
  10. data/lib/code_rippa/render/latex/black_pearl_ii.render +147 -0
  11. data/lib/code_rippa/render/latex/bongzilla.render +78 -0
  12. data/lib/code_rippa/render/latex/close_to_the_sea.render +90 -0
  13. data/lib/code_rippa/render/latex/clouds.render +117 -0
  14. data/lib/code_rippa/render/latex/clouds_midnight.render +120 -0
  15. data/lib/code_rippa/render/latex/coda.render +102 -0
  16. data/lib/code_rippa/render/latex/cssedit.render +90 -0
  17. data/lib/code_rippa/render/latex/django.render +129 -0
  18. data/lib/code_rippa/render/latex/django_smoothy.render +132 -0
  19. data/lib/code_rippa/render/latex/emacs_strict.render +84 -0
  20. data/lib/code_rippa/render/latex/espresso.render +102 -0
  21. data/lib/code_rippa/render/latex/espresso_tutti.render +117 -0
  22. data/lib/code_rippa/render/latex/fade_to_grey.render +99 -0
  23. data/lib/code_rippa/render/latex/fake.render +186 -0
  24. data/lib/code_rippa/render/latex/fluidvision.render +132 -0
  25. data/lib/code_rippa/render/latex/forlatex.render +90 -0
  26. data/lib/code_rippa/render/latex/friendship_bracelet.render +102 -0
  27. data/lib/code_rippa/render/latex/github.render +180 -0
  28. data/lib/code_rippa/render/latex/glitterbomb.render +120 -0
  29. data/lib/code_rippa/render/latex/happy_happy_joy_joy_2.render +198 -0
  30. data/lib/code_rippa/render/latex/idlefingers.render +123 -0
  31. data/lib/code_rippa/render/latex/ir_black.render +213 -0
  32. data/lib/code_rippa/render/latex/ir_white.render +207 -0
  33. data/lib/code_rippa/render/latex/krtheme.render +162 -0
  34. data/lib/code_rippa/render/latex/lowlight.render +174 -0
  35. data/lib/code_rippa/render/latex/made_of_code.render +186 -0
  36. data/lib/code_rippa/render/latex/merbivore.render +99 -0
  37. data/lib/code_rippa/render/latex/merbivore_soft.render +99 -0
  38. data/lib/code_rippa/render/latex/{moc.render → mocththeme.render} +1 -1
  39. data/lib/code_rippa/render/latex/monoindustrial.render +132 -0
  40. data/lib/code_rippa/render/latex/monokai.render +96 -0
  41. data/lib/code_rippa/render/latex/multimarkdown.render +75 -0
  42. data/lib/code_rippa/render/latex/pastie.render +102 -0
  43. data/lib/code_rippa/render/latex/putty.render +93 -0
  44. data/lib/code_rippa/render/latex/rails_envy.render +99 -0
  45. data/lib/code_rippa/render/latex/railscasts.render +93 -0
  46. data/lib/code_rippa/render/latex/rdark.render +93 -0
  47. data/lib/code_rippa/render/latex/rubyblue.render +129 -0
  48. data/lib/code_rippa/render/latex/rubyrobot.render +87 -0
  49. data/lib/code_rippa/render/latex/ryan_light.render +81 -0
  50. data/lib/code_rippa/render/latex/solarized_dark.render +537 -0
  51. data/lib/code_rippa/render/latex/solarized_light.render +534 -0
  52. data/lib/code_rippa/render/latex/spectacular.render +135 -0
  53. data/lib/code_rippa/render/latex/starlight.render +51 -0
  54. data/lib/code_rippa/render/latex/succulent.render +186 -0
  55. data/lib/code_rippa/render/latex/summer_camp.render +78 -0
  56. data/lib/code_rippa/render/latex/summer_camp_mod.render +78 -0
  57. data/lib/code_rippa/render/latex/swyphs_ii.render +105 -0
  58. data/lib/code_rippa/render/latex/tango.render +135 -0
  59. data/lib/code_rippa/render/latex/text_ex_machina.render +96 -0
  60. data/lib/code_rippa/render/latex/tubster.render +93 -0
  61. data/lib/code_rippa/render/latex/upstream.render +135 -0
  62. data/lib/code_rippa/render/latex/upstream_sunburst.render +195 -0
  63. data/lib/code_rippa/render/latex/upstream_vibrant.render +147 -0
  64. data/lib/code_rippa/render/latex/vibrant_fin.render +141 -0
  65. data/lib/code_rippa/render/latex/vibrant_ink.render +141 -0
  66. data/lib/code_rippa/render/latex/vibrant_tango.render +141 -0
  67. data/lib/code_rippa/render/latex/whys_poignant.render +72 -0
  68. data/lib/code_rippa/render/latex/zenburn.render +192 -0
  69. data/lib/code_rippa/syntax/coffeescript.syntax +292 -0
  70. data/lib/code_rippa/uv_overrides.rb +1 -1
  71. data/lib/code_rippa/version.rb +2 -1
  72. data/test/test_private_methods.rb +24 -24
  73. data/test/test_public_methods.rb +2 -2
  74. metadata +115 -11
  75. data/lib/code_rippa/syntax/html.syntax +0 -362
  76. data/lib/code_rippa/syntax/latex.syntax +0 -566
  77. data/lib/code_rippa/syntax/latex_beamer.syntax +0 -41
  78. data/lib/code_rippa/syntax/latex_log.syntax +0 -50
  79. data/lib/code_rippa/syntax/latex_memoir.syntax +0 -64
  80. data/lib/code_rippa/syntax/tex.syntax +0 -86
  81. data/lib/code_rippa/syntax/tex_math.syntax +0 -49
data/.gitignore CHANGED
@@ -4,3 +4,5 @@ log/*.log
4
4
  tmp/
5
5
  .sass-cache/
6
6
  .DS_Store
7
+ *.gem
8
+ out.*
data/README.md CHANGED
@@ -2,7 +2,12 @@
2
2
 
3
3
  [![Build Status](https://secure.travis-ci.org/benjamintanweihao/code_rippa.png)](http://travis-ci.org/benjamintanweihao/code_rippa)
4
4
 
5
- CodeRippa takes your source code and turns it into a beautiful PDF file. Currently, it supports 150 languages and 15 themes, all of which are available in TextMate. More syntaxes and themes will be available soon.
5
+ _CodeRippa_ takes your source code and turns it into a beautiful PDF file. Currently, it supports 150 languages and 84 themes, all of which are available in TextMate.
6
+
7
+ ## Prerequisites
8
+
9
+ You will definitely need a TeX distribution installed. To check, simply type `pdflatex`.
10
+ In case your system doesn't have `pdflatex`, you should install a [LaTeX](http://www.tug.org/texlive/) distribution.
6
11
 
7
12
  ## Installation
8
13
 
@@ -16,64 +21,53 @@ CodeRippa takes your source code and turns it into a beautiful PDF file. Current
16
21
  -l, --list-themes List all available themes
17
22
  -t, --theme THEME Selected theme
18
23
  -n, --list-syntax List all available syntax
19
- -s, --syntax SYNTAX Selected syntax
20
- -x, --excluded-exts E1,E2,EN Exclude these extensions when processing
21
24
  -h, --help Display this screen
22
25
 
23
- ### List all available themes
26
+ ### List all available themes (84 and counting!)
27
+
28
+ Many of the themes found in CodeRippa can be found [here](http://textmatetheme.com/)
24
29
 
25
30
  $ code_rippa -l
26
31
 
27
32
  active4d
28
33
  all_hallows_eve
29
34
  amy
30
- moc
35
+ made_of_code
31
36
  twilight
32
37
  zenburnesque
33
38
  ... more themes omitted
34
-
35
- ### List all supported syntax
36
-
37
- $ code_rippa -n
38
-
39
- actionscript
40
- erlang
41
- java
42
- javascript
43
- prolog
44
- ruby
45
- yaml
46
- ... more syntaxes omitted
47
-
39
+
48
40
  ### Producing PDF from a single file
49
41
 
50
42
  Example:
51
-
52
- $ code_rippa -s ruby -t zenburnesque path_to_single_file.rb
53
43
 
54
- Note that the output file is saved as _out.tex_ in the current directory where _code_rippa_ was called from.
44
+ Without theme specified (defaults to: _made_of_code_):
55
45
 
56
- $ pdflatex out.tex # Saved as out.pdf
46
+ $ code_rippa path_to_single_file.rb
47
+
48
+ With theme specified:
49
+
50
+ $ code_rippa -t zenburnesque path_to_single_file.rb
51
+
52
+ Note that the output file is saved as _out.pdf_ in the current directory where _code_rippa_ was called from.
57
53
 
58
-
59
54
  ### Producing PDF from a directory
60
55
 
61
56
  Example:
62
57
 
63
- $ code_rippa -s java -t moc path_to_directory
58
+ Without theme specified (defaults to: _made_of_code_):
59
+
60
+ $ code_rippa path_to_directory
64
61
 
65
- Note that the output file is saved as _out.tex_ in the current directory where _code_rippa_ was called from.
62
+ With theme specified:
66
63
 
67
- Then, you'll need to run _pdflatex_ __twice__. This is because LaTeX needs to generate the bookmarks.
64
+ $ code_rippa -t rubyblue path_to_directory
68
65
 
69
- $ pdflatex out.tex # Saved as out.pdf
70
- $ pdflatex out.tex # Remember to run this twice!
71
-
72
- Note: In case your system doesn't have `pdflatex`, you can get a [LaTeX](http://www.tug.org/texlive/) distribution.
66
+ Note that the output file is saved as _out.pdf_ in the current directory where _code_rippa_ was called from.
73
67
 
74
68
  ## Credits
75
69
 
76
- None of this would be possible without the awesome [ultraviolet](https://github.com/giom/ultraviolet) and [spox-ultraviolet](https://github.com/spox/ultraviolet) gems. Props to [__lwheng__](https://github.com/lwheng) for providing most of the LaTeX help.
70
+ None of this would be possible without the awesome [ultraviolet](https://github.com/giom/ultraviolet) [spox-ultraviolet](https://github.com/spox/ultraviolet) and [language_sniffer](https://github.com/grosser/language_sniffer) gems. Props to [__lwheng__](https://github.com/lwheng) for providing most of the LaTeX help.
77
71
 
78
72
  ## Contributing
79
73
 
@@ -81,6 +75,15 @@ Currently this gem is in its infancy. Any bug reports and feature requests are v
81
75
 
82
76
  ## Changelog
83
77
 
78
+ ### 0.0.7
79
+
80
+ - Using [language_sniffer](https://github.com/grosser/language_sniffer) in place of Linguist for automated source code language detection
81
+ - Themes! Glorious themes! 84 themes to choose from! Props to [filmgirl](https://github.com/filmgirl/TextMate-Themes), and the rest of the wonderful TM users who submitted their themes.
82
+ - Wrap lines of troublesome files such as minified javascript and parser generator outputs.
83
+ - Sensible defaults, removed the need for specifying the syntax
84
+ - Detects if pdflatex is installed, and automatically runs pdflatex if so
85
+ - Proper cleanup after LaTeX successfully completes
86
+
84
87
  ### 0.0.6
85
88
 
86
89
  - Include MiniTest specs
data/bin/code_rippa CHANGED
@@ -1,7 +1,7 @@
1
1
  #! /usr/bin/env ruby
2
2
  begin
3
- require 'optparse'
4
- require 'code_rippa'
3
+ require 'optparse'
4
+ require 'code_rippa'
5
5
  rescue LoadError
6
6
  $:.unshift File.join(File.dirname(__FILE__), '..', 'lib', )
7
7
  require 'code_rippa'
@@ -9,97 +9,77 @@ end
9
9
 
10
10
  options = {}
11
11
  option_parser = OptionParser.new do |opts|
12
- opts.banner =<<END
12
+ opts.banner =<<END
13
13
 
14
14
  Usage: code_rippa [options] input_file_or_directory
15
15
 
16
16
  Parses input_file or directory and outputs a file named out.tex.
17
- It expects both the syntax and theme to be specified.
18
-
19
- To see all syntaxes, type:
20
- code_rippa -n
21
-
22
- And to see all themes, type:
17
+ Unless specified, 'Made of Code' is used as the default theme.
18
+
19
+ To see all themes, type:
23
20
  code_rippa -l
24
21
 
25
- Example:
26
-
27
- code_rippa -s ruby -t amy path_to_file.rb
28
-
29
- Renders the contents of path_to_file.rb into out.tex.
22
+ Examples:
23
+
24
+ 1. code_rippa path_to_file.rb (uses default theme)
25
+
26
+ 2. code_rippa -t rubyblue path_to_file.rb (with theme specified)
27
+
28
+ 3. code_rippa -t rubyblue path_to_dir
30
29
 
31
30
  Then run `pdflatex -interaction=batchmode out.tex` to generate the PDF output.
32
31
 
33
- "-s" and "-t" are mandatory. The rest are optional.
34
-
35
32
  Options:
36
33
  END
37
-
38
- opts.on('-s', '--syntax SYNTAX', 'Selected syntax') do |syntax|
39
- if CodeRippa.supported_syntax.include? syntax
40
- options[:syntax] = syntax
41
- else
42
- raise ArgumentError, "syntax for #{syntax} not found. Use -n to see the list of available syntax."
43
- end
44
- end
45
-
46
- opts.on('-t', '--theme THEME', 'Selected theme') do |theme|
47
- if Uv.themes.include? theme
48
- options[:theme] = theme
49
- else
50
- raise ArgumentError, "#{theme} theme not found. Use -l to see the list of available themes."
51
- end
52
- end
53
-
54
- opts.on('-n', '--list-syntax', 'List all available syntax') do
34
+
35
+ opts.on('-t', '--theme THEME', 'Selected theme') do |theme|
36
+ if Uv.themes.include? theme
37
+ options[:theme] = theme
38
+ else
39
+ raise ArgumentError, "#{theme} theme not found. Use -l to see the list of available themes."
40
+ end
41
+ end
42
+
43
+ opts.on('-n', '--list-syntax', 'List all available syntax') do
55
44
  puts CodeRippa.supported_syntax.join("\n")
56
- exit 0
57
- end
58
-
59
- opts.on('-l', '--list-themes', 'List all available themes') do
60
- puts Uv.themes.join("\n")
61
- exit 0
62
- end
63
-
64
- opts.on('-v', '--version', 'Display version number') do
65
- puts CodeRippa::VERSION
66
- exit 0
67
- end
68
-
69
- options[:excluded_exts] = []
70
- opts.on('-x', '--excluded-exts E1,E2,EN', Array, 'Exclude these extensions when processing') do |exts|
71
- options[:excluded_exts] = exts.sort!
72
- valid_exts = exts & CodeRippa.supported_exts
73
- if valid_exts != exts
74
- invalid_exts = exts - valid_exts
75
- raise ArgumentError, "These extensions are not supported: #{invalid_exts.join(" ")}. Aborting."
76
- else
77
- options[:ex_extensions] = valid_exts
78
- end
79
- end
80
-
81
- opts.on('-h', '--help', 'Display this screen') do
82
- puts opts
83
- exit 0
84
- end
45
+ exit 0
46
+ end
47
+
48
+ opts.on('-l', '--list-themes', 'List all available themes') do
49
+ puts Uv.themes.join("\n")
50
+ exit 0
51
+ end
52
+
53
+ opts.on('-v', '--version', 'Display version number') do
54
+ puts CodeRippa::VERSION
55
+ exit 0
56
+ end
57
+
58
+ opts.on('-h', '--help', 'Display this screen') do
59
+ puts opts
60
+ exit 0
61
+ end
85
62
  end
86
63
 
87
64
  begin
88
- option_parser.parse!
89
- if options[:theme] and options[:syntax] and ARGV.size == 1
90
- if FileTest.file?(ARGV[0])
91
- CodeRippa.rip_file(ARGV[0], options[:theme], options[:syntax])
92
- elsif File.directory?(ARGV[0])
93
- Dir.chdir(ARGV[0])
94
- CodeRippa.rip_dir(Dir.pwd, options[:theme], options[:syntax], options[:excluded_exts])
95
- else
96
- raise ArgumentError, "Invalid path. Aborting.\n"
97
- end
98
- exit 0
99
- else
100
- raise ArgumentError, "Missing arguments. Aborting.\n"
101
- end
65
+ option_parser.parse!
66
+ # Set default theme. TODO: Allow user to change this
67
+ options[:theme] ||= "made_of_code"
68
+
69
+ if ARGV.size == 1
70
+ if FileTest.file?(ARGV[0])
71
+ CodeRippa.parse(ARGV[0], options[:theme])
72
+ elsif File.directory?(ARGV[0])
73
+ Dir.chdir(ARGV[0])
74
+ CodeRippa.parse(Dir.pwd, options[:theme])
75
+ else
76
+ raise ArgumentError, "Invalid path. Aborting.\n"
77
+ end
78
+ exit 0
79
+ else
80
+ raise ArgumentError, "Missing arguments. Aborting.\n"
81
+ end
102
82
  rescue ArgumentError => e
103
- puts e
104
- exit 1
83
+ puts e
84
+ exit 1
105
85
  end
data/code_rippa.gemspec CHANGED
@@ -16,8 +16,11 @@ Gem::Specification.new do |gem|
16
16
  gem.require_paths = ["lib", "lib/syntax", "lib/render"]
17
17
  gem.version = CodeRippa::VERSION
18
18
  gem.required_ruby_version = '>= 1.9.0'
19
- gem.add_dependency "rainbow"
19
+ gem.add_dependency "color"
20
20
  gem.add_dependency "ansi"
21
+ gem.add_dependency "language_sniffer"
22
+ gem.add_dependency "ptools", "~> 1.2.1"
23
+ gem.add_dependency "rainbow"
21
24
  gem.add_dependency "spox-ultraviolet", "~> 0.10.5"
22
25
  gem.add_development_dependency "rake"
23
26
  gem.add_development_dependency "minitest"
data/lib/code_rippa.rb CHANGED
@@ -2,316 +2,334 @@ require 'find'
2
2
  require 'code_rippa/uv_overrides'
3
3
  require 'code_rippa/version'
4
4
  require 'ansi/progressbar'
5
+ require 'language_sniffer'
5
6
  require 'rainbow'
6
- include ANSI
7
+ require 'color'
8
+ require 'ptools'
7
9
 
10
+ include ANSI
8
11
 
9
12
  YAML::ENGINE.yamler = 'syck'
10
13
 
11
14
  module CodeRippa
12
-
13
- @@supported_syntax = nil
14
- @@supported_ext = nil
15
-
16
- # Parses the given file, and writes the output file (out.tex)
17
- # into the current directory.
18
- #
19
- # path - The file path
20
- # syntax - The syntax to perform parsing/syntax highlighting.
21
- # Note the the syntax should be supported by code_rippa.
22
- # excluded_exts - An Array of extensions to ignore during parsing.
23
- #
24
- # Examples
25
- #
26
- # rip_dir("~/code/ruby/some_folder/some_file.rb", "space_cadet", "ruby", [])
27
- #
28
- # Returns nothing.
29
- def self.rip_file(path, theme, syntax)
30
- begin
31
- srcfile = File.read(path)
32
- src_ext = File.extname(path)[1..-1]
33
- outfile = File.open('out.tex', 'w')
34
- outfile.write preamble theme
35
- outfile.write "\\textcolor{headingcolor}{\\textbf{\\texttt{#{path.gsub('_','\_').gsub('%','\%')}}}}\\\\\n"
36
- outfile.write "\\textcolor{headingcolor}{\\rule{\\linewidth}{1.0mm}}\\\\\n"
37
- outfile.write Uv.parse(srcfile, 'latex', syntax, true, theme)
38
- outfile.write endtag
39
-
40
- msg = "Completed successfully.\n".color(:green)
41
- msg << "Output file written to: "
42
- msg << "#{File.expand_path(outfile)}\n".color(:yellow)
43
- msg << "Now run "
44
- msg << "pdflatex -interaction=batchmode #{File.expand_path(outfile)} ".color(:red)
45
- msg << "** TWICE ** to generate PDF."
46
- puts msg
47
- outfile.close
48
- rescue Exception => e
49
- puts e
50
- end
51
- end
15
+
16
+ MAX_WIDTH = 120
17
+ @@supported_syntax = nil
18
+ @@supported_ext = nil
19
+
20
+ # main entry point:
21
+ # Parses the given directory/file, and writes the output file (out.tex)
22
+ # into the current directory.
23
+ #
24
+ # path - The directory path
25
+ # theme - The selected theme
26
+ #
27
+ # Examples
28
+ #
29
+ # parse("~/code/ruby/some_folder_or_file", "space_cadet")
30
+ #
31
+ # Returns nothing
32
+ def self.parse(path, theme)
33
+ # logfile = File.open('code_rippa.log', 'w')
34
+ output = ""
35
+
36
+ if FileTest.file?(path)
37
+ output = parse_file(path, theme)
38
+ else
39
+ pbar = Progressbar.new("Rippin'", Dir["**/*"].length)
40
+ counter = 0
41
+
42
+ Find.find path do |p|
43
+ # logfile << "Parsing: #{p}\n"
44
+ depth = p.to_s.count('/')
45
+
46
+ if File.basename(p)[0] == ?.
47
+ Find.prune
48
+ else
49
+ output << bookmark(p, depth, counter) if bookmarkable?(p, source_syntax(p))
50
+ begin
51
+ output << parse_file(p, theme)
52
+ rescue Exception => e
53
+ # logfile << "* Failed: #{p}\n"
54
+ end
55
+ end
56
+ counter += 1
57
+ pbar.inc
58
+ end
59
+ pbar.finish
60
+ end
61
+
62
+ outfile = File.open('out.tex', 'w')
63
+ output = preamble(theme) << output << postscript
64
+ outfile.write output
65
+
66
+ outfile.close
67
+
68
+ # Run the 'pdflatex' command
69
+ puts "=================================================="
70
+ if pdflatex_installed?
71
+ puts "pdflatex found!. Converting TeX -> PDF".color(:green)
72
+ puts "Compiling [1/2]"
73
+ `pdflatex -interaction=batchmode #{File.expand_path(outfile)}`
74
+ puts "Compiling [2/2]"
75
+ `pdflatex -interaction=batchmode #{File.expand_path(outfile)}`
76
+
77
+ # Cleanup
78
+ %w[aux log out tex].each do |ext|
79
+ path = File.expand_path(outfile).gsub!('tex', ext)
80
+ FileUtils.rm path
81
+ end
82
+ puts completed_message(path, File.expand_path(outfile))
83
+ else
84
+ puts install_pdflatex_message "#{File.expand_path(outfile)}"
85
+ end
86
+ puts "=================================================="
87
+
88
+ end
89
+
90
+
91
+ # Parses the given file, and writes the output file (out.tex)
92
+ # into the current directory.
93
+ #
94
+ # path - The file path
95
+ # theme - The selected theme
96
+ #
97
+ # Examples
98
+ #
99
+ # parse_file("~/code/ruby/some_folder/some_file.rb", "space_cadet")
100
+ #
101
+ # Returns a String of TeX output.
102
+ def self.parse_file(path, theme)
103
+ content = ""
104
+ syntax = source_syntax(path)
105
+
106
+ if rippable?(path, syntax)
107
+ content << heading(path)
108
+ output = (max_width(path) <= MAX_WIDTH) ? File.read(path) : wrap_file(path, MAX_WIDTH)
109
+ content << Uv.parse(output, 'latex', syntax, true, theme)
110
+ content << "\\clearpage\n"
111
+ end
112
+ content
113
+ end
114
+
115
+
116
+ private
117
+
118
+ # Returns True if path should be bookmarked in the output TEX/PDF document.
119
+ #
120
+ # path - The file/directory path
121
+ # syntax - The syntax to perform parsing/syntax highlighting.
122
+ # Note the the syntax should be supported by code_rippa.
123
+ #
124
+ # Examples
125
+ #
126
+ # bookmarkable?("hello.rb", "ruby")
127
+ # # => true
128
+ #
129
+ # bookmarkable?("hello.klingon", "klingon")
130
+ # # => false
131
+ #
132
+ # Returns True if path should be bookmarked.
133
+ def self.bookmarkable?(path, syntax)
134
+ if FileTest.directory?(path)
135
+ true
136
+ else
137
+ src_ext = File.extname(path)[1..-1]
138
+ if File.basename(path) == "out.tex"
139
+ false
140
+ elsif supported_exts.include?(src_ext)
141
+ true
142
+ else
143
+ false
144
+ end
145
+ end
146
+ end
147
+
148
+ # Returns True if path should be ripped as part of the output TEX file.
149
+ #
150
+ # path - The file. (directories will return false.)
151
+ # syntax - The syntax to perform parsing/syntax highlighting.
152
+ # Note the the syntax should be supported by code_rippa.
153
+ #
154
+ # Examples
155
+ #
156
+ # rippable?("hello.rb", "ruby")
157
+ # # => true
158
+ #
159
+ # rippable?("~/code/", "ruby")
160
+ # # => false
161
+ #
162
+ # rippable?("hello.klingon", "klingon")
163
+ # # => false
164
+ #
165
+ # Returns true if path should be ripped.
166
+ def self.rippable?(path, syntax)
167
+ if FileTest.directory?(path)
168
+ false
169
+ else
170
+ if supported_exts.include?(File.extname(path)[1..-1])
171
+ true
172
+ else
173
+ false
174
+ end
175
+ end
176
+ end
177
+
178
+ # Places a PDF bookmark
179
+ def self.bookmark(path, depth, counter)
180
+ "\\pdfbookmark[#{depth-2}]{#{File.basename(path).gsub('_','\_').gsub('%','\%')}}{#{counter}}\n"
181
+ end
182
+
183
+ # Returns the maximum width (number of characters) in a given file
184
+ def self.max_width(path)
185
+ IO.readlines(path).collect { |x| x.length }.max
186
+ end
187
+
188
+ # Returns the String of the wrapped text
189
+ def self.wrap(text, width)
190
+ text.gsub(/(.{1,#{width}})( +|$\n?)|(.{1,#{width}})/, "\\1\\3\n")
191
+ end
192
+
193
+ # Returns the String of the wrapped file
194
+ def self.wrap_file(path, width)
195
+ wrapped_output = ""
196
+ IO.readlines(path).each { |line| wrapped_output << wrap(line, width) }
197
+ wrapped_output
198
+ end
199
+
200
+ # Returns the String of the source file. If not found, a blank String is returned.
201
+ def self.source_syntax(path)
202
+ syntax = ""
203
+ language = ""
204
+ if FileTest.file?(path) and not File.binary?(path)
205
+ begin
206
+ language = LanguageSniffer.detect(path).language
207
+ syntax = language.name.downcase if language
208
+ rescue Exception => e
209
+ end
210
+ end
211
+ syntax
212
+ end
213
+
214
+ def self.syntax_path
215
+ Uv.syntax_path
216
+ end
217
+
218
+ # Returns an Array of supported file extensions
219
+ def self.supported_exts
220
+ if @@supported_ext
221
+ @@supported_ext
222
+ else
223
+ @@supported_ext = []
224
+ Dir.foreach(syntax_path) do |f|
225
+ if File.extname(f) == ".syntax"
226
+ y = YAML.load(File.read "#{syntax_path}/#{f}")
227
+ @@supported_ext += y["fileTypes"] if y["fileTypes"]
228
+ end
229
+ end
230
+ @@supported_ext
231
+ end
232
+ end
233
+
234
+ # Returns an Array of supported languages.
235
+ def self.supported_langs
236
+ langs = []
237
+ Dir.foreach(syntax_path) do |f|
238
+ if File.extname(f) == ".syntax"
239
+ y = YAML.load(File.read "#{syntax_path}/#{f}")
240
+ langs << y["name"] if y["name"]
241
+ end
242
+ end
243
+ langs
244
+ end
245
+
246
+ # Returns an Array of supported syntaxes.
247
+ def self.supported_syntax
248
+ if @@supported_syntax
249
+ @@supported_syntax
250
+ else
251
+ @@supported_syntax = []
252
+ Dir.foreach(syntax_path) do |f|
253
+ if File.extname(f) == ".syntax"
254
+ @@supported_syntax << File.basename(f, '.*')
255
+ end
256
+ end
257
+ @@supported_syntax
258
+ end
259
+ end
260
+
261
+ # Returns a String containing the heading of the parsed file.
262
+ def self.heading(path)
263
+ "\\textcolor{headingcolor}{\\textbf{\\texttt{#{path.gsub('_','\_').gsub('%','\%')}}}}\\\\\n" +
264
+ "\\textcolor{headingcolor}{\\rule{\\linewidth}{1.0mm}}\\\\\n"
265
+ end
266
+
267
+ # Returns the hex color code of the heading, which is the inverse of page color.
268
+ def self.heading_color(theme)
269
+ c = Color::RGB.from_html(page_color(theme))
270
+ Color::RGB.new(255-c.red, 255-c.green, 255- c.blue).html.gsub("#","").upcase
271
+ end
272
+
273
+ # Returns a String containing the hex color code of the page.
274
+ def self.page_color(theme)
275
+ f = YAML.load(File.read("#{Uv.render_path}/latex/#{theme}.render"))
276
+ /([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.match(f['listing']['begin'].split('\\')[3]).to_s
277
+ end
278
+
279
+ def self.preamble(theme)
280
+ preamble = ''
281
+ preamble << "\\documentclass[a4paper,landscape]{article}\n"
282
+ preamble << "\\pagestyle{empty}\n"
283
+ preamble << "\\usepackage{xcolor}\n"
284
+ preamble << "\\usepackage{colortbl}\n"
285
+ preamble << "\\usepackage{longtable}\n"
286
+ preamble << "\\usepackage[left=0cm,top=0.2cm,right=0cm,bottom=0.2cm,nohead,nofoot]{geometry}\n"
287
+ preamble << "\\usepackage[T1]{fontenc}\n"
288
+ preamble << "\\usepackage[scaled]{beramono}\n"
289
+ preamble << "\\usepackage[bookmarksopen,bookmarksdepth=20]{hyperref}\n"
290
+ preamble << "\\definecolor{pgcolor}{HTML}{#{page_color(theme)}}\n"
291
+ preamble << "\\definecolor{headingcolor}{HTML}{#{heading_color(theme)}}\n"
292
+ preamble << "\\pagecolor{pgcolor}\n"
293
+ preamble << "\\begin{document}\n"
294
+ preamble << "\\setlength\\LTleft\\parindent\n"
295
+ preamble << "\\setlength\\LTright\\fill\n"
296
+ preamble << "\\setlength{\\LTpre}{-10pt}\n"
297
+ preamble
298
+ end
52
299
 
53
- # Parses the given directory, and writes the output file (out.tex)
54
- # into the current directory.
55
- #
56
- # dir_path - The directory path
57
- # syntax - The syntax to perform parsing/syntax highlighting.
58
- # Note the the syntax should be supported by code_rippa.
59
- # excluded_exts - An Array of extensions to ignore during parsing.
60
- #
61
- # Examples
62
- #
63
- # rip_dir("~/code/ruby/some_folder", "space_cadet", "ruby", [])
64
- #
65
- # Returns nothing.
66
- def self.rip_dir(dir_path, theme, syntax, excluded_exts = [])
67
- pbar = Progressbar.new("Rippin'".color(:blue), Dir["**/*"].length)
68
- counter = 0
69
- outfile = File.open('out.tex', 'w')
70
-
71
- outfile.write preamble theme
72
- Find.find dir_path do |path|
73
- depth = path.to_s.count('/')
74
- if File.basename(path)[0] == ?. or File.basename(path) == "out.tex"
75
- Find.prune
76
- else
77
- begin
78
- is_rippable = rippable?(path, syntax, excluded_exts)
79
- if is_rippable
80
- outfile.write "\\textcolor{white}{\\textbf{\\texttt{#{path.gsub('_','\_').gsub('%','\%')}}}}\\\\\n"
81
- outfile.write "\\textcolor{white}{\\rule{\\linewidth}{1.0mm}}\\\\\n"
82
- end
83
-
84
- if bookmarkable?(path, syntax, excluded_exts)
85
- outfile.write "\\pdfbookmark[#{depth-2}]{#{File.basename(path).gsub('_','\_').gsub('%','\%')}}{#{counter}}\n"
86
- end
87
-
88
- if is_rippable
89
- outfile.write Uv.parse(File.read(path), 'latex', syntax, true, theme)
90
- outfile.write "\\clearpage\n"
91
- end
92
- rescue Exception => e
93
- puts e
94
- end
95
- counter += 1
96
- end
97
- pbar.inc
98
- end
99
-
100
- outfile.write endtag
101
- pbar.finish
102
-
103
- msg = "Completed successfully.\n".color(:green)
104
- msg << "Output file written to: "
105
- msg << "#{File.expand_path(outfile)}\n".color(:yellow)
106
- msg << "Now run "
107
- msg << "pdflatex -interaction=batchmode #{File.expand_path(outfile)} ".color(:red)
108
- msg << "** TWICE ** to generate PDF."
109
- puts msg
110
-
111
- outfile.close
112
- end
113
-
114
- private
115
- def self.syntax_path
116
- Uv.syntax_path
117
- end
118
-
119
- # Returns an Array of supported syntaxes. This is done by parsing
120
- # all the file names in the syntax folder.
121
- #
122
- # Examples
123
- #
124
- # supported_syntax
125
- # # => ['ruby','prolog']
126
- #
127
- # Returns an Array of supported syntaxes
128
- def self.supported_syntax
129
- if @@supported_syntax
130
- @@supported_syntax
131
- else
132
- @@supported_syntax = []
133
- Dir.foreach(syntax_path) do |f|
134
- if File.extname(f) == ".syntax"
135
- @@supported_syntax << File.basename(f, '.*')
136
- end
137
- end
138
- @@supported_syntax
139
- end
140
- end
141
-
142
- # Returns an Array of supported languages. This is done by parsing
143
- # all the file names in the syntax folder.
144
- #
145
- # Examples
146
- #
147
- # supported_langs
148
- # # => ['Ruby','Prolog']
149
- #
150
- # Returns an Array of supported languages
151
- def self.supported_langs
152
- langs = []
153
- Dir.foreach(syntax_path) do |f|
154
- if File.extname(f) == ".syntax"
155
- y = YAML.load(File.read "#{syntax_path}/#{f}")
156
- langs << y["name"] if y["name"]
157
- end
158
- end
159
- langs
160
- end
161
-
162
- # Returns an Array of file extensions that is supported by code_rippa
163
- #
164
- # Examples
165
- #
166
- # supported_langs
167
- # # => ['rb', 'Gemfile', 'erb']
168
- #
169
- # Returns an Array of supported extensions.
170
- def self.supported_exts
171
- if @@supported_ext
172
- @@supported_ext
173
- else
174
- @@supported_ext = []
175
- Dir.foreach(syntax_path) do |f|
176
- if File.extname(f) == ".syntax"
177
- y = YAML.load(File.read "#{syntax_path}/#{f}")
178
- @@supported_ext += y["fileTypes"] if y["fileTypes"]
179
- end
180
- end
181
- @@supported_ext
182
- end
183
- end
300
+ def self.postscript
301
+ "\\end{document}\n"
302
+ end
303
+
304
+ def self.completed_message(in_path, out_path)
305
+ msg = "Success!. ".color(:green)
306
+ msg << "Output file written to: "
307
+ msg << "#{out_path.gsub!('tex', 'pdf')}".color(:green)
308
+ end
184
309
 
185
- # Returns True if path should be bookmarked in the output TEX/PDF document.
186
- #
187
- # path - The file/directory path
188
- # syntax - The syntax to perform parsing/syntax highlighting.
189
- # Note the the syntax should be supported by code_rippa.
190
- # excluded_exts - An Array of extensions to ignore during parsing.
191
- #
192
- #
193
- # Examples
194
- #
195
- # bookmarkable?("hello.rb", "ruby", [])
196
- # # => true
197
- #
198
- # bookmarkable?("hello.rb", "ruby", ["rb", "html"])
199
- # # => false
200
- #
201
- # bookmarkable?("hello.klingon", "klingon", [])
202
- # # => false
203
- #
204
- # Returns True if path should be bookmarked.
205
- def self.bookmarkable?(path, syntax, excluded_exts)
206
- if FileTest.directory?(path)
207
- true
208
- else
209
- src_ext = File.extname(path)[1..-1]
210
- if File.basename(path) == "out.tex"
211
- false
212
- elsif excluded_exts.include?(src_ext)
213
- false
214
- elsif supported_exts.include?(src_ext)
215
- true
216
- else
217
- false
218
- end
219
- end
220
- end
221
-
222
- # Returns True if path should be ripped as part of the output TEX file.
223
- #
224
- # path - The file. (directories will return false.)
225
- # syntax - The syntax to perform parsing/syntax highlighting.
226
- # Note the the syntax should be supported by code_rippa.
227
- # excluded_exts - An Array of extensions to ignore during parsing.
228
- #
229
- #
230
- # Examples
231
- #
232
- # rippable?("hello.rb", "ruby", [])
233
- # # => true
234
- #
235
- # rippable?("~/code/", "ruby", [])
236
- # # => false
237
- #
238
- # rippable?("hello.rb", "ruby", ["rb", "html"])
239
- # # => false
240
- #
241
- # rippable?("hello.klingon", "klingon", [])
242
- # # => false
243
- #
244
- # Returns true if path should be ripped.
245
- def self.rippable?(path, syntax, excluded_exts)
246
- if FileTest.directory?(path)
247
- false
248
- else
249
- src_ext = File.extname(path)[1..-1]
250
- if excluded_exts.include? src_ext
251
- false
252
- elsif supported_exts.include?(src_ext)
253
- true
254
- else
255
- false
256
- end
257
- end
258
- end
310
+ def self.install_pdflatex_message(out_path)
311
+ msg = "You do not have 'pdflatex' installed!\n".color(:red)
312
+ msg << "Please install it at "
313
+ msg << "http://www.tug.org/texlive'\n".color(:yellow)
314
+ msg << "Output TEX file written to: "
315
+ msg << "#{out_path}\n".color(:yellow)
316
+ end
259
317
 
260
- # Returns the hex color code of the page color. This is done by looking at
261
- # the *.render file of the selected theme.
262
- #
263
- # theme - The selected theme.
264
- #
265
- # Examples
266
- #
267
- # page_color('moc')
268
- # # => "E8E8E8"
269
- #
270
- # Returns an String containing the hex color code of the page.
271
- def self.page_color(theme)
272
- f = YAML.load(File.read("#{Uv.render_path}/latex/#{theme}.render"))
273
- /([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.match(f['listing']['begin'].split('\\')[3]).to_s
274
- end
275
-
276
- # Returns the hex color code of the heading. This is done by looking at
277
- # the *.render file of the selected theme. The heading is present at
278
- # the top of each new document in the output TEX/PDF file.
279
- #
280
- # theme - The selected theme.
281
- #
282
- # Examples
283
- #
284
- # heading_color('moc')
285
- # # => "E8E8E8"
286
- #
287
- # Returns an String containing the hex color code of the heading.
288
- def self.heading_color(theme)
289
- f = YAML.load(File.read("#{Uv.render_path}/latex/#{theme}.render"))
290
- /([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.match(f['listing']['begin'].split('\\')[2]).to_s
291
- end
318
+ def self.pdflatex_installed?
319
+ cmd = 'pdflatex'
320
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
321
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
322
+ exts.each do |ext|
323
+ exe = "#{path}/#{cmd}#{ext}"
324
+ exe if File.executable? exe
325
+ return exe
326
+ end
327
+ end
328
+ nil
329
+ end
330
+
331
+ end
292
332
 
293
- def self.preamble(theme)
294
- preamble = ''
295
- preamble << "\\documentclass[a4paper,landscape]{article}\n"
296
- preamble << "\\pagestyle{empty}\n"
297
- preamble << "\\usepackage{xcolor}\n"
298
- preamble << "\\usepackage{colortbl}\n"
299
- preamble << "\\usepackage{longtable}\n"
300
- preamble << "\\usepackage[left=0cm,top=0.2cm,right=0cm,bottom=0.2cm,nohead,nofoot]{geometry}\n"
301
- preamble << "\\usepackage[T1]{fontenc}\n"
302
- preamble << "\\usepackage[scaled]{beramono}\n"
303
- preamble << "\\usepackage[bookmarksopen,bookmarksdepth=20]{hyperref}\n"
304
- preamble << "\\definecolor{pgcolor}{HTML}{#{page_color(theme)}}\n"
305
- preamble << "\\definecolor{headingcolor}{HTML}{#{heading_color(theme)}}\n"
306
- preamble << "\\pagecolor{pgcolor}\n"
307
- preamble << "\\begin{document}\n"
308
- preamble << "\\setlength\\LTleft\\parindent\n"
309
- preamble << "\\setlength\\LTright\\fill\n"
310
- preamble << "\\setlength{\\LTpre}{-10pt}\n"
311
- preamble
312
- end
313
-
314
- def self.endtag
315
- "\\end{document}\n"
316
- end
317
- end
333
+ # Sanity check
334
+ # CodeRippa.parse("/Users/rambo/code/ruby/code_rippa", "succulent")
335
+ # CodeRippa.parse("/Users/rambo/code/ruby/code_rippa/lib/code_rippa.rb", "amy")