zine_brewer 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/zine_brewer +13 -0
- data/lib/zine_brewer.rb +2 -0
- data/lib/zine_brewer/kramdown/converter/sehtml.rb +152 -0
- data/lib/zine_brewer/kramdown/parser/sekd.rb +161 -0
- data/lib/zine_brewer/main.rb +128 -0
- data/lib/zine_brewer/templates/bookranking.rb +35 -0
- data/lib/zine_brewer/templates/casts.rb +104 -0
- data/lib/zine_brewer/templates/fig/module_fig_base.rb +68 -0
- data/lib/zine_brewer/templates/fig/module_fig_plus.rb +15 -0
- data/lib/zine_brewer/templates/fig_a.rb +26 -0
- data/lib/zine_brewer/templates/fig_h.rb +27 -0
- data/lib/zine_brewer/templates/fig_n.rb +27 -0
- data/lib/zine_brewer/templates/fig_p.rb +31 -0
- data/lib/zine_brewer/templates/fig_z.rb +26 -0
- data/lib/zine_brewer/version.rb +3 -0
- data/zine_brewer.gemspec +28 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6e2d08e05252737a218c8293c1b3f0961e6e5ccc686b7618c7d1f003a5ee344b
|
4
|
+
data.tar.gz: 74c096aa7daaea76924e5f5ca526d14903b2b4b452e7a4de145dbcd5048caf42
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cf2f41012a5fbdbbeffe777fa8b46031536469cb10dab13c50c52491bfe76bdd1e042f7fac7ad4418c53320e1c35bfa30c40cf49b61854298b31a973453243ec
|
7
|
+
data.tar.gz: 74c92ca207131f8b1742d06effa4597b98d3fc9fd1bcaa38f549bb85f1ec9d7c4b2b4c7ce75d8ac13f125c45a6bd1e6d10ddcae8355d05c638100e0b43da8a1e
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at akinori.ichigo@gmail.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [https://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: https://contributor-covenant.org
|
74
|
+
[version]: https://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 Akinori Ichigo
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# ZineBrewer
|
2
|
+
|
3
|
+
ZineBrewer converts Kramdown (=exhanced Markdown) document to HTML for Shoeisha Web Media.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'zine_brewer'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install zine_brewer
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
$ zine_brewer *kramdown document*
|
24
|
+
|
25
|
+
## License
|
26
|
+
|
27
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
28
|
+
|
29
|
+
## Code of Conduct
|
30
|
+
|
31
|
+
Everyone interacting in the ZineBrewer project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/akinori-ichigo/zine_brewer/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "zine_brewer"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/exe/zine_brewer
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "zine_brewer"
|
4
|
+
|
5
|
+
begin
|
6
|
+
zine = ZineBrewer::Application.new(ARGV[0])
|
7
|
+
zine.write_out
|
8
|
+
puts 'Conversion from Markdown to HTML is done. The output files (header.txt / body.txt) are in proof directory.'
|
9
|
+
rescue => e
|
10
|
+
puts 'Something wrong...'
|
11
|
+
p e
|
12
|
+
end
|
13
|
+
|
data/lib/zine_brewer.rb
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009-2015 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
# Copyright (C) 2016 Akinori Ichigo <ichigo@shoeisha.co.jp>
|
6
|
+
#
|
7
|
+
# This file is part of kramdown which is licensed under the MIT.
|
8
|
+
#++
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'kramdown'
|
12
|
+
require 'kramdown/parser'
|
13
|
+
require 'kramdown/converter'
|
14
|
+
require 'kramdown/utils'
|
15
|
+
|
16
|
+
module Kramdown
|
17
|
+
module Converter
|
18
|
+
class SeHtml < Html
|
19
|
+
|
20
|
+
def convert_img(el, indent)
|
21
|
+
if %r{^common} =~ File.dirname(el.attr['src'])
|
22
|
+
el.attr['src'] = "/static/images/article/common/#{File.basename(el.attr['src'])}"
|
23
|
+
end
|
24
|
+
"<img#{html_attributes(el.attr)} />"
|
25
|
+
end
|
26
|
+
|
27
|
+
def convert_codeblock(el, indent)
|
28
|
+
raw_caption = el.attr.delete('caption')
|
29
|
+
caption = if raw_caption.nil?
|
30
|
+
''
|
31
|
+
else
|
32
|
+
el_caption = Document.new(raw_caption, {:auto_ids => false, :input => 'sekd'}).root.children[0]
|
33
|
+
format_as_block_html('div', {'class' => 'caption'}, inner(el_caption, indent), indent + 2)
|
34
|
+
end
|
35
|
+
|
36
|
+
result = escape_html(el.value)
|
37
|
+
result.chomp!
|
38
|
+
if el.attr['class'].to_s =~ /\bshow-whitespaces\b/
|
39
|
+
result.gsub!(/(?:(^[ \t]+)|([ \t]+$)|([ \t]+))/) do |m|
|
40
|
+
suffix = ($1 ? '-l' : ($2 ? '-r' : ''))
|
41
|
+
m.scan(/./).map do |c|
|
42
|
+
case c
|
43
|
+
when "\t" then "<span class=\"ws-tab#{suffix}\">\t</span>"
|
44
|
+
when " " then "<span class=\"ws-space#{suffix}\">⋅</span>"
|
45
|
+
end
|
46
|
+
end.join('')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
format_as_indented_block_html('div', {'class' => 'src_frame'},
|
51
|
+
caption + ' ' + format_as_indented_block_html('pre', {'class' => el.attr['class']}, result, indent),
|
52
|
+
indent)
|
53
|
+
end
|
54
|
+
|
55
|
+
def convert_column(el, indent)
|
56
|
+
format_as_indented_block_html('section', el.attr, inner(el, indent), indent)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Makes caption element from caption attr of table element.
|
60
|
+
def table_caption(raw_caption)
|
61
|
+
el_caption = Document.new(raw_caption, {:auto_ids => false, :input => 'sekd'}).root.children[0]
|
62
|
+
format_as_block_html('caption', {}, inner(el_caption, indent), indent)
|
63
|
+
end
|
64
|
+
|
65
|
+
def convert_table(el, indent)
|
66
|
+
raw_caption = el.attr.delete('caption')
|
67
|
+
table = super(el, indent)
|
68
|
+
if !raw_caption.nil?
|
69
|
+
table.sub!(/\A(<table.*?>)/, "\\1\n#{table_caption(raw_caption)}\n")
|
70
|
+
end
|
71
|
+
table.gsub(/^\s*<\/?t(head|body|foot)>\n/, '')
|
72
|
+
.gsub(/ style="text-align: left"/, '')
|
73
|
+
.gsub(/ style="text-align: center"/, ' class="txtC"')
|
74
|
+
.gsub(/ style="text-align: right"/, ' class="txtR"')
|
75
|
+
end
|
76
|
+
|
77
|
+
def convert_definition_table(el, indent)
|
78
|
+
raw_caption = el.attr.delete('caption')
|
79
|
+
rows = raw_caption.nil? ? '' : table_caption(raw_caption)
|
80
|
+
inner(el.children.first, indent).scan(/(<dt>.+?<\/dt>|<dd>.+?<\/dd>)/m).
|
81
|
+
map{|x| x.first.sub(/\A<dt>(.+)<\/dt>\z/m, "<th>\\1</th>")}.
|
82
|
+
map{|x| x.sub(/\A<dd>(.+)<\/dd>\z/m, "<td>\\1</td>")}.
|
83
|
+
each_slice(2) do |x|
|
84
|
+
row = x.map{|c| (' '*(indent + 2)) + c}.join("\n")
|
85
|
+
rows += format_as_indented_block_html('tr', {}, "#{row}\n", indent + 2)
|
86
|
+
end
|
87
|
+
format_as_indented_block_html('table', el.attr, rows, indent)
|
88
|
+
end
|
89
|
+
|
90
|
+
def convert_div(el, indent)
|
91
|
+
format_as_indented_block_html('div', el.attr, inner(el, indent), indent)
|
92
|
+
end
|
93
|
+
|
94
|
+
def convert_page(el, indent)
|
95
|
+
el.value + "\n"
|
96
|
+
end
|
97
|
+
|
98
|
+
def convert_footnote_marker_sekd(el, indent)
|
99
|
+
%!<sup id="fnref:#{el.value}"><a href="#fn:#{el.value}">[#{el.value}]</a></sup>!
|
100
|
+
end
|
101
|
+
|
102
|
+
def convert_footnote_definition_sekd(el, indent)
|
103
|
+
format_as_block_html('section', el.attr, "\n <h4>注</h4>\n" + inner(el, indent), indent)
|
104
|
+
end
|
105
|
+
|
106
|
+
def convert_a(el, indent)
|
107
|
+
res = inner(el, indent)
|
108
|
+
attr = el.attr.dup
|
109
|
+
if attr['href'].start_with?('mailto:')
|
110
|
+
mail_addr = attr['href'][7..-1]
|
111
|
+
attr['href'] = obfuscate('mailto') << ":" << obfuscate(mail_addr)
|
112
|
+
res = obfuscate(res) if res == mail_addr
|
113
|
+
else
|
114
|
+
attr['target'] = '_blank' unless attr['href'].start_with?('#')
|
115
|
+
end
|
116
|
+
format_as_span_html(el.type, attr, res)
|
117
|
+
end
|
118
|
+
|
119
|
+
def convert_span(el, indent)
|
120
|
+
format_as_span_html('span', el.attr, inner(el, indent))
|
121
|
+
end
|
122
|
+
|
123
|
+
def convert_em(el, indent)
|
124
|
+
format_as_span_html('strong', el.attr, inner(el, indent))
|
125
|
+
end
|
126
|
+
|
127
|
+
def convert_math(el, indent)
|
128
|
+
if (result = format_math(el, :indent => indent))
|
129
|
+
result
|
130
|
+
elsif el.options[:category] == :block
|
131
|
+
format_as_block_html('pre', el.attr, "$$\n#{el.value}\n$$", indent)
|
132
|
+
else
|
133
|
+
format_as_span_html('math', el.attr, "$#{el.value}$")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def convert_root(el, indent)
|
138
|
+
result = inner(el, indent)
|
139
|
+
if @toc_code
|
140
|
+
toc_tree = generate_toc_tree(@toc, @toc_code[0], @toc_code[1] || {})
|
141
|
+
text = if toc_tree.children.size > 0
|
142
|
+
convert(toc_tree, 0)
|
143
|
+
else
|
144
|
+
''
|
145
|
+
end
|
146
|
+
result.sub!(/#{@toc_code.last}/, text.gsub(/\\/, "\\\\\\\\"))
|
147
|
+
end
|
148
|
+
result
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2017 Akinori Ichigo <akinori.ichigo@gmail.com>
|
4
|
+
#
|
5
|
+
# This source code has written to extend and modify kramdown for
|
6
|
+
# web media published by SHOEISHA Co., Ltd.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'kramdown'
|
10
|
+
require 'kramdown/parser'
|
11
|
+
|
12
|
+
module Kramdown
|
13
|
+
module Parser
|
14
|
+
class Sekd < Kramdown
|
15
|
+
|
16
|
+
def initialize(source, options)
|
17
|
+
super
|
18
|
+
|
19
|
+
parsers_replacing = {
|
20
|
+
:@block_parsers => {:codeblock_fenced => :codeblock_fenced_sekd,
|
21
|
+
:footnote_definition => :footnote_definition_sekd},
|
22
|
+
:@span_parsers => {:footnote_marker => :footnote_marker_sekd}
|
23
|
+
}
|
24
|
+
parsers_replacing.each do |target, definitions|
|
25
|
+
target_instance = instance_variable_get(target)
|
26
|
+
definitions.each do |current, replacement|
|
27
|
+
target_instance[target_instance.index(current)] = replacement
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
@block_parsers.insert(5, :column, :definition_table, :page)
|
32
|
+
@span_parsers.insert(5, :span)
|
33
|
+
|
34
|
+
@page = 0
|
35
|
+
@fn_counter = 0
|
36
|
+
@fn_number = Hash.new{|h, k| h[k] = (@fn_counter += 1).to_s }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Parse the fenced codeblock at the current location
|
40
|
+
# code highlighting by Google Prettify.
|
41
|
+
def parse_codeblock_fenced_sekd
|
42
|
+
if @src.check(self.class::FENCED_CODEBLOCK_MATCH)
|
43
|
+
start_line_number = @src.current_line_number
|
44
|
+
@src.pos += @src.matched_size
|
45
|
+
el = new_block_el(:codeblock, @src[4].chomp, nil, :location => start_line_number)
|
46
|
+
lang, linenums = @src[3].to_s.strip.split(/:/)
|
47
|
+
lang_ext = LANG_BY_EXT[lang] || lang
|
48
|
+
el.attr['class'] = "prettyprint" + (lang_ext.nil? ? ' nocode' : " lang-#{lang_ext}")
|
49
|
+
el.attr['class'] += " linenums:#{linenums}" unless linenums.nil?
|
50
|
+
@tree.children << el
|
51
|
+
true
|
52
|
+
else
|
53
|
+
false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
FENCED_CODEBLOCK_MATCH = /^(([~`]){3,})\s*?(\w[\d:\w-]*)?\s*?\n(.*?)^\1\2*\s*?\n/m
|
57
|
+
define_parser(:codeblock_fenced_sekd, /^[~`]{3,}/, nil, 'parse_codeblock_fenced_sekd')
|
58
|
+
|
59
|
+
LANG_BY_EXT = {
|
60
|
+
"bash"=>"bsh", "clojure"=>"clj", "csharp"=>"cs", "c#"=>"cs", "el"=>"lisp",
|
61
|
+
"erl"=>"erlang", "golang"=>"go", "haskell"=>"hs", "javascript"=>"js", "obj-c"=>"m",
|
62
|
+
"objective-c"=>"m", "objc"=>"m", "pas"=>"pascal", "python"=>"py", "rlang"=>"r",
|
63
|
+
"ruby"=>"rb", "sc"=>"scala", "visualbasic"=>"vb"
|
64
|
+
}.merge(Hash[*%w!
|
65
|
+
apollo basic bsh c cc cpp clj cs csh css cyc cv dart erlang go hs htm html java js
|
66
|
+
llvm m matlab ml mumps mxml lisp lua n pascal perl pl pm proto py r rb rd scala sh
|
67
|
+
sql tcl tex vb vhdl wiki xhtml xml xq xsl yaml yml
|
68
|
+
!.map{|i| [i, i]}.flatten])
|
69
|
+
|
70
|
+
def parse_column
|
71
|
+
if @src.check(self.class::COLUMN_MATCH)
|
72
|
+
start_line_number = @src.current_line_number
|
73
|
+
@src.pos += @src.matched_size
|
74
|
+
el = Element.new(:column, nil, {'class' => 'columnSection'}, :location => start_line_number)
|
75
|
+
parse_blocks(el, @src[1])
|
76
|
+
update_attr_with_ial(el.attr, @block_ial) unless @block_ial.nil?
|
77
|
+
@tree.children << el
|
78
|
+
true
|
79
|
+
else
|
80
|
+
false
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
COLUMN_MATCH = /^={3,}\s*?column\s*?\n(.*?)^={2,}\/column\s*?\n/mi
|
85
|
+
define_parser(:column, /^={3,}co/i, nil, 'parse_column')
|
86
|
+
|
87
|
+
def parse_definition_table
|
88
|
+
if @src.check(self.class::DEFINITION_TABLE_MATCH)
|
89
|
+
start_line_number = @src.current_line_number
|
90
|
+
@src.pos += @src.matched_size
|
91
|
+
el = Element.new(:definition_table, nil, nil, :location => start_line_number)
|
92
|
+
parse_blocks(el, @src[1])
|
93
|
+
update_attr_with_ial(el.attr, @block_ial) unless @block_ial.nil?
|
94
|
+
@tree.children << el
|
95
|
+
true
|
96
|
+
else
|
97
|
+
false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
DEFINITION_TABLE_MATCH = /^={3,}\s*?dtable\s*?\n\n*(.*?)^={2,}\/dtable\s*?\n/mi
|
102
|
+
define_parser(:definition_table, /^={3,}dt/i, nil, 'parse_definition_table')
|
103
|
+
|
104
|
+
@page = 0
|
105
|
+
def parse_page
|
106
|
+
if @src.check(self.class::PAGE_MATCH)
|
107
|
+
start_line_number = @src.current_line_number
|
108
|
+
@src.pos += @src.matched_size
|
109
|
+
page = (@page > 0 ? "</div>\n<!-- page_delimiter -->\n" : '') + "<div id=\"p#{@page+=1}\">"
|
110
|
+
@tree.children << new_block_el(:page, page, nil, :location => start_line_number)
|
111
|
+
true
|
112
|
+
else
|
113
|
+
false
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
PAGE_MATCH = /^<%-*\s*page\s*-*>/
|
118
|
+
define_parser(:page, /^<%/, nil, 'parse_page')
|
119
|
+
|
120
|
+
def parse_footnote_definition_sekd
|
121
|
+
start_line_number = @src.current_line_number
|
122
|
+
@src.pos += @src.matched_size
|
123
|
+
if @fn_number.has_key?(@src[1])
|
124
|
+
warning("Duplicate footnote name '#{@src[1]}' on line #{start_line_number} - overwriting")
|
125
|
+
end
|
126
|
+
a = %!<a href="#fnref:#{@fn_number[@src[1]]}">[#{@fn_number[@src[1]]}]</a>: #{@src[2].strip}!
|
127
|
+
p = new_block_el(:p, nil, {'id' => "fn:#{@fn_number[@src[1]]}"})
|
128
|
+
p.children << new_block_el(:raw_text, a, nil)
|
129
|
+
if @tree.children.last.type == :footnote_definition_sekd
|
130
|
+
@tree.children.last.children << p
|
131
|
+
elsif [-1, -2].map{|i| @tree.children[i].type } == [:blank, :footnote_definition_sekd]
|
132
|
+
@tree.children.pop
|
133
|
+
@tree.children.last.children << p
|
134
|
+
else
|
135
|
+
f = new_block_el(:footnote_definition_sekd, nil, {'class' => 'columnSection footnotes'},
|
136
|
+
:location => start_line_number)
|
137
|
+
f.children << p
|
138
|
+
@tree.children << f
|
139
|
+
end
|
140
|
+
true
|
141
|
+
end
|
142
|
+
|
143
|
+
FOOTNOTE_DEFINITION_START = /^#{OPT_SPACE}\[\^(#{ALD_ID_NAME})\]:\s*?(.*?\n#{CODEBLOCK_MATCH})/
|
144
|
+
define_parser(:footnote_definition_sekd, FOOTNOTE_DEFINITION_START, /^#{OPT_SPACE}\[^/, 'parse_footnote_definition_sekd')
|
145
|
+
|
146
|
+
def parse_footnote_marker_sekd
|
147
|
+
start_line_number = @src.current_line_number
|
148
|
+
@src.pos += @src.matched_size
|
149
|
+
unless @fn_number.has_key?(@src[1])
|
150
|
+
warning("No footnote marker '#{@src[1]}' on line #{start_line_number} - missing")
|
151
|
+
end
|
152
|
+
@tree.children << new_block_el(:footnote_marker_sekd, @fn_number[@src[1]], nil,
|
153
|
+
:location => start_line_number)
|
154
|
+
end
|
155
|
+
|
156
|
+
FOOTNOTE_MARKER_START = /\[\^(#{ALD_ID_NAME})\]/
|
157
|
+
define_parser(:footnote_marker_sekd, FOOTNOTE_MARKER_START, '\[', 'parse_footnote_marker_sekd')
|
158
|
+
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'kconv'
|
4
|
+
require 'darkmouun'
|
5
|
+
|
6
|
+
require_relative 'kramdown/parser/sekd'
|
7
|
+
require_relative 'kramdown/converter/sehtml'
|
8
|
+
|
9
|
+
module ZineBrewer
|
10
|
+
|
11
|
+
class Application
|
12
|
+
|
13
|
+
Commons = "[hlink]: common/hlink.svg"
|
14
|
+
|
15
|
+
attr_reader :corner, :title, :lead, :pic, :author, :css, :converted
|
16
|
+
|
17
|
+
def initialize(path)
|
18
|
+
|
19
|
+
begin
|
20
|
+
Encoding.default_external = Kconv.guess(File.open(path, 'r:BINARY').read)
|
21
|
+
input_data = File.open(path, 'rt').read.encode('UTF-8')
|
22
|
+
rescue
|
23
|
+
puts 'ERROR: There is not the input file. Check the input file.'
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
|
27
|
+
@dir = File.dirname(path)
|
28
|
+
|
29
|
+
@article_id = begin
|
30
|
+
File.open("#{@dir}/id.txt", "rt").read.chomp
|
31
|
+
rescue
|
32
|
+
docdir = File.basename(@dir)
|
33
|
+
/^\d+$/ =~ docdir ? docdir : '■記事ID■'
|
34
|
+
end
|
35
|
+
|
36
|
+
header, body = /\A((?:.|\n)*?)<%-- page -->/.match(input_data).yield_self do |m|
|
37
|
+
if m.nil?
|
38
|
+
['', "\n\n" + Commons + "\n\n" + input_data]
|
39
|
+
else
|
40
|
+
[m[1], '<%-- page -->' + "\n\n" + Commons + "\n\n" + m.post_match]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
@article_id = $+ if header.sub!(/^■記事ID■[^0-9]+(\d+)$/, '')
|
45
|
+
h = header.strip.split(/\n\n+/)
|
46
|
+
@corner = set_header_item(h[0], 'IT人材ラボの記事・ニュース')
|
47
|
+
@title = set_header_item(h[1], 'タイトル' )
|
48
|
+
@lead = set_header_item(h[2], 'リード')
|
49
|
+
@pic = set_header_item(h[3], 'dummy.png')
|
50
|
+
@author = set_header_item(h[4], '著者 クレジット')
|
51
|
+
@css = set_header_item(h[5], '')
|
52
|
+
|
53
|
+
@converted = convert(body)
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_header_item(target, default)
|
57
|
+
if /\A[\-%]+\Z/ =~ target || target.nil?
|
58
|
+
default.define_singleton_method(:is_complete?){ false }
|
59
|
+
default
|
60
|
+
else
|
61
|
+
target.define_singleton_method(:is_complete?){ true }
|
62
|
+
target
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
## Writing out header and body to each file
|
67
|
+
def write_out
|
68
|
+
make_proof_directory
|
69
|
+
write_proof_header
|
70
|
+
write_proof_body
|
71
|
+
end
|
72
|
+
|
73
|
+
def make_proof_directory
|
74
|
+
@proof_dir = @dir + '/proof'
|
75
|
+
begin
|
76
|
+
Dir.mkdir(@proof_dir)
|
77
|
+
rescue Errno::EEXIST
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def write_proof_header
|
82
|
+
header_output = ""
|
83
|
+
header_output << "[コーナー]\n#{@corner}\n\n" if @corner.is_complete?
|
84
|
+
header_output << "[タイトル]\n#{@title}\n\n" if @title.is_complete?
|
85
|
+
header_output << "[リード]\n<p>#{@lead}</p>\n\n" if @lead.is_complete?
|
86
|
+
header_output << "[タイトル画像]\n#{@pic}\n\n" if @pic.is_complete?
|
87
|
+
header_output << "[著者クレジット]\n#{@author}\n\n" if @author.is_complete?
|
88
|
+
header_output << "[追加CSS]\n#{@css}\n\n" if @css.is_complete?
|
89
|
+
File.open("#{@proof_dir}/header.txt", 'wb') do |f|
|
90
|
+
f.write(header_output)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def write_proof_body
|
95
|
+
File.open("#{@proof_dir}/body.txt", 'wb') do |f|
|
96
|
+
f.write(@converted.gsub("<!-- page_delimiter -->\n", ''))
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
## Converts markdown to html and returns body
|
101
|
+
def convert(body)
|
102
|
+
dkmn = Darkmouun.document.new(body, {:auto_ids => false, :input => 'sekd'}, :se_html)
|
103
|
+
|
104
|
+
### Sets templates
|
105
|
+
dkmn.add_templates "#{__dir__}/templates/", *Dir['*.rb',base:"#{__dir__}/templates/"]
|
106
|
+
|
107
|
+
### Sets pre process
|
108
|
+
dkmn.pre_process = lambda do |t|
|
109
|
+
t.gsub!(/\n\K={2,}div/, "<div markdown=\"1\">")
|
110
|
+
t.gsub!(/\n\K={2,}\/div/, "</div>")
|
111
|
+
end
|
112
|
+
|
113
|
+
### Sets post process
|
114
|
+
dkmn.post_process = lambda do |t|
|
115
|
+
t.gsub!('(((BR)))', '<br/>')
|
116
|
+
t.gsub!(/■記事ID■/, @article_id)
|
117
|
+
t.gsub!(/—/, "―")
|
118
|
+
t.gsub!(/[‘’]/, "'")
|
119
|
+
t.gsub!(/<li>\\/, '<li>')
|
120
|
+
t << "</div>" if /<div id="p1">/ =~ t
|
121
|
+
end
|
122
|
+
|
123
|
+
### Converts a markdown document and returns that converted body
|
124
|
+
dkmn.convert
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
class BookRanking < Mustache
|
4
|
+
|
5
|
+
# <<BookRanking>>
|
6
|
+
# url: AmazonのURL
|
7
|
+
# title: 書名
|
8
|
+
# src: 書影ファイル名
|
9
|
+
# desc: 説明
|
10
|
+
|
11
|
+
@template = <<EOT
|
12
|
+
<div class="imgLRBlock cf">
|
13
|
+
<figure class="imgR">
|
14
|
+
<a href="{{url}}" target="_blank"><img alt="{{title}}" src="{{cover}}" style="border:1px solid #808080; width:100px;" title="{{title}}" /></a></figure>
|
15
|
+
<p markdown="1"> {{& description}}</p>
|
16
|
+
</div>
|
17
|
+
EOT
|
18
|
+
|
19
|
+
def description
|
20
|
+
Mustache.new.render(desc, {book: "『[#{title}](#{url})』"})
|
21
|
+
end
|
22
|
+
|
23
|
+
def cover
|
24
|
+
case File.dirname(src)
|
25
|
+
when ".", "images"
|
26
|
+
"/static/images/article/■記事ID■/#{File.basename(src)}"
|
27
|
+
when "common"
|
28
|
+
"/static/images/article/common/#{File.basename(src)}"
|
29
|
+
else
|
30
|
+
src
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
class Casts < Mustache
|
4
|
+
|
5
|
+
# <<Casts>>
|
6
|
+
# casts:
|
7
|
+
# src: 写真ファイル名
|
8
|
+
# name: 姓 名
|
9
|
+
# huri: ふり がな
|
10
|
+
# cap: プロフィール
|
11
|
+
|
12
|
+
# CSSに下記の登録が必要
|
13
|
+
# article#contents div.article div.casts>div ~ div { margin-top:8px; }
|
14
|
+
|
15
|
+
@template = <<EOT
|
16
|
+
<div class="casts" style="margin-bottom:30px; padding:13px 13px 3px; border:solid 2px #eee;">
|
17
|
+
{{#prof_list}}
|
18
|
+
<div class="imgLRBlock cf">
|
19
|
+
<figure class="imgL">
|
20
|
+
<img src="{{fig_src}}" alt="{{name}}" style="height:135px;" />
|
21
|
+
</figure>
|
22
|
+
<p class="ovh" markdown="span" style="font-size:14px; line-height:1.7; margin-bottom:10px;"><strong>{{name}}({{huri}})氏</strong><br />{{& caption}}</p>
|
23
|
+
</div>
|
24
|
+
{{/prof_list}}
|
25
|
+
</div>
|
26
|
+
EOT
|
27
|
+
|
28
|
+
def prof_list
|
29
|
+
result = []
|
30
|
+
(casts rescue a_cast_param).each do |h|
|
31
|
+
a_cast = {}
|
32
|
+
raise "Error: No src:" if h["src"].nil?
|
33
|
+
a_cast[:fig_src] = make_src(h["src"])
|
34
|
+
a_cast[:name] = h["name"]
|
35
|
+
a_cast[:huri] = h["huri"]
|
36
|
+
a_cast[:caption] = make_caption(h["cap"])
|
37
|
+
result << a_cast
|
38
|
+
end
|
39
|
+
result
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def a_cast_param
|
44
|
+
[{"src" => (src rescue nil),
|
45
|
+
"name" => (name rescue nil),
|
46
|
+
"huri" => (huri rescue nil),
|
47
|
+
"cap" => (cap rescue nil)}]
|
48
|
+
end
|
49
|
+
|
50
|
+
def make_src(l_src)
|
51
|
+
case File.dirname(l_src)
|
52
|
+
when ".", "images"
|
53
|
+
"/static/images/article/■記事ID■/#{File.basename(l_src)}"
|
54
|
+
when "common"
|
55
|
+
"/static/images/article/common/#{File.basename(l_src)}"
|
56
|
+
else
|
57
|
+
l_src
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def make_caption(l_cap)
|
62
|
+
begin
|
63
|
+
l_cap.chomp.sub(/^\\/, '').gsub(/\n/, '(((BR)))')
|
64
|
+
rescue
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
__END__
|
72
|
+
|
73
|
+
{:.casts %margin-bottom:45px; %padding:13px 13px 3px; %border:solid 2px #eee;}
|
74
|
+
===div
|
75
|
+
|
76
|
+
{:.imgLRBlock .cf}
|
77
|
+
===div
|
78
|
+
{:.imgL}
|
79
|
+
<<Fig_N>>
|
80
|
+
src: 2096_misonou_p.jpg
|
81
|
+
height: 135px
|
82
|
+
|
83
|
+
{:.ovh markdown="1" %font-size:14px; %line-height:1.7; %margin-bottom:10px;}
|
84
|
+
**御園生 銀平(みそのう ぎんぺい)氏**<br/>
|
85
|
+
ソフトバンク株式会社[[ ]]{:%font-size:3px;}人事本部[[ ]]{:%font-size:3px;}戦略企画統括部[[ ]]{:%font-size:3px;}人材戦略部[[ ]]{:%font-size:3px;}デジタルHR推進課。<br/>
|
86
|
+
(※御園生様のプロフィールを100〜150字程度でお願いいたします)。
|
87
|
+
==/div
|
88
|
+
|
89
|
+
{:.imgLRBlock .cf}
|
90
|
+
===div
|
91
|
+
{:.imgL}
|
92
|
+
<<Fig_N>>
|
93
|
+
src: 2096_shikauchi_p.jpg
|
94
|
+
height: 135px
|
95
|
+
|
96
|
+
{:.ovh markdown="1" %font-size:14px; %line-height:1.7; %margin-bottom:10px;}
|
97
|
+
**鹿内 学(しかうち まなぶ)氏**<br/>
|
98
|
+
博士(理学)。株式会社シンギュレイト 代表。<br/>
|
99
|
+
働く中でのコミュニケーション・データから関係性に注目した次世代ピープルアナリティクスにとりくむ。代表を務めるシンギュレイトでは1 on 1や会議で利用できる可視化ツールを提供中。働く組織の科学と実用をめざす。情報量規準が好き、サッカー好き、漫画好き。
|
100
|
+
==/div
|
101
|
+
|
102
|
+
==/div
|
103
|
+
|
104
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Fig_00
|
4
|
+
|
5
|
+
def imgs_list
|
6
|
+
result = []
|
7
|
+
(imgs rescue a_img_param).each do |h|
|
8
|
+
a_img = {}
|
9
|
+
raise "Error: No src:" if h["src"].nil?
|
10
|
+
a_img[:fig_src] = make_src(h["src"])
|
11
|
+
a_img[:href] = h["href"]
|
12
|
+
a_img[:alt] = make_alt(h["alt"])
|
13
|
+
a_img[:img_style] = make_img_style(h["width"], h["height"]) \
|
14
|
+
unless h["width"].nil? && h["height"].nil?
|
15
|
+
result << a_img
|
16
|
+
end
|
17
|
+
result
|
18
|
+
end
|
19
|
+
|
20
|
+
def caption
|
21
|
+
begin
|
22
|
+
cap.chomp.sub(/^\\/, '').gsub(/\n/,'(((BR)))')
|
23
|
+
rescue
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def a_img_param
|
30
|
+
[{"src" => (src rescue nil),
|
31
|
+
"href" => (href rescue nil),
|
32
|
+
"alt" => (alt rescue caption),
|
33
|
+
"width" => (width rescue nil),
|
34
|
+
"height" => (height rescue nil)}]
|
35
|
+
end
|
36
|
+
|
37
|
+
def make_src(l_src)
|
38
|
+
case File.dirname(l_src)
|
39
|
+
when ".", "images"
|
40
|
+
f = File.basename(l_src)
|
41
|
+
"/static/images/article/■記事ID■/#{/^\d+_/ =~ f ? f : '■記事ID■_' + f}"
|
42
|
+
when "common"
|
43
|
+
"/static/images/article/common/#{File.basename(l_src)}"
|
44
|
+
else
|
45
|
+
l_src
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def make_alt(l_alt)
|
50
|
+
begin
|
51
|
+
l_alt.gsub(/\[(.+?)\]\(.+?\)/, '\1').gsub(/\n/, '')
|
52
|
+
rescue
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def make_img_style(l_width, l_height)
|
58
|
+
s = []
|
59
|
+
s << "width:#{l_width};" unless l_width.nil?
|
60
|
+
s << "height:#{l_height};" unless l_height.nil?
|
61
|
+
unless s.all?{|v| v.nil? }
|
62
|
+
%Q{style="#{s.join(' ').strip}" }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative 'fig/module_fig_base'
|
4
|
+
require_relative 'fig/module_fig_plus'
|
5
|
+
|
6
|
+
class Fig_A < Mustache
|
7
|
+
|
8
|
+
include Fig_00, Fig_01
|
9
|
+
|
10
|
+
# <<Fig_A>>
|
11
|
+
# src: 画像ファイル名
|
12
|
+
# width: 画像幅
|
13
|
+
# height: 画像高さ
|
14
|
+
# cap: キャプション
|
15
|
+
|
16
|
+
@template = <<EOT
|
17
|
+
<figure>
|
18
|
+
{{#imgs_list}}
|
19
|
+
<a href="{{fig_src}}" target="_blank"><img src="{{fig_src}}" alt="{{alt}}" {{& img_style}}/></a>
|
20
|
+
{{/imgs_list}}
|
21
|
+
<figcaption markdown="span">{{#figcaption_sw}}{{& caption}}<br/>{{/figcaption_sw}}[画像クリックで拡大表示]</figcaption>
|
22
|
+
</figure>
|
23
|
+
EOT
|
24
|
+
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative 'fig/module_fig_base'
|
4
|
+
require_relative 'fig/module_fig_plus'
|
5
|
+
|
6
|
+
class Fig_H < Mustache
|
7
|
+
|
8
|
+
include Fig_00, Fig_01
|
9
|
+
|
10
|
+
# <<Fig_H>>
|
11
|
+
# src: 画像ファイル名
|
12
|
+
# href: 画像クリックで遷移するURL
|
13
|
+
# width: 画像幅
|
14
|
+
# height: 画像高さ
|
15
|
+
# cap: キャプション
|
16
|
+
|
17
|
+
@template = <<EOT
|
18
|
+
<figure>
|
19
|
+
{{#imgs_list}}
|
20
|
+
{{#href}}<a href="{{href}}" target="_blank">{{/href}}<img src="{{fig_src}}" alt="{{alt}}" {{& img_style}}/>{{#href}}</a>{{/href}}
|
21
|
+
{{/imgs_list}}
|
22
|
+
{{#figcaption_sw}}<figcaption markdown="span">{{& caption}}</figcaption>{{/figcaption_sw}}
|
23
|
+
</figure>
|
24
|
+
EOT
|
25
|
+
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative 'fig/module_fig_base'
|
4
|
+
require_relative 'fig/module_fig_plus'
|
5
|
+
|
6
|
+
class Fig_N < Mustache
|
7
|
+
|
8
|
+
include Fig_00, Fig_01
|
9
|
+
|
10
|
+
# <<Fig_N>>
|
11
|
+
# src: 画像ファイル名
|
12
|
+
# width: 画像幅
|
13
|
+
# height: 画像高さ
|
14
|
+
# cap: キャプション
|
15
|
+
# from: 出典 << 出典URL
|
16
|
+
|
17
|
+
@template = <<EOT
|
18
|
+
<figure>
|
19
|
+
{{#imgs_list}}
|
20
|
+
<img src="{{fig_src}}" alt="{{alt}}" {{& img_style}}/>
|
21
|
+
{{/imgs_list}}
|
22
|
+
{{#figcaption_sw}}<figcaption markdown="span">{{caption}}{{& cited_from}}</figcaption>{{/figcaption_sw}}
|
23
|
+
</figure>
|
24
|
+
EOT
|
25
|
+
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative 'fig/module_fig_base'
|
4
|
+
|
5
|
+
class Fig_P < Mustache
|
6
|
+
|
7
|
+
include Fig_00
|
8
|
+
|
9
|
+
# <<Fig_P>>
|
10
|
+
# src: 画像ファイル名
|
11
|
+
# name: 姓 名
|
12
|
+
# huri: ふり・がな
|
13
|
+
# width: 画像幅
|
14
|
+
# height: 画像高さ
|
15
|
+
# cap: |
|
16
|
+
# キャプション
|
17
|
+
|
18
|
+
@template = <<EOT
|
19
|
+
<figure>
|
20
|
+
{{#imgs_list}}
|
21
|
+
<img src="{{fig_src}}" alt="{{name}}氏" {{& img_style}} />
|
22
|
+
{{/imgs_list}}
|
23
|
+
<div style="text-align:left; padding:0em 2em;">
|
24
|
+
<figcaption><strong>{{name}}({{huri}})氏</strong></figcaption>
|
25
|
+
<figcaption markdown="span">{{caption}}</figcaption>
|
26
|
+
</div>
|
27
|
+
</figure>
|
28
|
+
EOT
|
29
|
+
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative 'fig/module_fig_base'
|
4
|
+
require_relative 'fig/module_fig_plus'
|
5
|
+
|
6
|
+
class Fig_Z < Mustache
|
7
|
+
|
8
|
+
include Fig_00, Fig_01
|
9
|
+
|
10
|
+
# <<Fig_Z>>
|
11
|
+
# src: 画像ファイル名
|
12
|
+
# width: 画像幅
|
13
|
+
# height: 画像高さ
|
14
|
+
# cap: キャプション
|
15
|
+
|
16
|
+
@template = <<EOT
|
17
|
+
<figure>
|
18
|
+
{{#imgs_list}}
|
19
|
+
<a href="{{fig_src}}" rel="lightbox" target="_blank"><img src="{{fig_src}}" alt="{{alt}}" {{& img_style}}/></a>
|
20
|
+
{{/imgs_list}}
|
21
|
+
<figcaption markdown="span">{{#figcaption_sw}}{{& caption}}<br/>{{/figcaption_sw}}[画像クリックで拡大表示]</figcaption>
|
22
|
+
</figure>
|
23
|
+
EOT
|
24
|
+
|
25
|
+
end
|
26
|
+
|
data/zine_brewer.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative 'lib/zine_brewer/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "zine_brewer"
|
5
|
+
spec.version = ZineBrewer::VERSION
|
6
|
+
spec.authors = ["Akinori Ichigo"]
|
7
|
+
spec.email = ["akinori.ichigo@gmail.com"]
|
8
|
+
|
9
|
+
spec.summary = %q{Kramdown to HTML converter for Shoeisha Web Media}
|
10
|
+
spec.homepage = "https://github.com/akinori-ichigo/zine_brewer"
|
11
|
+
spec.license = "MIT"
|
12
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
13
|
+
|
14
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
15
|
+
spec.metadata["source_code_uri"] = "https://github.com/akinori-ichigo/zine_brewer"
|
16
|
+
spec.metadata["changelog_uri"] = "https://github.com/akinori-ichigo/zine_brewer"
|
17
|
+
|
18
|
+
# Specify which files should be added to the gem when it is released.
|
19
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
20
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
21
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
|
+
end
|
23
|
+
spec.bindir = "exe"
|
24
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
|
+
spec.require_paths = ["lib"]
|
26
|
+
|
27
|
+
spec.add_runtime_dependency "darkmouun"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zine_brewer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Akinori Ichigo
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-10-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: darkmouun
|
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
|
+
description:
|
28
|
+
email:
|
29
|
+
- akinori.ichigo@gmail.com
|
30
|
+
executables:
|
31
|
+
- zine_brewer
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- CODE_OF_CONDUCT.md
|
36
|
+
- Gemfile
|
37
|
+
- LICENSE.txt
|
38
|
+
- README.md
|
39
|
+
- Rakefile
|
40
|
+
- bin/console
|
41
|
+
- bin/setup
|
42
|
+
- exe/zine_brewer
|
43
|
+
- lib/zine_brewer.rb
|
44
|
+
- lib/zine_brewer/kramdown/converter/sehtml.rb
|
45
|
+
- lib/zine_brewer/kramdown/parser/sekd.rb
|
46
|
+
- lib/zine_brewer/main.rb
|
47
|
+
- lib/zine_brewer/templates/bookranking.rb
|
48
|
+
- lib/zine_brewer/templates/casts.rb
|
49
|
+
- lib/zine_brewer/templates/fig/module_fig_base.rb
|
50
|
+
- lib/zine_brewer/templates/fig/module_fig_plus.rb
|
51
|
+
- lib/zine_brewer/templates/fig_a.rb
|
52
|
+
- lib/zine_brewer/templates/fig_h.rb
|
53
|
+
- lib/zine_brewer/templates/fig_n.rb
|
54
|
+
- lib/zine_brewer/templates/fig_p.rb
|
55
|
+
- lib/zine_brewer/templates/fig_z.rb
|
56
|
+
- lib/zine_brewer/version.rb
|
57
|
+
- zine_brewer.gemspec
|
58
|
+
homepage: https://github.com/akinori-ichigo/zine_brewer
|
59
|
+
licenses:
|
60
|
+
- MIT
|
61
|
+
metadata:
|
62
|
+
homepage_uri: https://github.com/akinori-ichigo/zine_brewer
|
63
|
+
source_code_uri: https://github.com/akinori-ichigo/zine_brewer
|
64
|
+
changelog_uri: https://github.com/akinori-ichigo/zine_brewer
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 2.3.0
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubygems_version: 3.1.4
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: Kramdown to HTML converter for Shoeisha Web Media
|
84
|
+
test_files: []
|