psd2html 0.0.4

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c285961d492dab7ec2462fa504d338c7cfd93801
4
+ data.tar.gz: e9dbd07796a7688e57c79c3965a9e5e2ad016e7e
5
+ SHA512:
6
+ metadata.gz: 3d05e194a7dad02fcd2c6a529b5b29de98f4e0c03e3c7a2f750886ffaa3560d342f9a3c6e734e6dd7efb67ee0157c02eeb7cdbed69f08e0a73968bd12429f2c1
7
+ data.tar.gz: 22dbd20f07b74e0628e10f1c696745bd9143a49d0b1317413bd9206a13ea7b7903b855b2582d6c0b0ee909574a9285e56e9b799e6d6d9891deb1f7069d698123
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ require 'psd2html'
3
+ psdPath = ARGV[0]
4
+ dstHtmlPath = ARGV[1]
5
+ psd = Psd2Html.new(psdPath)
6
+ unless dstHtmlPath
7
+ puts psd.render()
8
+ else
9
+ fh = File.new(dstHtmlPath, "w") #创建一个可写文件流
10
+ fh.puts psd.render()
11
+ fh.close
12
+ end
@@ -0,0 +1,80 @@
1
+ require 'psd'
2
+ require_relative 'psd2html/until.rb'
3
+ require_relative 'psd2html/convertor.rb'
4
+ Dir.glob( File.expand_path( "psd2html/psconvertor/*.rb", File.dirname(__FILE__) ) ) do |convertor|
5
+ require convertor
6
+ end
7
+ Until.log("start generate psd tree....")
8
+ class Psd2Html
9
+ CONVERTING_MAP = {
10
+ "text" => ::Psd2html::PsConvertor::Text,
11
+ "text-link" => ::Psd2html::PsConvertor::TextLink,
12
+ "block" => ::Psd2html::PsConvertor::Block,
13
+ "block-link" => ::Psd2html::PsConvertor::BlockLink,
14
+ "img" => ::Psd2html::PsConvertor::Img,
15
+ "img-link" => ::Psd2html::PsConvertor::ImgLink,
16
+ "img-bg" => ::Psd2html::PsConvertor::ImgBackground,
17
+ "root" => ::Psd2html::PsConvertor::Root
18
+ }
19
+ def initialize(psdPath)
20
+ psd = PSD.new(psdPath)
21
+ psd.parse!
22
+ blockRoot = psd.tree
23
+ rootConvertor = get_convertor(blockRoot,1)
24
+ @treeRoot = format_tree(rootConvertor)
25
+ puts "start generate psd tree...."
26
+ end
27
+
28
+ def render_css
29
+ Until.log("start render css....")
30
+ return @treeRoot.render_css
31
+ end
32
+ def render_html
33
+ Until.log("start render html....")
34
+ return @treeRoot.render_html
35
+ end
36
+
37
+ def render
38
+ return <<-STR
39
+ <meta charset="utf-8" />
40
+ <style type="text/css">
41
+ #{@treeRoot.render_css}
42
+ </style>
43
+ #{@treeRoot.render_html}
44
+ STR
45
+
46
+ end
47
+
48
+ protected
49
+ def get_convertor(node,index)
50
+
51
+ return CONVERTING_MAP["root"].new(node,index) if node.root?
52
+
53
+ return unless node.name.include?("|")
54
+
55
+ convertorName = node.name.split('|').last.to_s
56
+ unless CONVERTING_MAP.include?(convertorName)
57
+ return
58
+ end
59
+ CONVERTING_MAP[convertorName].new(node,index)
60
+ end
61
+ def format_tree(convertor)
62
+ if convertor.psNode.has_children?
63
+ convertor.psNode.children.each_with_index do |node,index|
64
+ childConvertor = get_convertor(node,index)
65
+ if childConvertor
66
+ childConvertor.parentConvertor = convertor
67
+ convertor.childrenConvertors << format_tree(childConvertor)
68
+ end
69
+ end
70
+ end
71
+ convertor
72
+ end
73
+
74
+ end
75
+
76
+
77
+
78
+
79
+
80
+
@@ -0,0 +1,120 @@
1
+ require "mustache"
2
+ require 'digest/md5'
3
+ require_relative '../until.rb'
4
+ module Psd2html
5
+ class Convertor
6
+ attr_accessor :psNode, :index, :childrenConvertors,:parentConvertor
7
+
8
+ CSS_TPL = "\.{{classname}}\{ \n{{#styles}} {{key}}:{{value}};\n{{/styles}} \}"
9
+ CSS_HASH_BASE = {
10
+ "classname" => 'root-container',
11
+ "styles" => {
12
+ "position" => "relative"
13
+ }
14
+ }
15
+ @@css_dictory = {
16
+
17
+ }
18
+
19
+ HTML_TPL = "<{{tag}} {{#attributes}} {{key}}=\"{{value}}\" {{/attributes}}>{{{content}}}</{{tag}}>"
20
+ HTML_HASH_BASE = {
21
+ "attributes" => {
22
+ "class" => "root-container"
23
+ },
24
+ "tag" => "div",
25
+ "content" => ""
26
+ }
27
+ def initialize(psNode,index)
28
+ @psNode = psNode
29
+ @index = index
30
+ @parentConvertor = nil
31
+ @childrenConvertors = []
32
+ end
33
+ def guid
34
+ className = @psNode.name.split("|")[-2]
35
+ guidStr = className+@index.to_s
36
+ if /\p{Han}+/u.match(className)
37
+ Digest::MD5.hexdigest(guidStr)
38
+ else
39
+ guidStr
40
+ end
41
+
42
+ end
43
+ #需要被重写,用于生成css的对象hash
44
+ def css_skeleton
45
+ CSS_HASH_BASE
46
+ end
47
+ #需要被重写,用于生成html的模板渲染对象
48
+ def html_skeleton
49
+ HTML_HASH_BASE
50
+ end
51
+ def get_css_tpl
52
+ CSS_TPL
53
+ end
54
+ def get_html_tpl
55
+ HTML_TPL
56
+ end
57
+ #为了处理css的同名问题,需要使用一个hash来去重
58
+ def css_map
59
+ return unless css_skeleton
60
+ data = css_skeleton.clone
61
+ data["styles"] = hash_to_array(data["styles"])
62
+ data["convertnode"] = self
63
+ @@css_dictory[data["classname"]] = data
64
+ @childrenConvertors.each do |node|
65
+ node.css_map
66
+ end
67
+ end
68
+ def render_css
69
+ Until.log("start generate css of #{@psNode.name}...")
70
+ css_map()
71
+ cssStr = ""
72
+ @@css_dictory.values.each do |cssData|
73
+ cssStr += "\n" + Mustache.render(cssData['convertnode'].get_css_tpl,cssData)
74
+ end
75
+ @@css_dictory = {}
76
+ cssStr = sync_css(cssStr)
77
+ Until.log("done generate css of #{@psNode.name}...")
78
+ end
79
+
80
+ def render_html
81
+ Until.log("start generate html of #{@psNode.name}...")
82
+ return "" unless html_skeleton
83
+ data = html_skeleton.clone
84
+ data["attributes"] = hash_to_array(data["attributes"])
85
+
86
+ @childrenConvertors.each do |node|
87
+ data["content"] += node.render_html
88
+ end
89
+
90
+ htmlStr = Mustache.render(get_html_tpl,data)
91
+ htmlStr = sync_html(htmlStr)
92
+ Until.log("done generate html of #{@psNode.name}...")
93
+ end
94
+ def sync_css(cssstr)
95
+ cssstr
96
+ end
97
+ def sync_html(htmlstr)
98
+ htmlstr
99
+ end
100
+ protected
101
+ def hash_to_array(originHash)
102
+ dstArray = []
103
+ originHash.each do |key,value|
104
+ dstArray << {"key"=>key,"value"=>value}
105
+ end
106
+ dstArray
107
+ end
108
+ def css_hook(style)
109
+ hookHash = {
110
+ "pt" => "px",
111
+ "MicrosoftYaHei" => "microsoft yahei"
112
+ }
113
+ hookHash.each do |key,value|
114
+ style = style.gsub(key,value)
115
+ end
116
+ style
117
+ end
118
+ end
119
+
120
+ end
@@ -0,0 +1,36 @@
1
+ module Psd2html
2
+ module PsConvertor
3
+ class Block < ::Psd2html::Convertor
4
+
5
+ def css_skeleton
6
+ cssRenderData = {
7
+ "classname" => "block-#{guid}",
8
+ "styles" => {
9
+ "position"=> "absolute",
10
+ "display" => "inline-block",
11
+ "width" => "#{@psNode.width}px",
12
+ "height" => "#{@psNode.height}px",
13
+ "left" => "#{@psNode.left-@parentConvertor.psNode.left}px",
14
+ "top" => "#{@psNode.top-@parentConvertor.psNode.top}px",
15
+ "z-index" => "#{@psNode.depth}#{@parentConvertor.childrenConvertors.length - @index.to_i}"
16
+ }
17
+ }
18
+ cssRenderData = CSS_HASH_BASE.merge(cssRenderData)
19
+ end
20
+ def get_html_tpl
21
+ "<{{tag}} {{#attributes}} {{key}}=\"{{value}}\" {{/attributes}}><div style=\"position:relative;\">{{{content}}}</div></{{tag}}>"
22
+ end
23
+ def html_skeleton
24
+ htmlRenderData = {
25
+ "attributes" => {
26
+ "class" => "block-#{guid}"
27
+ },
28
+ "tag" => "div"
29
+ }
30
+ htmlRenderData = HTML_HASH_BASE.merge(htmlRenderData)
31
+ end
32
+
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,21 @@
1
+ module Psd2html
2
+ module PsConvertor
3
+ class BlockLink < ::Psd2html::PsConvertor::Block
4
+ def guid
5
+ "link-" + super
6
+ end
7
+ def html_skeleton
8
+ htmlRenderData = {
9
+ "attributes" => {
10
+ "class" => "block-#{guid}",
11
+ "href" => "#"
12
+ },
13
+ "tag" => "a",
14
+ }
15
+ htmlRenderData = HTML_HASH_BASE.merge(htmlRenderData)
16
+ end
17
+
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,37 @@
1
+ module Psd2html
2
+ module PsConvertor
3
+ class Img < ::Psd2html::Convertor
4
+ def css_skeleton
5
+ cssRenderData = {
6
+ "classname" => "img-#{guid}",
7
+ "styles" => {
8
+ "position" => "absolute",
9
+ "display" => "inline-block",
10
+ "width" => "#{@psNode.width}px",
11
+ "height" => "#{@psNode.height}px",
12
+ "left" => "#{@psNode.left-@parentConvertor.psNode.left}px",
13
+ "top" => "#{@psNode.top-@parentConvertor.psNode.top}px",
14
+ "z-index" => "#{@psNode.depth}#{@parentConvertor.childrenConvertors.length - @index.to_i}"
15
+ }
16
+ }
17
+ cssRenderData = CSS_HASH_BASE.merge(cssRenderData)
18
+ end
19
+ def get_html_tpl
20
+ "<{{tag}} {{#attributes}} {{key}}=\"{{value}}\" {{/attributes}} />"
21
+ end
22
+ def html_skeleton
23
+ imgUrl = "./img-source-#{guid}-#{Time.now.to_i}.png"
24
+ @psNode.image.save_as_png(imgUrl)
25
+ htmlRenderData = {
26
+ "attributes" => {
27
+ "class" => "img-#{guid}",
28
+ "src" => imgUrl
29
+ },
30
+ "tag" => "img"
31
+ }
32
+ htmlRenderData = HTML_HASH_BASE.merge(htmlRenderData)
33
+ end
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,23 @@
1
+ module Psd2html
2
+ module PsConvertor
3
+ class ImgBackground < ::Psd2html::Convertor
4
+ #对父转换对象进行了css注入
5
+ def css_map
6
+ imgUrl = "./img-source-#{guid}-#{Time.now.to_i}.png"
7
+ @psNode.image.save_as_png(imgUrl)
8
+ parentConvertorClassName = @parentConvertor.css_skeleton()["classname"]
9
+ if @@css_dictory.has_key?(parentConvertorClassName)
10
+ @@css_dictory[parentConvertorClassName]['styles'] << {"key" => "background","value" => "url(#{imgUrl}) center center"}
11
+ end
12
+ end
13
+ def html_skeleton
14
+ return nil
15
+ end
16
+ def get_html_tpl
17
+ return ""
18
+ end
19
+
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,38 @@
1
+ module Psd2html
2
+ module PsConvertor
3
+ class ImgLink < ::Psd2html::Convertor
4
+ def guid
5
+ "link-" + super
6
+ end
7
+ def css_skeleton
8
+ cssRenderData = {
9
+ "classname" => "img-#{guid}",
10
+ "styles" => {
11
+ "position" => "absolute",
12
+ "display" => "inline-block",
13
+ "width" => "#{@psNode.width}px",
14
+ "height" => "#{@psNode.height}px",
15
+ "left" => "#{@psNode.left-@parentConvertor.psNode.left}px",
16
+ "top" => "#{@psNode.top-@parentConvertor.psNode.top}px",
17
+ "z-index" => "#{@psNode.depth}#{@parentConvertor.childrenConvertors.length - @index.to_i}"
18
+ }
19
+ }
20
+ cssRenderData = CSS_HASH_BASE.merge(cssRenderData)
21
+ end
22
+ def html_skeleton
23
+ imgUrl = "./img-source-#{guid}-#{Time.now.to_i}.png"
24
+ @psNode.image.save_as_png(imgUrl)
25
+ htmlRenderData = {
26
+ "attributes" => {
27
+ "class" => "img-#{guid}",
28
+ "href" => "#"
29
+ },
30
+ "content" => "<img src=\"#{imgUrl}\" />",
31
+ "tag" => "a"
32
+ }
33
+ htmlRenderData = HTML_HASH_BASE.merge(htmlRenderData)
34
+ end
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,10 @@
1
+ require "mustache"
2
+
3
+ module Psd2html
4
+ module PsConvertor
5
+ class Root < ::Psd2html::Convertor
6
+
7
+ end
8
+ end
9
+
10
+ end
@@ -0,0 +1,37 @@
1
+ module Psd2html
2
+ module PsConvertor
3
+ class Text < ::Psd2html::Convertor
4
+ def css_skeleton
5
+ cssRenderData = {
6
+ "classname" => "text-#{guid}",
7
+ "styles" => {
8
+ "position" => "absolute",
9
+ "display" => "inline-block",
10
+ "width" => "#{@psNode.width+2}px",
11
+ "height" => "#{@psNode.height+2}px",
12
+ "left" => "#{@psNode.left-@parentConvertor.psNode.left}px",
13
+ "top" => "#{@psNode.top-@parentConvertor.psNode.top}px",
14
+ "z-index" => "#{@psNode.depth}#{@parentConvertor.childrenConvertors.length - @index.to_i}"
15
+ }
16
+ }
17
+ @psNode.text[:font][:css].split(";").each do |styleString|
18
+ styleKey = styleString.split(":")[0]
19
+ styleValue = styleString.split(":")[1]
20
+ cssRenderData["styles"][styleKey] = css_hook(styleValue)
21
+ end
22
+ cssRenderData = CSS_HASH_BASE.merge(cssRenderData)
23
+ end
24
+ def html_skeleton
25
+ htmlRenderData = {
26
+ "attributes" => {
27
+ "class" => "text-#{guid}",
28
+ },
29
+ "tag" => "span",
30
+ "content" => @psNode.text[:value]
31
+ }
32
+ htmlRenderData = HTML_HASH_BASE.merge(htmlRenderData)
33
+ end
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,22 @@
1
+ module Psd2html
2
+ module PsConvertor
3
+ class TextLink < ::Psd2html::PsConvertor::Text
4
+ def guid
5
+ "link-" + super
6
+ end
7
+
8
+ def html_skeleton
9
+ htmlRenderData = {
10
+ "attributes" => {
11
+ "class" => "text-#{guid}",
12
+ "href" => "#"
13
+ },
14
+ "tag" => "a",
15
+ "content" => @psNode.text[:value]
16
+ }
17
+ htmlRenderData = HTML_HASH_BASE.merge(htmlRenderData)
18
+ end
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,3 @@
1
+ module Psd2html
2
+ VERSION = "0.0.4"
3
+ end
@@ -0,0 +1,31 @@
1
+ class Until
2
+
3
+ def self.log(info)
4
+ STDOUT.puts "log:" + green(info)
5
+ end
6
+
7
+ def self.error(info)
8
+ STDOUT.puts "error:" + red(info)
9
+ end
10
+
11
+ protected
12
+ def self.colorize(color_code,str)
13
+ "\e[#{color_code}m#{str}\e[0m"
14
+ end
15
+
16
+ def self.red(str)
17
+ colorize(31,str)
18
+ end
19
+
20
+ def self.green(str)
21
+ colorize(32,str)
22
+ end
23
+
24
+ def self.yellow(str)
25
+ colorize(33,str)
26
+ end
27
+
28
+ def self.pink(str)
29
+ colorize(35)
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: psd2html
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - cherishpeace
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mustache
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: psd
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: |-
70
+ psd2html是一个可以通过特定ps约定来自动生成html的ruby命令行程序。
71
+ psd2html会自动解析你的psd文件生成相应的html代码包括css。生成的代码都是使用绝对定位实现的,因此psd2html适合的场景为对性能,html语义都不是要求很高的场景,比如只有几天寿命的活动页面。
72
+
73
+ 应该说完美的psd2html的解决方案几乎是不存在的。经过一些调研,最终确定了使用一种约定生成的方式。
74
+ email:
75
+ - xhzhuweikang@163.com
76
+ executables:
77
+ - psd2html
78
+ extensions: []
79
+ extra_rdoc_files: []
80
+ files:
81
+ - bin/psd2html
82
+ - lib/psd2html.rb
83
+ - lib/psd2html/convertor.rb
84
+ - lib/psd2html/psconvertor/block.rb
85
+ - lib/psd2html/psconvertor/blockLink.rb
86
+ - lib/psd2html/psconvertor/img.rb
87
+ - lib/psd2html/psconvertor/imgBackground.rb
88
+ - lib/psd2html/psconvertor/imgLink.rb
89
+ - lib/psd2html/psconvertor/root.rb
90
+ - lib/psd2html/psconvertor/text.rb
91
+ - lib/psd2html/psconvertor/textLink.rb
92
+ - lib/psd2html/version.rb
93
+ - lib/until.rb
94
+ homepage: ''
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ - bin
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 2.2.2
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: psd2html是一个可以通过特定ps约定来自动生成html的ruby程序。支持命令行和程序内部引用。
119
+ test_files: []