win32-captureie 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +3 -0
- data/License.txt +20 -0
- data/Manifest.txt +45 -0
- data/README.txt +49 -0
- data/Rakefile +4 -0
- data/TODO.txt +78 -0
- data/bin/prtie +62 -0
- data/config/hoe.rb +72 -0
- data/config/requirements.rb +17 -0
- data/lib/win32/capture_ie/base.rb +4 -0
- data/lib/win32/capture_ie/bitmap.rb +115 -0
- data/lib/win32/capture_ie/browser.rb +119 -0
- data/lib/win32/capture_ie/cli/base.rb +7 -0
- data/lib/win32/capture_ie/cli/prt_ie.rb +100 -0
- data/lib/win32/capture_ie/commands/base.rb +39 -0
- data/lib/win32/capture_ie/commands/prt_ie.rb +66 -0
- data/lib/win32/capture_ie/ffi/base.rb +22 -0
- data/lib/win32/capture_ie/ffi/gdi32.rb +165 -0
- data/lib/win32/capture_ie/ffi/struct.rb +246 -0
- data/lib/win32/capture_ie/ffi/user32.rb +101 -0
- data/lib/win32/capture_ie/ffi.rb +3 -0
- data/lib/win32/capture_ie/screen_captor.rb +131 -0
- data/lib/win32/capture_ie/version.rb +11 -0
- data/lib/win32/capture_ie/window.rb +47 -0
- data/lib/win32/capture_ie.rb +92 -0
- data/script/destroy +14 -0
- data/script/destroy.cmd +1 -0
- data/script/generate +14 -0
- data/script/generate.cmd +1 -0
- data/script/rdoc_filter.rb +75 -0
- data/script/txt2html +74 -0
- data/script/txt2html.cmd +1 -0
- data/setup.rb +1585 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/win32/capture_ie_spec.rb +11 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/deployment2.rake +90 -0
- data/tasks/environment.rake +7 -0
- data/tasks/helper/rake.rb +58 -0
- data/tasks/helper/rake_sh_filter.rb +23 -0
- data/tasks/helper/util.rb +19 -0
- data/tasks/helper.rb +3 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +17 -0
- metadata +95 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
require "win32/capture_ie/ffi/base"
|
2
|
+
|
3
|
+
module Win32::CaptureIE::FFI
|
4
|
+
module User32 #:nodoc:
|
5
|
+
extend Win32::CaptureIE::FFI::Base
|
6
|
+
|
7
|
+
GW_HWNDFIRST = 0
|
8
|
+
GW_HWNDLAST = 1
|
9
|
+
GW_HWNDNEXT = 2
|
10
|
+
GW_HWNDPREV = 3
|
11
|
+
|
12
|
+
define_ffi_entry(:GetClassName, "LPI", "I", "user32", "GetClassNameA")
|
13
|
+
define_ffi_entry(:GetDC, "L", "L", "user32")
|
14
|
+
define_ffi_entry(:GetWindowDC, "L", "L", "user32")
|
15
|
+
define_ffi_entry(:ReleaseDC, "LL", "I", "user32")
|
16
|
+
|
17
|
+
define_ffi_entry(:OpenIcon, "L", "B", "user32")
|
18
|
+
define_ffi_entry(:CloseWindow, "L", "B", "user32")
|
19
|
+
define_ffi_entry(:BringWindowToTop, "L", "B", "user32")
|
20
|
+
define_ffi_entry(:GetActiveWindow, "", "L", "user32")
|
21
|
+
define_ffi_entry(:GetForegroundWindow, "", "L", "user32")
|
22
|
+
define_ffi_entry(:GetTopWindow, "L", "L", "user32")
|
23
|
+
define_ffi_entry(:GetWindow, "LI", "L", "user32")
|
24
|
+
define_ffi_entry(:GetWindowRect, "LP", "B", "user32")
|
25
|
+
|
26
|
+
module_function
|
27
|
+
|
28
|
+
def get_class_name(hwnd)
|
29
|
+
buf = "\0" * 255
|
30
|
+
r = GetClassName(hwnd, buf, buf.length)
|
31
|
+
raise Win32APIError, "GetClassName failed" if r.nil? or r.zero?
|
32
|
+
buf[0...r]
|
33
|
+
end
|
34
|
+
|
35
|
+
def with_window_dc(hwnd)
|
36
|
+
hdc = GetWindowDC(hwnd)
|
37
|
+
raise Win32APIError, "GetDC failed" if hdc.nil? or hdc.zero?
|
38
|
+
begin
|
39
|
+
yield hdc
|
40
|
+
ensure
|
41
|
+
ReleaseDC(hwnd, hdc)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_window_rect(hwnd)
|
46
|
+
buf = [0, 0, 0, 0].pack("L4")
|
47
|
+
GetWindowRect(hwnd, buf)
|
48
|
+
buf.unpack("L4")
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def get_top_window(hwnd)
|
53
|
+
r = GetTopWindow(hwnd)
|
54
|
+
if r.nil? or r.zero?
|
55
|
+
nil
|
56
|
+
else
|
57
|
+
r
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_window(hwnd, cmd)
|
62
|
+
r = GetWindow(hwnd, cmd)
|
63
|
+
if r.nil? or r.zero?
|
64
|
+
nil
|
65
|
+
else
|
66
|
+
r
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_first_child(hwnd)
|
71
|
+
get_top_window(hwnd)
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_first_sibling(hwnd)
|
75
|
+
get_window(hwnd, GW_HWNDFIRST)
|
76
|
+
end
|
77
|
+
|
78
|
+
def get_last_sibling(hwnd)
|
79
|
+
get_window(hwnd, GW_HWNDLAST)
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_next_sibling(hwnd)
|
83
|
+
get_window(hwnd, GW_HWNDNEXT)
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_prev_sibling(hwnd)
|
87
|
+
get_window(hwnd, GW_HWNDPREV)
|
88
|
+
end
|
89
|
+
|
90
|
+
def each_child_window(hwnd)
|
91
|
+
child = get_first_child(hwnd)
|
92
|
+
if child
|
93
|
+
yield child
|
94
|
+
while child = get_next_sibling(child)
|
95
|
+
yield child
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require "win32/capture_ie/base"
|
2
|
+
require "win32/capture_ie/ffi"
|
3
|
+
require "win32/capture_ie/bitmap"
|
4
|
+
|
5
|
+
module Win32::CaptureIE
|
6
|
+
|
7
|
+
class ScreenCaptor #:nodoc:
|
8
|
+
include Win32::CaptureIE::FFI
|
9
|
+
include Win32::CaptureIE::FFI::User32
|
10
|
+
include Win32::CaptureIE::FFI::GDI32
|
11
|
+
|
12
|
+
attr_reader :browser
|
13
|
+
def initialize(browser)
|
14
|
+
@browser = browser
|
15
|
+
end
|
16
|
+
|
17
|
+
def body
|
18
|
+
browser.body
|
19
|
+
end
|
20
|
+
|
21
|
+
def capture_browser(opts=nil)
|
22
|
+
browser.save_excursion do
|
23
|
+
opts ||= {}
|
24
|
+
h = opts[:only_drawing_area] ? browser.embedding_ie_hwnd : browser.hwnd
|
25
|
+
browser.bring_window_to_top
|
26
|
+
capture_hwnd(h)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def capture_page
|
31
|
+
browser.save_excursion do
|
32
|
+
browser.bring_window_to_top
|
33
|
+
capture_area(browser.embedding_ie_hwnd, 0, 0, body.scrollWidth, body.scrollHeight)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def capture_area(hwnd, px, py, w, h)
|
38
|
+
px = 0 if px < 0
|
39
|
+
py = 0 if py < 0
|
40
|
+
|
41
|
+
w = body.scrollWidth - px if px + w > body.scrollWidth
|
42
|
+
h = body.scrollHeight - py if py + h > body.scrollHeight
|
43
|
+
|
44
|
+
# Scrolls the page so that top of the object is visible at the top of the window.
|
45
|
+
body.scrollTop = py - 2
|
46
|
+
body.scrollLeft = px - 2
|
47
|
+
|
48
|
+
# The position on the screen is different due to page scrolling and Body border
|
49
|
+
sx = px - body.scrollLeft + body.clientLeft
|
50
|
+
sy = py - body.scrollTop + body.clientTop
|
51
|
+
|
52
|
+
if sx + w < body.clientWidth && sy + h < body.clientHeight
|
53
|
+
# If the whole object is visible
|
54
|
+
capture_hwnd_area(hwnd, sx, sy, w, h)
|
55
|
+
else
|
56
|
+
# If only part of it is visible
|
57
|
+
capture_and_scroll(hwnd, px, py, w, h)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def capture_and_scroll(hwnd, px, py, w, h)
|
62
|
+
# Captured area
|
63
|
+
result = BitMap.new(0, 0)
|
64
|
+
|
65
|
+
# We will do the screen capturing in more steps by areas of maximum dimensions maxw x maxh
|
66
|
+
maxw = body.clientWidth;
|
67
|
+
maxh = body.clientHeight;
|
68
|
+
|
69
|
+
cw = 0
|
70
|
+
ch = 0
|
71
|
+
cnt_x = 0
|
72
|
+
while cw < w
|
73
|
+
# Scroll to the top and right
|
74
|
+
body.scrollTop = px - 2;
|
75
|
+
body.scrollLeft = px - 2 + cnt_x * (maxw * 0.9).to_i
|
76
|
+
|
77
|
+
ch = 0;
|
78
|
+
cnt_y = 0
|
79
|
+
strip = BitMap.new(0, 0)
|
80
|
+
while ch < h
|
81
|
+
body.scrollTop = px - 2 + cnt_y * (maxh * 0.9).to_i
|
82
|
+
|
83
|
+
# Recalculate the position on the screen
|
84
|
+
sx = px - body.scrollLeft + body.clientLeft + cw
|
85
|
+
sy = py - body.scrollTop + body.clientTop + ch
|
86
|
+
|
87
|
+
# Calculate the dimensions of the part to be captured
|
88
|
+
pw = (px + cw - body.scrollLeft + maxw) > maxw ? maxw - (px + cw) + body.scrollLeft : maxw
|
89
|
+
pw = cw + pw > w ? w - cw : pw
|
90
|
+
|
91
|
+
ph = (py + ch - body.scrollTop + maxh) > maxh ? maxh - (py + ch) + body.scrollTop : maxh
|
92
|
+
ph = ch + ph > h ? h - ch : ph
|
93
|
+
|
94
|
+
# Capture the part and append it to the strip
|
95
|
+
strip << capture_hwnd_area(hwnd, sx, sy, pw, ph)
|
96
|
+
ch += ph
|
97
|
+
cnt_y += 1
|
98
|
+
end
|
99
|
+
|
100
|
+
result.concat_right!(strip)
|
101
|
+
cw += pw
|
102
|
+
cnt_x += 1
|
103
|
+
end
|
104
|
+
|
105
|
+
result
|
106
|
+
end
|
107
|
+
|
108
|
+
def capture_hwnd(hwnd)
|
109
|
+
left, top, right, bottom = get_window_rect(hwnd)
|
110
|
+
capture_hwnd_area(hwnd, 0, 0, right - left, bottom - top)
|
111
|
+
end
|
112
|
+
|
113
|
+
def capture_hwnd_area(hwnd, x, y, w, h)
|
114
|
+
with_window_dc(hwnd) do |hdc|
|
115
|
+
with_delete_dc(CreateCompatibleDC(hdc)) do |memdc|
|
116
|
+
with_delete_object(CreateCompatibleBitmap(hdc, w, h)) do |hbmp|
|
117
|
+
SelectObject(memdc, hbmp)
|
118
|
+
BitBlt(memdc, 0, 0, w, h, hdc, x, y, SRCCOPY)
|
119
|
+
|
120
|
+
bmp = BitMap.new(w, h)
|
121
|
+
r = GetDIBits(memdc, hbmp, 0, h, bmp.data, bmp.info.pack, DIB_RGB_COLORS)
|
122
|
+
raise Win32APIError, "GetDIBits failed: #{r}" if r.nil? or r.zero?
|
123
|
+
|
124
|
+
bmp
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "timeout"
|
2
|
+
|
3
|
+
require "win32/capture_ie/base"
|
4
|
+
require "win32/capture_ie/ffi"
|
5
|
+
|
6
|
+
module Win32::CaptureIE
|
7
|
+
class Window
|
8
|
+
include Win32::CaptureIE::FFI::User32
|
9
|
+
|
10
|
+
attr_reader :hwnd
|
11
|
+
|
12
|
+
def initialize(hwnd)
|
13
|
+
@hwnd = hwnd
|
14
|
+
end
|
15
|
+
|
16
|
+
def bring_window_to_top(timeout=5, wait=0.5)
|
17
|
+
return if GetForegroundWindow() == hwnd
|
18
|
+
timeout(timeout) {
|
19
|
+
while GetForegroundWindow() != hwnd
|
20
|
+
CloseWindow(hwnd)
|
21
|
+
OpenIcon(hwnd)
|
22
|
+
BringWindowToTop(hwnd)
|
23
|
+
sleep(wait)
|
24
|
+
end
|
25
|
+
}
|
26
|
+
wait_for_redraw
|
27
|
+
end
|
28
|
+
|
29
|
+
def wait_for_redraw(dt=1)
|
30
|
+
sleep(dt)
|
31
|
+
end
|
32
|
+
|
33
|
+
def list_child_window(hwnd)
|
34
|
+
r = [hwnd]
|
35
|
+
each_child_window(hwnd) {|child|
|
36
|
+
r << list_child_window(child)
|
37
|
+
}
|
38
|
+
r
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_child_window_by_classname(window, classname)
|
42
|
+
w = list_child_window(window).flatten
|
43
|
+
w.find{|e| get_class_name(e) == classname }
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require "win32ole"
|
2
|
+
require "win32/capture_ie/browser"
|
3
|
+
require "win32/capture_ie/version"
|
4
|
+
|
5
|
+
module Win32 #:nodoc:
|
6
|
+
|
7
|
+
module CaptureIE
|
8
|
+
class <<self
|
9
|
+
|
10
|
+
class ConnectError < StandardError; end
|
11
|
+
|
12
|
+
# call-seq:
|
13
|
+
# start(url) -> Win32::CaptureIE::Browser
|
14
|
+
# start(url, :no_wait => true) -> Win32::CaptureIE::Browser
|
15
|
+
# start(url){|ie| ... }
|
16
|
+
# start(url, :no_wait => true){|ie| ... }
|
17
|
+
#
|
18
|
+
# lanuch IE and return/eval Win32::CaptureIE::Browser object.
|
19
|
+
def start(url="about:blank", opts=nil, &block)
|
20
|
+
opts ||= {}
|
21
|
+
ie = wrap(create_ie_object)
|
22
|
+
ie.browser.Visible = true
|
23
|
+
ie.navigate(url.to_s, !opts[:no_wait])
|
24
|
+
run(ie, opts, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
# call-seq:
|
28
|
+
# connect_or_start(url) -> Win32::CaptureIE::Browser
|
29
|
+
# connect_or_start(url, :no_wait => true) -> Win32::CaptureIE::Browser
|
30
|
+
# connect_or_start(url){|ie| ... }
|
31
|
+
# connect_or_start(url, :no_wait => true){|ie| ... }
|
32
|
+
#
|
33
|
+
# connect existing IE or start.
|
34
|
+
def connect_or_start(url="about:blank", opts=nil, &block)
|
35
|
+
attach(url, lambda { start(url, opts, &block) }, opts, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
# call-seq:
|
39
|
+
# connect(url) -> Win32::CaptureIE::Browser or Win32::CaptureIE::ConnectError
|
40
|
+
# connect(url){|ie| ... }
|
41
|
+
#
|
42
|
+
# connect existing IE that displayed specified +url+.
|
43
|
+
# And return/eval Win32::CaptureIE::Browser object.
|
44
|
+
def connect(url="about:blank", opts=nil, &block)
|
45
|
+
attach(url, lambda { raise ConnectError, "no such IE `#{url}'" }, opts, &block)
|
46
|
+
end
|
47
|
+
|
48
|
+
def attach(url, fallback, opts=nil, &block)
|
49
|
+
url = url.to_s
|
50
|
+
ie = list_ie.find{|e| e.LocationURL == url }
|
51
|
+
if ie
|
52
|
+
run(wrap(ie), opts, &block)
|
53
|
+
else
|
54
|
+
fallback.call
|
55
|
+
end
|
56
|
+
end
|
57
|
+
private :attach
|
58
|
+
|
59
|
+
def list_ie
|
60
|
+
shell = WIN32OLE.new("Shell.Application")
|
61
|
+
w = shell.Windows.extend(Enumerable)
|
62
|
+
w.select{|e| e.FullName =~ /\biexplore\.exe\z/i }
|
63
|
+
end
|
64
|
+
|
65
|
+
def run(ie, opts=nil, &block)
|
66
|
+
opts ||= {}
|
67
|
+
return ie unless block
|
68
|
+
begin
|
69
|
+
block.call(ie)
|
70
|
+
ensure
|
71
|
+
begin
|
72
|
+
ie.browser.Quit unless opts[:no_quit]
|
73
|
+
rescue WIN32OLERuntimeError => ignored
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
private :run
|
78
|
+
|
79
|
+
def wrap(ie)
|
80
|
+
Win32::CaptureIE::Browser.new(ie.HWND, nil, ie)
|
81
|
+
end
|
82
|
+
private :wrap
|
83
|
+
|
84
|
+
def create_ie_object
|
85
|
+
WIN32OLE.new("InternetExplorer.Application")
|
86
|
+
end
|
87
|
+
private :create_ie_object
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.join(File.dirname(__FILE__), '..')
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/destroy.cmd
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
@ruby script/destroy %*
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.join(File.dirname(__FILE__), '..')
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
data/script/generate.cmd
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
@ruby script/generate %*
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class Filter
|
2
|
+
|
3
|
+
def initialize
|
4
|
+
@filter = []
|
5
|
+
end
|
6
|
+
|
7
|
+
def define_replace(regexp, replace, key)
|
8
|
+
@filter << [regexp, lambda { replace }, key]
|
9
|
+
end
|
10
|
+
|
11
|
+
def define_insert_before(tag, snippet, key)
|
12
|
+
@filter << [tag, lambda { snippet + tag }, key]
|
13
|
+
end
|
14
|
+
|
15
|
+
def define_insert_after(tag, snippet, key)
|
16
|
+
@filter << [tag, lambda { tag + snippet }, key]
|
17
|
+
end
|
18
|
+
|
19
|
+
def update!(file)
|
20
|
+
b = File.read(file)
|
21
|
+
a = @filter.inject(b) {|bb,subs|
|
22
|
+
re, sub, key = *subs
|
23
|
+
if key and bb =~ /#{Regexp.quote(key)}/
|
24
|
+
bb
|
25
|
+
else
|
26
|
+
bb.gsub(re, &sub)
|
27
|
+
end
|
28
|
+
}
|
29
|
+
if b != a
|
30
|
+
puts file
|
31
|
+
File.open(file, "w") {|w| w.puts a }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
GOOGLE_WEBMASTER_TOOL_TAG = "4xi61YK06FtgbbYoHU2oPltUGvJZLrQogTtv+vaPYTI="
|
39
|
+
GOOGLE_ANALYTICS_ACCOUNT = "UA-1161245-8"
|
40
|
+
GOOGLE_ANALYTICS = <<GOOGLE
|
41
|
+
|
42
|
+
<!-- Google Analytics -->
|
43
|
+
<div id="google-analytics">
|
44
|
+
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
45
|
+
</script>
|
46
|
+
<script type="text/javascript">
|
47
|
+
_uacct = "#{GOOGLE_ANALYTICS_ACCOUNT}";
|
48
|
+
urchinTracker();
|
49
|
+
</script>
|
50
|
+
</div>
|
51
|
+
|
52
|
+
GOOGLE
|
53
|
+
|
54
|
+
f = Filter.new
|
55
|
+
f.define_replace(/\A\s+/m, "", nil)
|
56
|
+
f.define_replace(/\s*<!--.*?-->\s*<html/m, "<html", nil)
|
57
|
+
f.define_insert_before("</body>", GOOGLE_ANALYTICS, '<div id="google-analytics">')
|
58
|
+
f.define_replace("</frameset>\n</html>", <<NOFRAME, '<div id="google-analytics">')
|
59
|
+
</frameset>
|
60
|
+
|
61
|
+
<noframe>
|
62
|
+
<body>
|
63
|
+
#{GOOGLE_ANALYTICS}
|
64
|
+
</body>
|
65
|
+
</noframe>
|
66
|
+
|
67
|
+
</html>
|
68
|
+
NOFRAME
|
69
|
+
|
70
|
+
tag = %Q{\n<meta name="verify-v1" content="#{GOOGLE_WEBMASTER_TOOL_TAG}" />\n}
|
71
|
+
f.define_insert_after("<head>", tag, '<meta name="verify-v1"')
|
72
|
+
|
73
|
+
ARGV.each do |html|
|
74
|
+
f.update!(html)
|
75
|
+
end
|
data/script/txt2html
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
begin
|
5
|
+
require 'newgem'
|
6
|
+
rescue LoadError
|
7
|
+
puts "\n\nGenerating the website requires the newgem RubyGem"
|
8
|
+
puts "Install: gem install newgem\n\n"
|
9
|
+
exit(1)
|
10
|
+
end
|
11
|
+
require 'redcloth'
|
12
|
+
require 'syntax/convertors/html'
|
13
|
+
require 'erb'
|
14
|
+
require File.dirname(__FILE__) + '/../lib/win32-captureie/version.rb'
|
15
|
+
|
16
|
+
version = Win32-captureie::VERSION::STRING
|
17
|
+
download = 'http://rubyforge.org/projects/win32-captureie'
|
18
|
+
|
19
|
+
class Fixnum
|
20
|
+
def ordinal
|
21
|
+
# teens
|
22
|
+
return 'th' if (10..19).include?(self % 100)
|
23
|
+
# others
|
24
|
+
case self % 10
|
25
|
+
when 1: return 'st'
|
26
|
+
when 2: return 'nd'
|
27
|
+
when 3: return 'rd'
|
28
|
+
else return 'th'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Time
|
34
|
+
def pretty
|
35
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def convert_syntax(syntax, source)
|
40
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
41
|
+
end
|
42
|
+
|
43
|
+
if ARGV.length >= 1
|
44
|
+
src, template = ARGV
|
45
|
+
template ||= File.join(File.dirname(__FILE__), '/../website/template.rhtml')
|
46
|
+
|
47
|
+
else
|
48
|
+
puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
|
49
|
+
exit!
|
50
|
+
end
|
51
|
+
|
52
|
+
template = ERB.new(File.open(template).read)
|
53
|
+
|
54
|
+
title = nil
|
55
|
+
body = nil
|
56
|
+
File.open(src) do |fsrc|
|
57
|
+
title_text = fsrc.readline
|
58
|
+
body_text = fsrc.read
|
59
|
+
syntax_items = []
|
60
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
61
|
+
ident = syntax_items.length
|
62
|
+
element, syntax, source = $1, $2, $3
|
63
|
+
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
64
|
+
"syntax-temp-#{ident}"
|
65
|
+
}
|
66
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
67
|
+
body = RedCloth.new(body_text).to_html
|
68
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
69
|
+
end
|
70
|
+
stat = File.stat(src)
|
71
|
+
created = stat.ctime
|
72
|
+
modified = stat.mtime
|
73
|
+
|
74
|
+
$stdout << template.result(binding)
|
data/script/txt2html.cmd
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
@ruby script/txt2html %*
|