win32-captureie 0.1.0
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.
- 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 %*
|