code_rippa 0.0.6 → 0.0.7

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