yard-sd 0.0.1

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/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: []