yard-sd 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Example.md ADDED
@@ -0,0 +1,74 @@
1
+ Input:
2
+
3
+ !!!plain
4
+ !!!sd
5
+ % size = 800
6
+
7
+ thread SimulationServer as SiS
8
+ participant SimControlNode as SCN
9
+ participant PhysicsServer as PS
10
+ participant[2] SenseServer as SeS
11
+
12
+ SiS->SeS: Initialize()
13
+ SeS-->SiS:
14
+
15
+ block "Run Loop" "The main loop"
16
+ SiS->SCN: StartCycle()
17
+ SCN->SeS: ActAgent()
18
+ SeS-->SCN:
19
+ SCN-->SiS:
20
+
21
+ SiS->PS: Update()
22
+ PS->SeS: PrePhysicsUpdate
23
+ noreturn
24
+
25
+ PS->PS: PhysicsUpdate()
26
+ PS-->PS:
27
+
28
+ PS->SeS: PostPhysicsUpdate()
29
+ SeS-->PS:
30
+
31
+ PS-->SiS:
32
+
33
+ SiS->SCN: EndCycle()
34
+ SCN->SeS: SenseAgent()
35
+ SeS-->SCN:
36
+ SCN-->SiS:
37
+
38
+ Output:
39
+
40
+ !!!sd
41
+ % size = 800
42
+
43
+ thread SimulationServer as SiS
44
+ participant SimControlNode as SCN
45
+ participant PhysicsServer as PS
46
+ participant[2] SenseServer as SeS
47
+
48
+ SiS->SeS: Initialize()
49
+ SeS-->SiS:
50
+
51
+ block "Run Loop" "The main loop"
52
+ SiS->SCN: StartCycle()
53
+ SCN->SeS: ActAgent()
54
+ SeS-->SCN:
55
+ SCN-->SiS:
56
+ SiS->SCN: Something
57
+ SCN-->SiS: Something else
58
+
59
+ SiS->PS: Update()
60
+ PS->SeS: PrePhysicsUpdate
61
+ noreturn
62
+
63
+ PS->PS: PhysicsUpdate()
64
+ PS-->PS:
65
+
66
+ PS->SeS: PostPhysicsUpdate()
67
+ SeS-->PS:
68
+
69
+ PS-->SiS:
70
+
71
+ SiS->SCN: EndCycle()
72
+ SCN->SeS: SenseAgent()
73
+ SeS-->SCN:
74
+ SCN-->SiS:
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Dominik Honnef
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # yard-sd
2
+
3
+ Note: This README and {file:Example.md the example} are best viewed on
4
+ {http://doc.fork-bomb.org/yard-sd/} or a service supporting the
5
+ yard-sd plugin.
6
+
7
+ ## Description
8
+
9
+ yard-sd allows embedding sequence diagrams directly in docstrings and
10
+ files. During documentation generation, it replaces the text
11
+ description with images.
12
+
13
+ ## Requirements
14
+
15
+ yard-sd needs YARD 0.7.5/0.8.0 to function properly.
16
+
17
+ Furthermore, yard-sd needs the following binaries:
18
+
19
+ - pdflatex
20
+ - convert (from the ImageMagick suite)
21
+ - gs (Ghostscript, needed by convert)
22
+
23
+ ## Installation
24
+
25
+ $ gem install yard-sd
26
+
27
+ ## Usage
28
+
29
+ yard-sd defines a new language for code blocks called "sd". Like other
30
+ languages, it can be used with the tripple-bang syntax (!!!LANG).
31
+
32
+ ## Example
33
+
34
+ ### Input
35
+
36
+ !!!plain
37
+ !!!sd
38
+ % size = 400
39
+
40
+ thread Alice
41
+ participant[2] Bob
42
+ participant[2] Eve
43
+
44
+ Alice -> Bob: Some message
45
+ Bob -> Eve: Another message
46
+ Eve --> Bob: Return value
47
+ noreturn
48
+
49
+ ### Output
50
+
51
+ !!!sd
52
+ %size = 400
53
+
54
+ thread Alice
55
+ participant[2] Bob
56
+ participant[2] Eve
57
+
58
+ Alice -> Bob: Some message
59
+ Bob -> Eve: Another message
60
+ Eve --> Bob: Return value
61
+ noreturn
62
+
63
+ ## The format
64
+
65
+ A sequence diagram consists of two parts: the metadata (currently only
66
+ the size) and the actual description of the diagram's content.
67
+
68
+ ### Metadata
69
+
70
+ The only currently supported and required metadata is the size of the
71
+ diagram. You can either specify only a width (e.g. `500`), only a
72
+ height (e.g. `x500`) or both (e.g. `500x500`). In most cases it makes
73
+ sense to specify only one of the dimensions so the aspect ratio can be
74
+ kept.
75
+
76
+ ### Content
77
+
78
+ The content itself can also be separated into two parts: The list of
79
+ threads/participants (simply called participants from now on) and the
80
+ messages between those.
81
+
82
+ #### Participants
83
+
84
+ In their most basic form, they consist of a type (`thread` or
85
+ `participant`) and a name.
86
+
87
+ Example:
88
+
89
+ !!!plain
90
+ thread Alice
91
+ participant Bob
92
+
93
+ Output:
94
+
95
+ !!!sd
96
+ % size = 200
97
+ thread Alice
98
+ participant Bob
99
+
100
+ It is also possible to specify the distance to the previous
101
+ participant by adding a number in square brackets. The default is `0`,
102
+ so `1` will double the distance, `2` will triple it and so on.
103
+
104
+ Example:
105
+
106
+ !!!plain
107
+ thread Alice
108
+ participant[1] Bob
109
+
110
+ Output:
111
+
112
+ !!!sd
113
+ % size = 200
114
+ thread Alice
115
+ participant[1] Bob
116
+
117
+ Finally, it is also possible to assign aliases to avoid typing out
118
+ long names over and over again.
119
+
120
+ Example:
121
+
122
+ !!!plain
123
+ participant "Alice, the wonderful girl" as Alice
124
+ participant Bob
125
+
126
+ Alice -> Bob: Yey
127
+
128
+ Output:
129
+
130
+ !!!sd
131
+ % size = 300
132
+ participant "Alice, the wonderful girl" as Alice
133
+ participant Bob
134
+
135
+ Alice -> Bob: Yey
136
+ #### Messages
137
+
138
+ The second part of description of the sequende diagram consists of
139
+ messages between participants. Messages are denoted by an arrow and
140
+ text (`p1 -> p2: The message`) while return values are denoted by a
141
+ dashed arrow and also text (`p2 --> p1: The return value`). If a
142
+ message has no return value, a `noreturn` has to be placed after the
143
+ execution finished.
144
+
145
+ Example:
146
+
147
+ !!!plain
148
+ Alice -> Bob: Some message
149
+ Bob -> Eve: Another message
150
+ Eve --> Bob: Return value
151
+ noreturn
152
+
153
+ Output:
154
+
155
+ !!!sd
156
+ % size = 400
157
+ participant Alice
158
+ participant[1] Bob
159
+ participant[2] Eve
160
+
161
+ Alice -> Bob: Some message
162
+ Bob -> Eve: Another message
163
+ Eve --> Bob: Return value
164
+ noreturn
165
+
166
+ #### Blocks
167
+
168
+ Furthermore, it is possible to group messages into blocks, for example
169
+ for representing loops:
170
+
171
+ Example:
172
+
173
+ !!!plain
174
+ block "Name" "Description"
175
+ Alice -> Bob: Msg1
176
+ Bob --> Alice: Ret1
177
+
178
+ block "Another name" "Nested blocks, yey"
179
+ Alice -> Bob: Msg2
180
+ noreturn
181
+
182
+ Alice -> Bob: Msg3
183
+ Bob --> Alice: Ret3
184
+
185
+ Output:
186
+
187
+ !!!sd
188
+ % size = 200
189
+
190
+ participant Alice
191
+ participant Bob
192
+
193
+ block "Name" "Description"
194
+ Alice -> Bob: Msg1
195
+ Bob --> Alice: Ret1
196
+
197
+ block "Another name" "Nested blocks, yey"
198
+ Alice -> Bob: Msg2
199
+ noreturn
200
+
201
+ Alice -> Bob: Msg3
202
+ Bob --> Alice: Ret3
203
+
204
+ Blocks automatically get closed, based on the indentation level.
205
+
206
+ ### More information
207
+
208
+ For a more advanced example, see {file:Example.md Example.md}.
209
+
210
+ ## Caveats
211
+
212
+ yard-sd currently does not support Unicode.
@@ -0,0 +1,168 @@
1
+ require "tmpdir"
2
+ require "fileutils"
3
+
4
+ module SequenceDiagram
5
+
6
+ class Diagram
7
+ Block = Struct.new(:level, :name, :description)
8
+ Call = Struct.new(:p1, :p2, :message, :return, :block)
9
+ @@uid = 0
10
+
11
+ attr_reader :uid
12
+ def initialize
13
+ @participants = []
14
+ @calls = []
15
+ @uid = @@uid += 1
16
+ end
17
+
18
+ def parse(s)
19
+ last_calls = Hash.new {|h, k| h[k] = []}
20
+ blocks = [Block.new(0, nil, nil)]
21
+ last_indent = 0
22
+
23
+ s.each_line do |line|
24
+ line.chomp!
25
+ next if line.empty?
26
+
27
+ case line
28
+ when /^(participant|thread)(?:\[(\d+)\])? ("?)(.+?)\3(?: as (.+))?$/
29
+ distance = $2 && $2.to_i
30
+ name = $4
31
+ aliasing = $5 || name
32
+ thread = $1 == "thread"
33
+ @participants << Participant.new(name, aliasing, distance, thread)
34
+ when /^(\s*)block "([^"]+)" "([^"]+)"/
35
+ if $1.size < last_indent
36
+ blocks.pop
37
+ end
38
+
39
+ blocks << Block.new(blocks.size, $2, $3)
40
+ when /^(\s*)(.+?)\s*(->|-->)\s*(.+?):(?: (.+))?$/
41
+ p1 = @participants.find {|p| p.aliasing == $2}
42
+ p2 = @participants.find {|p| p.aliasing == $4}
43
+
44
+ error(:unknown_participant, line) if p1.nil?
45
+ error(:unknown_participant, line) if p2.nil?
46
+
47
+ message = $5.to_s
48
+
49
+ if $1.size < last_indent
50
+ blocks.pop
51
+ end
52
+
53
+ last_indent = $1.size
54
+
55
+ case $3
56
+ when "->"
57
+ call = Call.new(p1, p2, message, nil, blocks.last)
58
+ last_calls[p1] << call
59
+ @calls << call
60
+ when "-->"
61
+ last_calls[p2].pop.return = message.to_s
62
+ @calls << :pop
63
+ end
64
+ when /^\s*noreturn$/
65
+ @calls << :pop
66
+ else
67
+ error(:cannot_parse, line)
68
+ end
69
+ end
70
+
71
+ self
72
+ end
73
+
74
+ def error(kind, information)
75
+ raise ParseError, [kind, information].inspect
76
+ end
77
+
78
+ def to_s
79
+ s = "\\begin{sequencediagram}\n"
80
+ @participants.each do |p|
81
+ s << p.to_s << "\n"
82
+ end
83
+
84
+ last_callee = nil
85
+ prev_block_level = 0
86
+ open = []
87
+
88
+ indent = 0
89
+ @calls.each do |call|
90
+ if call == :pop
91
+ indent -= 1
92
+ s << " " * indent << "\\end{#{open.pop}}\n"
93
+ next
94
+ end
95
+
96
+ if call.block.level > prev_block_level
97
+ s << " " * indent << "\\begin{sdblock}{#{call.block.name}}{#{call.block.description}}\n"
98
+ indent += 1
99
+ elsif call.block.level < prev_block_level
100
+ indent -= 1
101
+ s << " " * indent << "\\end{sdblock}\n"
102
+ end
103
+ prev_block_level = call.block.level
104
+
105
+ if !call.return.nil?
106
+ if call.p1 == call.p2
107
+ s << " " * indent << "\\begin{callself}{#{call.p1.uid}}{#{SequenceDiagram.latex_escape(call.message)}}{#{SequenceDiagram.latex_escape(call.return)}}\n"
108
+ open << :callself
109
+ else
110
+ s << " " * indent << "\\begin{call}{#{call.p1.uid}}{#{SequenceDiagram.latex_escape(call.message)}}{#{call.p2.uid}}{#{SequenceDiagram.latex_escape(call.return)}}\n"
111
+ open << :call
112
+ end
113
+ else
114
+ s << " "* indent << "\\begin{messcall}{#{call.p1.uid}}{#{SequenceDiagram.latex_escape(call.message)}}{#{call.p2.uid}}\n"
115
+ open << :messcall
116
+ end
117
+ indent += 1
118
+ end
119
+
120
+ while close = open.pop
121
+ s << " " * indent << "\\end{#{close}}\n"
122
+ indent -= 1
123
+ end
124
+
125
+ while prev_block_level > 0
126
+ indent -= 1
127
+ s << " " * indent << "\\end{sdblock}\n"
128
+ prev_block_level -= 1
129
+ end
130
+
131
+ s << "\\end{sequencediagram}"
132
+ end
133
+
134
+ def to_png(options = {})
135
+ graph = self.to_s
136
+ tex = Template.sub("%%EMBED\n", graph.sub(/\n+$/, ""))
137
+ dir = Dir.mktmpdir
138
+ image = nil
139
+
140
+ Dir.chdir(dir) do
141
+ # File.open("/tmp/debug.tex", "w"){|f| f.print tex}
142
+ IO.popen("pdflatex -halt-on-error", "w+") do |pipe|
143
+ pipe.write tex
144
+ pipe.close_write
145
+ pipe.read
146
+ end
147
+
148
+ if $?.exitstatus != 0
149
+ error("Couldn't compile latex", nil)
150
+ end
151
+
152
+ args = ["-depth", "4",
153
+ "-quality", "95",
154
+ "-colorspace", "RGB",
155
+ "-density", "500x500",
156
+ "-flatten"]
157
+
158
+ args << "-resize" << options[:size] if options[:size]
159
+
160
+ image = `convert #{args.join(" ")} texput.pdf png:-`
161
+ end
162
+
163
+ FileUtils.rm_rf(dir)
164
+
165
+ return image
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,4 @@
1
+ module SequenceDiagram
2
+ class ParseError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,30 @@
1
+ module SequenceDiagram
2
+ class Participant
3
+ @@uid = 0
4
+
5
+ attr_reader :name
6
+ attr_reader :distance
7
+ attr_reader :uid
8
+ attr_reader :aliasing
9
+ def initialize(name, aliasing, distance = nil, thread = false)
10
+ @name = name
11
+ @aliasing = aliasing
12
+ @distance = distance
13
+ @thread = thread
14
+ @uid = @@uid += 1
15
+ end
16
+
17
+ def to_s
18
+ cmd = @thread ? "newthread" : "newinst"
19
+ if @distance.nil?
20
+ "\\#{cmd}{#@uid}{#{SequenceDiagram.latex_escape(@name)}}"
21
+ else
22
+ "\\#{cmd}[#@distance]{#@uid}{#{SequenceDiagram.latex_escape(@name)}}"
23
+ end
24
+ end
25
+
26
+ def ==(other)
27
+ @uid == other.uid
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ require "zlib"
2
+
3
+ require "yard-sd/sequence_diagram/parse_error"
4
+ require "yard-sd/sequence_diagram/participant"
5
+ require "yard-sd/sequence_diagram/diagram"
6
+
7
+ module SequenceDiagram
8
+ # Author: Xu Yuan <xuyuan.cn@gmail.com>, Southeast University, China
9
+ # Contributor: Nobel Huang <nobel1984@gmail.com>, Southeast University, China
10
+ Template = Zlib::Inflate.inflate "x\x9C\xE5ZK\x8F\xDB8\x12\xBE\xF7\xAF\xE0\xA2\xD1@w\xDA\x16\xFC\xE8\xCE\x06\t\x9C\xC3\xCC\x06\x8B=\f\xB0X\xCC\xCD6\x06\xB4D\xDB\x9C\x96H\rE\xB5\xE3\xD1\xEA\xBFo\x15\x1F\x12\xF5pO\xD2\xC9a13\x87\x8EE\x16\x8B\xF5\xFCX,\xCE&\x91q\x991\xA1\xE3\x94\x16EUh*\x12\x9AJ\xC1\xEA\xABMN\x0F\xAC\xD0\xE7\x94U,\xCB\xF5\x19F\xCA\x82\xE54~\x82\xF1J\xF3\xA7\xDF\xEB+3\x84?S\xBEST\x9D+\xAA\x94<\x150qC\x12\x06<\x15#)=3U\x00\xBB\xC3\xDE\r\x99\x91j\a\x9C\x0EJ\x96\"\xA9\x87\x93\xFA\xA8\x18M\xC2i\xD8\xC7r\n\x16NB\xB2IF\xB90;\vv\"1\fi\xB3/|\xB9\x8F*W\x8C\x8BB\xD7\x9DA\x1C\x11e\xD6\x1D\xB4\x8C\a\xC3\x05\xFB-e\xCF,\xAD\xC9\r1?:\xB31M\xED\xEC`\xB4`\xE9~dj\x97\xCA\xF8\xC9\x8D;\xB9\xA9 (\x10\x151\x83\x91O\x9Fi\x96\xA7\xEC=\xFC\xC4u8\xB3f\xC9\x81\x91\x84[\x9Am\xF5LU]\t\x9A\xB1\xF7\xC6\x85~\x83,\x03OV~Q\xBD^n\xD7\xB3h\xB1\xAD\xAE\b\xD9\x14\x9A\xE5\x03\xEDa<\xA7\xFAHnqd\xA3\x8F\xCC\x19+b\xB4\xD0w\xF7\xB7\xD7\xF3\xC9\xEC\x8E\b\x99\xB05\x0E\x9B\xC0\xD8\xB6\xD4\x8E\xCF\x1D\xF0\xA96\xE0\r\xA6R.Xu\xBD\xAC\xEB\x0FC\xDE\x9E\xFA\xFEv6\x99\xCE\xA2\xC77\xB0\x84\xEB=\x8D\xB5Tv\x13r{\xBD\xB8#\x95]\x8C\x11f#\x11\x17\xC62\x95\xEAzQ\xAF\xD6\xDB\xBE6\x8D\x83\xC7\xECI\xACS/\x98\xD5p\r\xCCYW\x17\xECi\xB9\x18\x8B\x1E\x14=\xFFm9\xB3Vu\x8C*\x90\f\xD5\xEE\x8B\x16D\x14\x12\xA3\x1Dw,\x95'\"\xF7\xAB\x9EY&\xC6\x00\xDE\xC5\xABY\xF4.\xCE\xC0\xD4\x96\x03\xD25\xBCF,d\xE7\x8C6\x1DR0\xD7\x9E\xA7\xE9\xEAz\xBE}\xC9\xA4\r\x8D\xCDaEOD\x95Bpq@\x01x\xFCtG\xD0\xB1\x13R\x1Ce\x99&\xE0+M0\xC2A\\\xC5b\x9D\x9EC{\xBD\xA96\xC8\xC1[\xCC\x85\xDF\x8E\x1D\xB8\xA8 \xA5\xA50\x19]\xF7\xB2\x9D\xC0\x7Ff\xDD\xDA\x8E\e1';\xA9 \xA8~\xB1\x1FF\xCA\xD3\x91k\f\xC1\xEByt\x02\xA0\xBA#\xD3\xA9\xF90\x01k?\x16\xDD\x8F\x86,>\xC7)3\x86c\xE0\xD5@\x14\xAB6%\xFBR\xC4\x9AKat\xEBE\x8C\x95\x1F'\xEA5\xF8\xECp\xD4[\x9B\xFA\xA0\x89_W\xDB\x11\x88\"\xC5t\xA9\x00\x97n\xEC^f\x99\xB1\x11\x13\xCF\\I\x81\xE0\xEB\x98=n\xD7\xF3a\x866\x98\xD3\x9Fh\xE0\x06\xC0(/\x8B\xA3O3\xF8\x17\x93\xC7\xE4\x16\x86\x80g\x10&\x19$\xDD\xDF\xC7\x92.\xDE\xE3\n\xCF\x19\xC3\xCBp{\x886\xD6\x17;N\x8BWr\xD6}\xCE\x1F\xAE\xAE\xBC\xA3\xCD\xB1\xE1|;\xFD8\xF9\xB8\xD2\x8ASqH\x19y;\x03\x0FW]\xB1j\xEB\xD0\x1EG`f\xB2*\xE3\xC9\x89\x9E'\x84\xEE\xE43\x84\a\xE6\xA2\xF1t\xC2\xF6\x9B4\\Q]\xCFk?\xB1\xEFN,\x9A\t\xDD\x9Dxh&\xAC_\x9FiZ\x02\xCA=\xD6cIh~\xD7\xF7\xABu\x90b\x98X\xC6\xC54I\xB4\x1C\xF8\xB8\xEA\x8AX\x87>\xED\n\xF9:/\xA8Q\xFFv\xB5\xFCv_\xAB\x11_\x8F\xB9:\xA1\xC5\x91%\xD6\xE3\xA1\xBB\xBB\xEB\x9D\xBB{\xA2\x8F\xBB\xBB\n\xFD\xD2\xEEj\x15\xAA\xBA\x11S\xF7\xF7\x19\xB8\xA5\xA5\x9C\xCEM\x96\xC9|\x00\x10\x894\x18(\x18K,\x10J`\tu\xC7%\xCC\xC0R\xE0%\xDC\x18\xC1\v\xB3d\x143,\xB3\x87o\xC7\x8D\xFE|P\xB0\f`\xC5\xDB\xAC\xA1y3\x8B\xE6\x10\n\xF3\xAF\x0F\x94\"\x1E\v\xC7\xAA;\\\xFB\x12\xC4\xD4\n\xCB\xE58\xA3\xDD\v\xF0\x82'\x96\xC9\xBF\x89f\x9F\xF5j\x97B\x059\x8A3\xA3\ec\xF4\xDD\xC3\xEE\xD1;\xA8\x80|\xD8\tF\x15\x81\x03Zi\x17zD\x19\x8F\x1A\xBC\xF1+F\xE4\x85\xF5\x18\xCC}y\xBF\x01\xA1:@\xF4\xF05@\xF4\n\x1C\x1AA\xA1\xD7\x85\xC3\x98\e\xD1\xF7\xC5\x8B\xE7\x04\xFEY\xB5\xDE\xBC\x84\x1F=&\xDE\x8F\xED\x1E\xAC\xBFG\xC7\xC7\xF8\xD1\xC1\x16\xEB\xDA.\xB6\\r\xB0\xE34\xB5\xAC\xFA\b\xD4\xF3{]\xF5d\xF92\f\x1A\xA3i3\x16\t-Le\xAC(\xE0\xB2FvL\x9F\x18\x13\xAE\x00\xEEc\x13R\x81\xE7\xB1f\xAF+\xBF$\x96\xC0Yh\xC4\xA3\x98\xF1g,\x8D:\x850\xD2a\r\xFC2\xEC4\xB81\x7F\xDDA\x82\xBB\x00t6u\xC8\xF2\xF5l@\xBF\xEEA\xD4\x8F\x9Af/\xCC\xCFf\xC5xI\xB1\x00>x\xFB\xEDA2\xAE\xB2\xA5\xDCw\x80\xE4?K)\xF7\x7F\\\xC7\xFD\x15\v\xB6\xD1\xE3\xF3\x85\x82\xED{\x97N\xFFB\x18b\xA4\xE0\xBA\xA4\xA6\x80\x92{\x92\x95\xA9\xE6S\xE7\x03\xB8Z\xCA\x8C\x11\xB9\xFB\x15\xEE\x93\x05\xC1\x16\x92a\x96\x10\xAAq)\xF0(\xE0~N4\xCFXD~,\x95\x82\xD4K!PN\x8C\x1C)\x1C\xC4Z\x12\x9A\xFCZ\x16\x86\x9A\xA0Qp\x0F\xCB\xDD\\^\x11\x19\xA9(\x81\xE99\"\xFF\x96E\xC1w\x10\xA19U\xC0\x16{F\xB8\xE7{\x123T\x04\xD9\x16p\xC6\xE3\t\xD2E\xC0\x82\xE9\xD6\xEC5\xA6\xFB\xE6\x90\xCA\x1DMm\xBC5S\x18\x9E_\xA59\x98M\x80\xE2G\x9A\xE7\x80\xD9Vi\xA32\xF0\xF8B\xA5\x8D\xE9o\x91\xF8\x0Ew\xB1\x1C;j\xFF|\xE4E[\xC4f\xF4\x89\x15f\xA5)a\xA1\xB6I9SQW\xE1\\1\x1F\xF3\x17ra\xEA4\xA5\xC4t\xB6\xC8N~&'\x0EUCLs\xDC\xA7\xAD\x84\x8B\xC4P\xD4k7C\xDA\xA6\x1Eq\x9D\x187\x037i\x10\x00\xE5ojb\xBFx\x80\xBF\r\xD7\xE5vm\xBB\x03_\x0E\xC1A/.\x00\xE1XJ\x95pA5$\x89\xA1\x00\xF11\xF0[\xEA;\xF4\xD0\x8B9\x17\xE6\xDB\x87\x17\xE5\xC1\xC01\x9C\x9B\xF6M\xBBO\x88rf\x14\x9BT}\x92E\x9FM\x96\xF5Ilg\xAA\xE9\xC1p\x94B\x95\xB9\xDE\xA1\xED\xB98\x80\xCFjW\x1A\x0E\x947'\xE2\x1F\xA9\xBBx3P\xD8V\x8E\xB1\x8DZ\xE2w\xC2\xF0hJ\xFBh\xE1\xDB\x8B\xB0\x97\xFCl\v6\vv\xA3\xEB0+\xC9\x7F\xA7\xA4\x1A\xF7\n\x1C-\xF7\x04\x8B\xB0E[\xB3\x93[qj\xA0\xCD\x8A\xE4vBF\xAD\x82\xEEF\xC1:0h\x17c\x8B\xCB\x9Eg8oN=\xCCI\x9D\xB2\xB6\xA9\x87||w\xD4|\x98yk7#\xC0%\xF7u\x04k\x16F\x85,a\xC4\x1A\xE4\x1EM\x0FJ\xB5B6V\xBA\xBCb\xDA1n\xC1v#K\x84T\x9DM\xC2\x15\x18E\xDD\xD2\xC9\xB4\xDF.F\xEAv\x84s\xDB\xA0\xBB\xB0\xE9tj*s\xA6#\x8B\xBB\x96\x18\x84\xED|\x0F\x94\x1C\xE9\xE8}\x17/\xB4L<\xFA\x84\xBC\xDC\x98\xE5\xE6\xCCs)\xE3\\m\xE4\xFA\x8C\xE3\xE9f\xC2\b0\x95\xE8\x93\x84\x93\x92#\xFC\x03\xA0?1\x96\xDB3,\x88\xFCF\xBAD\xC2m\xF3v\x8F\xCA4J\x05\xC2\xBB\xE9\xC2\xE9\xEC\xC3ypP\a\x92vo\x18\xE3(e\xF0\x1De\np\x17\x8F\x18\xA0(\x196\xD9\x13N\x0Fp\x90\x0E\xB1\xD9\x11\xB8\xF9:h\x05c\x19\x96\xF3\x18\xEEV\xCCu\x7F\xF1\xB1\x87\x89\x83>V\x06K\xEC\xEF\xBA\x9A\xC7\x99o\x0F\xB3\xBD\xBF\x05V\xBB\x83\xF9\xB7\xAE\xFE\xF3\xCF\x1F\xEAj\xB1|\x98\x90\xC5\xC3\f\xFE<>\x8EP7\xB7GG\xFF\xEEqB\xE6\xB3\x05\xFCY\xBEu\xE4mY\xE8\x85\xAEW\xEB\x16\f\xB7}\xAA\xB05\r\x94\xDDK\xEA\x80:(\x90\a\xC4\xB6\xB1}ym\xF3\xF2\x02+\e,\x9A\x90\x1E\x13BE|\x94je+\x97\x8C\v\x9E\x95\x19\xB1-'\xFB\x9A\xD0\x8E\x9Ex\xA2\x8F\xABy\xF4\x16\a\xCD\xEE\xCE\x9CC-\x9B\x94\x82\xCD\xDD\x0Emr\x8F\x93\x87\xC93\xB6\n\xB6\x84{\xE6jSdPv\fX@\b\xD7X\x8B\v\xA6 \xBE\xF2\xD5,\xD7\xD6@\xB6\x81\x13s\x059?\xF1\x9A\x14\xFCw|+Y\xE4^\x96\xA0\x1Ak\x0F\xA4j\x16y7\x8FWk\x16n,\xC9\r\x00>\x84b\xFB\x98\xE8\x83\xB3\xFF\xDET\xCD\xEA\xC1\x9C\x7FY\e\x9Bk_e\xC6f\xDB\x82jd\xB2-\xAC/L\x06\x8D\x80\x11\x8A0\xDDg\x06yPM\xA98$\xA2%6\xE8\x11D\xBB}\xB5\x9BY\xF8pw\xA1\xE1\x13N\xF8\x9Ak\xD8\xF0=\xA8\xB7\xB1m)o\n\xF2\x91\xCC\xEC\xEC^\x82\x01\xE2#x\x9B\xAC\x19\x12\xC1N\xAB\r \x16\x17\xA4\x9AO\xA2(\x9A\x04\x0Fb\x06,\xDAg\xA1a\v\xB9y\x88\xBCk[o\x97\v\x94hX\xA2\x10\xE2\xC4\xDE\xF3\xA1\xF8\xAD\xB7\xBEZ\x81\xC0\xD1^\x05{\xC0\xFB\xC7\xBC?\xBC\xAF\xCD\xC7\xEEkvu\xD0\xD2\xE8eN\xEF:\xDBy\x13\xDC\x86\xB6t\xB7;/\x8D\x7F\x8Ac\xDE\x8D\xA1U\x06oef \x04ol\x89\xD8\xD0\xF0\xFF[\x01\xD4\xEC7\x9F~\xFA\xE1\xD3?,q;\xFC?$\xF7\x89\xD2"
11
+
12
+ def self.latex_escape(s)
13
+ s.gsub(/\\|~|[#%&{}$_]/) do |m|
14
+ case m
15
+ when "\\"
16
+ "\\textbackslash{}"
17
+ when "~"
18
+ "\\textasciitilde{}"
19
+ else
20
+ "\\#{m}"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,40 @@
1
+ module SequenceDiagramMixin
2
+ def htmlify(*args)
3
+ res = super
4
+ res = res.gsub(/<pre class="[^"]+? sd"><code>(.+?)<\/code><\/pre>/m, "\\1")
5
+ res
6
+ end
7
+
8
+ def html_syntax_highlight_sd(source)
9
+ lines = source.split("\n")
10
+ metadata = lines.take_while {|l| l.start_with?("%")}
11
+ source = lines[metadata.size..-1].join("\n")
12
+
13
+ metadata_h = {}
14
+ metadata.each do |line|
15
+ if line =~ /^%\s*([^\s=]+)\s*=\s*(.+)$/
16
+ key = $1.to_sym
17
+
18
+ case key
19
+ when :size
20
+ metadata_h[key] = $2
21
+ end
22
+ end
23
+ end
24
+
25
+ begin
26
+ diagram = SequenceDiagram::Diagram.new.parse(source)
27
+ img = diagram.to_png(metadata_h)
28
+ name = "images/diagrams/diagram_#{diagram.uid}.png"
29
+ options[:serializer].serialize(name, img)
30
+
31
+ return "<img src='%s' alt='Sequence diagram' />" % url_for(name)
32
+ rescue SequenceDiagram::ParseError => e
33
+ return "Error: Parsing error: #{h(e.inspect)}"
34
+ rescue => e
35
+ return "Error: #{h(e.backtrace.inspect)}"
36
+ end
37
+ end
38
+ end
39
+
40
+ YARD::Templates::Template.extra_includes << SequenceDiagramMixin
data/lib/yard-sd.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "yard-sd/sequence_diagram_mixin"
2
+ require "yard-sd/sequence_diagram"
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yard-sd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Dominik Honnef
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-01 00:00:00.000000000 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+ description:
16
+ email:
17
+ - dominikh@fork-bomb.org
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - LICENSE
23
+ - README.md
24
+ - Example.md
25
+ - lib/yard-sd/sequence_diagram.rb
26
+ - lib/yard-sd/sequence_diagram_mixin.rb
27
+ - lib/yard-sd/sequence_diagram/participant.rb
28
+ - lib/yard-sd/sequence_diagram/parse_error.rb
29
+ - lib/yard-sd/sequence_diagram/diagram.rb
30
+ - lib/yard-sd.rb
31
+ has_rdoc: true
32
+ homepage:
33
+ licenses: []
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 1.9.1
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project:
52
+ rubygems_version: 1.6.2
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: A YARD plugin for embedding sequence diagrams
56
+ test_files: []