ctioga2 0.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.
Files changed (84) hide show
  1. data/Changelog +25 -1
  2. data/lib/ctioga2/commands/commands.rb +13 -2
  3. data/lib/ctioga2/commands/doc/doc.rb +13 -17
  4. data/lib/ctioga2/commands/doc/documentation-commands.rb +14 -1
  5. data/lib/ctioga2/commands/doc/help.rb +136 -25
  6. data/lib/ctioga2/commands/doc/html.rb +56 -4
  7. data/lib/ctioga2/commands/doc/introspection.rb +45 -9
  8. data/lib/ctioga2/commands/doc/man.rb +7 -5
  9. data/lib/ctioga2/commands/doc/markup.rb +39 -12
  10. data/lib/ctioga2/commands/doc/wordwrap.rb +70 -0
  11. data/lib/ctioga2/commands/general-commands.rb +7 -4
  12. data/lib/ctioga2/commands/general-types.rb +27 -12
  13. data/lib/ctioga2/commands/interpreter.rb +2 -2
  14. data/lib/ctioga2/commands/parsers/command-line.rb +9 -5
  15. data/lib/ctioga2/commands/parsers/file.rb +5 -3
  16. data/lib/ctioga2/commands/type.rb +10 -3
  17. data/lib/ctioga2/commands/variables.rb +2 -2
  18. data/lib/ctioga2/data/backends/backend.rb +17 -15
  19. data/lib/ctioga2/data/backends/backends.rb +2 -2
  20. data/lib/ctioga2/data/backends/backends/gnuplot.rb +20 -5
  21. data/lib/ctioga2/data/backends/backends/math.rb +2 -2
  22. data/lib/ctioga2/data/backends/backends/text.rb +112 -17
  23. data/lib/ctioga2/data/backends/description.rb +10 -11
  24. data/lib/ctioga2/data/datacolumn.rb +73 -14
  25. data/lib/ctioga2/data/dataset.rb +305 -9
  26. data/lib/ctioga2/data/filters.rb +49 -1
  27. data/lib/ctioga2/data/indexed-dtable.rb +137 -0
  28. data/lib/ctioga2/data/point.rb +98 -7
  29. data/lib/ctioga2/data/stack.rb +98 -21
  30. data/lib/ctioga2/graphics/coordinates.rb +19 -2
  31. data/lib/ctioga2/graphics/elements.rb +12 -2
  32. data/lib/ctioga2/graphics/elements/containers.rb +14 -2
  33. data/lib/ctioga2/graphics/elements/contour.rb +67 -0
  34. data/lib/ctioga2/graphics/elements/curve2d.rb +103 -42
  35. data/lib/ctioga2/graphics/elements/element.rb +12 -2
  36. data/lib/ctioga2/graphics/elements/gradient-region.rb +94 -0
  37. data/lib/ctioga2/graphics/elements/parametric2d.rb +172 -0
  38. data/lib/ctioga2/graphics/elements/primitive.rb +37 -21
  39. data/lib/ctioga2/graphics/elements/region.rb +143 -0
  40. data/lib/ctioga2/graphics/elements/subplot.rb +92 -32
  41. data/lib/ctioga2/graphics/elements/tangent.rb +99 -0
  42. data/lib/ctioga2/graphics/elements/xyz-map.rb +126 -0
  43. data/lib/ctioga2/graphics/generator.rb +91 -6
  44. data/lib/ctioga2/graphics/legends.rb +26 -21
  45. data/lib/ctioga2/graphics/legends/area.rb +8 -8
  46. data/lib/ctioga2/graphics/legends/items.rb +5 -5
  47. data/lib/ctioga2/graphics/legends/storage.rb +4 -2
  48. data/lib/ctioga2/graphics/root.rb +24 -2
  49. data/lib/ctioga2/graphics/styles.rb +8 -0
  50. data/lib/ctioga2/graphics/styles/axes.rb +49 -23
  51. data/lib/ctioga2/graphics/styles/base.rb +2 -2
  52. data/lib/ctioga2/graphics/styles/carrays.rb +9 -2
  53. data/lib/ctioga2/graphics/styles/colormap.rb +272 -0
  54. data/lib/ctioga2/graphics/styles/curve.rb +64 -4
  55. data/lib/ctioga2/graphics/styles/drawable.rb +68 -9
  56. data/lib/ctioga2/graphics/styles/errorbar.rb +73 -0
  57. data/lib/ctioga2/graphics/styles/factory.rb +133 -17
  58. data/lib/ctioga2/graphics/styles/gradients.rb +60 -0
  59. data/lib/ctioga2/graphics/styles/location.rb +64 -0
  60. data/lib/ctioga2/graphics/styles/map-axes.rb +164 -0
  61. data/lib/ctioga2/graphics/styles/plot.rb +165 -62
  62. data/lib/ctioga2/graphics/styles/sets.rb +14 -1
  63. data/lib/ctioga2/graphics/styles/texts.rb +44 -34
  64. data/lib/ctioga2/graphics/subplot-commands.rb +94 -6
  65. data/lib/ctioga2/graphics/types.rb +113 -35
  66. data/lib/ctioga2/graphics/types/bijection.rb +3 -3
  67. data/lib/ctioga2/graphics/types/boundaries.rb +120 -1
  68. data/lib/ctioga2/graphics/types/dimensions.rb +8 -1
  69. data/lib/ctioga2/graphics/types/grid.rb +196 -0
  70. data/lib/ctioga2/graphics/types/location.rb +228 -0
  71. data/lib/ctioga2/graphics/types/point.rb +2 -2
  72. data/lib/ctioga2/log.rb +18 -18
  73. data/lib/ctioga2/metabuilder/type.rb +15 -3
  74. data/lib/ctioga2/metabuilder/types.rb +2 -2
  75. data/lib/ctioga2/metabuilder/types/coordinates.rb +13 -1
  76. data/lib/ctioga2/metabuilder/types/data.rb +50 -0
  77. data/lib/ctioga2/metabuilder/types/generic.rb +60 -0
  78. data/lib/ctioga2/metabuilder/types/lists.rb +53 -16
  79. data/lib/ctioga2/metabuilder/types/styles.rb +26 -45
  80. data/lib/ctioga2/plotmaker.rb +91 -20
  81. data/lib/ctioga2/postprocess.rb +8 -8
  82. data/lib/ctioga2/utils.rb +23 -4
  83. metadata +107 -75
  84. data/lib/ctioga2/data/merge.rb +0 -43
data/Changelog CHANGED
@@ -1,6 +1,30 @@
1
+ ctioga2 (0.1)
2
+
3
+ * Setting any set now resets its index
4
+ * Implemented a mechanism for tangents !
5
+ * Added a filter for averaging on successive identical values of X
6
+ * Make the gnuplot backend able to change the number of samples
7
+ required.
8
+ * Implemented error bars
9
+ * Implemented a grid layout (via setup-grid and the grid inset specification)
10
+ * Implemented alternate axes (y2, x2)
11
+ * Neatly colored help with pager(1) using the --help option
12
+ * Filled curves
13
+ * Implemented colored regions
14
+ * Automatic output file name incrementation
15
+ * Neat and easy color gradients for successive curves using the
16
+ --gradient command
17
+ * XYZ maps display
18
+ * Contours on XYZ maps
19
+ * The text backend now supports naming columns
20
+ * Added a --merge-datasets function to merge data sets with common X
21
+ (and more) values...
22
+ * Setup of a tests/ directory containing a whole bunch of visual tests.
23
+
24
+ -- Vincent Fourmond <vincent.fourmond@9online.fr> Mon Jan 31 19:00:00 CET 2011
25
+
1
26
  ctioga2 (0.0)
2
27
 
3
28
  * New version of ctioga, rewritten from scratch, with a whole new structure.
4
29
 
5
30
  -- Vincent Fourmond <vincent.fourmond@9online.fr> Sat Apr 18 13:16:34 CEST 2009
6
-
@@ -17,7 +17,7 @@ require 'ctioga2/commands/groups'
17
17
 
18
18
  module CTioga2
19
19
 
20
- Version::register_svn_info('$Revision: 16 $', '$Date: 2009-04-28 00:50:08 +0200 (Tue, 28 Apr 2009) $')
20
+ Version::register_svn_info('$Revision: 144 $', '$Date: 2010-04-06 13:31:39 +0200 (Tue, 06 Apr 2010) $')
21
21
 
22
22
  module Commands
23
23
 
@@ -32,6 +32,13 @@ module CTioga2
32
32
  end
33
33
 
34
34
  # One of the commands that can be used.
35
+ #
36
+ # \todo Write a Shortcut command that would simply be a shortcut
37
+ # for other things. Possibly taking arguments ? It could take a
38
+ # description, though that wouldn't be necessary.
39
+ #
40
+ # \todo Use this Shortcut to write DeprecatedShortcut for old
41
+ # ctioga options.
35
42
  class Command
36
43
 
37
44
  # The name of the command, ie how to call it in a commands file
@@ -219,7 +226,11 @@ module CTioga2
219
226
 
220
227
  # Whether the Command accepts the named _option_.
221
228
  #
222
- # TODO: maybe convert everything to lowercase ?????
229
+ # \todo Several conversions could be used, to facilitate the
230
+ # writing of options:
231
+ #
232
+ # * convert everything to lowercase .
233
+ # * ignore the difference between _ and - (a bit delicate).
223
234
  def has_option?(option)
224
235
  return @optional_arguments.key? option
225
236
  end
@@ -17,7 +17,7 @@ require 'ctioga2/commands/doc/markup'
17
17
 
18
18
  module CTioga2
19
19
 
20
- Version::register_svn_info('$Revision: 61 $', '$Date: 2009-05-29 01:00:56 +0200 (Fri, 29 May 2009) $')
20
+ Version::register_svn_info('$Revision: 138 $', '$Date: 2010-01-21 22:39:55 +0100 (Thu, 21 Jan 2010) $')
21
21
 
22
22
  module Commands
23
23
 
@@ -25,12 +25,6 @@ module CTioga2
25
25
  module Documentation
26
26
 
27
27
  # The base class for all documentation.
28
- #
29
- # TODO: create a class that would parse a description from a
30
- # group/command/type and understand some 'markup': lists, links
31
- # to other commands/groups/types, and maybe bold or things of
32
- # this kind. Then the various outputs should have a means to
33
- # parse this.
34
28
  class Doc
35
29
 
36
30
  # The hash containing all the commands, as returned
@@ -45,25 +39,23 @@ module CTioga2
45
39
  # by Interpreter::commands.
46
40
  attr_accessor :types
47
41
 
42
+ # The hash containing all the backends, as returned by
43
+ # Data::Backends::Backend::list_backends
44
+ attr_accessor :backends
45
+
48
46
  # Wether or not to ignore blacklisted commands
49
47
  attr_accessor :ignore_blacklisted
50
48
 
51
- # The CommandLineHelp object in charge of displaying
52
- # information about command-line
53
- attr_accessor :command_line_help
54
-
55
-
56
49
  # Create a Doc object caring about the current state of
57
50
  # registered commands and such.
58
51
  def initialize
59
52
  @commands = Interpreter::commands
60
53
  @groups = Interpreter::groups
61
54
  @types = Interpreter::types
55
+ @backends = Data::Backends::Backend::list_backends
62
56
 
63
57
  @ignore_blacklisted = ! (ENV.key?("CT2_DEV") &&
64
58
  ! ENV["CT2_DEV"].empty?)
65
-
66
- @command_line_help = CommandLineHelp.new
67
59
  end
68
60
 
69
61
  # Returns a [ cmds, groups ] hash containing the list of
@@ -77,7 +69,11 @@ module CTioga2
77
69
  elsif ! b
78
70
  -1
79
71
  else
80
- a.priority <=> b.priority
72
+ if a.priority == b.priority
73
+ a.name <=> b.name
74
+ else
75
+ a.priority <=> b.priority
76
+ end
81
77
  end
82
78
  end
83
79
  if @ignore_blacklisted
@@ -87,8 +83,8 @@ module CTioga2
87
83
  end
88
84
 
89
85
  # Display command-line help.
90
- def display_command_line_help
91
- @command_line_help.
86
+ def display_command_line_help(options)
87
+ CommandLineHelp.new(options).
92
88
  print_commandline_options(*self.documented_commands)
93
89
  end
94
90
 
@@ -20,7 +20,7 @@ require 'ctioga2/commands/doc/markup'
20
20
 
21
21
  module CTioga2
22
22
 
23
- Version::register_svn_info('$Revision: 77 $', '$Date: 2009-06-05 00:20:49 +0200 (Fri, 05 Jun 2009) $')
23
+ Version::register_svn_info('$Revision: 106 $', '$Date: 2009-10-21 01:31:34 +0200 (Wed, 21 Oct 2009) $')
24
24
 
25
25
  module Commands
26
26
 
@@ -74,6 +74,19 @@ EOH
74
74
  WriteHTMLTypes.describe("HTML documentation for types",
75
75
  <<EOH, DocumentationGenerationGroup)
76
76
  Prints the HTML documentation for all types.
77
+ EOH
78
+
79
+ WriteHTMLBackends =
80
+ Cmd.new("write-html-backends", nil, "--write-html-backends",
81
+ []) do |plotmaker|
82
+ html = HTML.new(plotmaker.interpreter.doc)
83
+ html.write_backends()
84
+ end
85
+
86
+ WriteHTMLBackends.describe("HTML documentation for backends",
87
+ <<EOH, DocumentationGenerationGroup)
88
+ Writes the documentation for all backends, in one monolithic HTML page
89
+ for now (but this would be a good idea to change).
77
90
  EOH
78
91
 
79
92
  WriteHTMLCommandLineOptions =
@@ -14,10 +14,11 @@
14
14
  require 'ctioga2/utils'
15
15
  require 'ctioga2/commands/commands'
16
16
  require 'ctioga2/commands/parsers/command-line'
17
+ require 'ctioga2/commands/doc/wordwrap'
17
18
 
18
19
  module CTioga2
19
20
 
20
- Version::register_svn_info('$Revision: 34 $', '$Date: 2009-05-03 20:22:29 +0200 (Sun, 03 May 2009) $')
21
+ Version::register_svn_info('$Revision: 132 $', '$Date: 2010-01-14 23:18:19 +0100 (Thu, 14 Jan 2010) $')
21
22
 
22
23
  module Commands
23
24
 
@@ -29,52 +30,138 @@ module CTioga2
29
30
  # How much space to leave for the options ?
30
31
  attr_accessor :options_column_width
31
32
 
32
- def initialize
33
+ # How many columns do we have at all ?
34
+ attr_accessor :total_width
35
+
36
+ # Whether output has (moderate) terminal capabilities
37
+ attr_accessor :to_tty
38
+
39
+ # Whether we should send output to pager if output has
40
+ # terminal support.
41
+ attr_accessor :to_pager
42
+
43
+ # Styles, ie a hash 'object' (option, argument...) => ANSI
44
+ # color code.
45
+ attr_accessor :styles
46
+
47
+ # Color output ?
48
+ attr_accessor :color
49
+
50
+ # The default value for the #styles attribute.
51
+ DefaultStyles = {
52
+ 'switch' => "01",
53
+ 'title' => "01;04",
54
+ 'arguments' => '32',
55
+ 'options' => '34'
56
+ }
57
+
58
+ # Creates an object to display command-line help. Available
59
+ # values for the options are given by the hash
60
+ # CommandLineHelpOptions. Their meaning is:
61
+ #
62
+ # * 'pager': disables or enables the use of a pager when
63
+ # sending output to a terminal
64
+ def initialize(options)
33
65
  @options_column_width = 20
66
+ @to_pager = if options.key? 'pager'
67
+ options['pager']
68
+ else
69
+ true
70
+ end
71
+
72
+ @styles = DefaultStyles.dup
73
+ @color = true
34
74
  end
35
75
 
36
76
  # Prints short help text suitable for a --help option about
37
77
  # available commands, by groups (ungrouped last). It takes a
38
78
  # list of all commands (_cmds_) and the list of _groups_ to
39
79
  # display.
40
- #
41
- # TODO: word splitting.
42
- #
43
- # TODO: why not try color, too ;-) ???
80
+ #
81
+ # \todo maybe the part about sending to the pager should be
82
+ # factorized into a neat utility class ?
44
83
  def print_commandline_options(cmds, groups)
84
+ @to_tty = false
85
+ if STDOUT.tty?
86
+ begin
87
+ require 'curses'
88
+ Curses.init_screen
89
+ @total_width = Curses.cols
90
+ Curses.close_screen
91
+ @to_tty = true
92
+ rescue
93
+ end
94
+ end
95
+ @total_width ||= 80 # 80 by default
96
+
97
+ # Disable color output if not a to a terminal
98
+ if ! @to_tty
99
+ @color = false
100
+ end
101
+
102
+ if @to_tty and @to_pager
103
+ # We pass -R as default value...
104
+ ENV['LESS'] = 'R'
105
+ output = IO::popen("pager", "w")
106
+ pager = true
107
+ else
108
+ output = $stdout
109
+ pager = false
110
+ end
111
+
45
112
  for group in groups
46
- puts unless group == groups[0]
113
+ output.puts unless group == groups[0]
47
114
  name = (group && group.name) || "Ungrouped commands"
48
115
  if group && group.blacklisted
49
116
  name << " (blacklisted)"
50
117
  end
51
- puts name
118
+ output.puts style(name, 'title')
52
119
  for cmd in cmds[group].sort {|a,b|
53
120
  a.long_option <=> b.long_option
54
121
  }
55
122
 
56
- strings = cmd.option_strings
57
- puts "#{leading_spaces}%2s%1s %-#{@options_column_width}s%s" %
58
- [
59
- strings[0], (strings[0] ? "," : " "),
60
- strings[1],
61
- if strings[1].size >= @options_column_width
62
- "\n#{total_leading_spaces}#{strings[2]}"
63
- else
64
- strings[2]
65
- end
66
- ]
67
- if cmd.has_options?
68
- puts "#{total_leading_spaces} options: %s" %
69
- cmd.optional_arguments.keys.sort.map {|x| "/#{x}"}.join(' ')
70
- end
123
+ output.puts format_one_entry(cmd)
71
124
  end
72
125
  end
73
-
126
+ output.close
74
127
  end
75
128
 
76
129
  protected
77
130
 
131
+ # Formats one entry of the commands
132
+ def format_one_entry(cmd)
133
+ sh, long, desc = cmd.option_strings
134
+
135
+ str = "#{leading_spaces}%2s%1s %-#{@options_column_width}s" %
136
+ [ sh, (sh ? "," : " "), long]
137
+
138
+ size = @total_width - total_leading_spaces.size
139
+
140
+ # Do the coloring: we need to parse option string first
141
+ if str =~ /(.*--\S+)(.*)/
142
+ switch = $1
143
+ args = $2
144
+ str = "#{style(switch,'switch')}#{style(args,'arguments')}"
145
+ end
146
+
147
+ # Now, add the description.
148
+ desc_lines = WordWrapper.wrap(desc, size)
149
+ if long.size >= @options_column_width
150
+ str += "\n#{total_leading_spaces}"
151
+ end
152
+ str += desc_lines.join("\n#{total_leading_spaces}")
153
+
154
+ if cmd.has_options?
155
+ op_start = ' options: '
156
+ options = cmd.optional_arguments.
157
+ keys.sort.map { |x| "/#{x}"}.join(' ')
158
+ opts_lines = WordWrapper.wrap(options, size - op_start.size)
159
+ str += "\n#{total_leading_spaces}#{style(op_start,'switch')}" +
160
+ style(opts_lines.join("\n#{total_leading_spaces}#{' ' * op_start.size}"), 'options')
161
+ end
162
+ return str
163
+ end
164
+
78
165
  # Leading spaces to align a string with the other option texts
79
166
  def total_leading_spaces
80
167
  return "#{leading_spaces}#{" " *(@options_column_width + 4)}"
@@ -85,7 +172,31 @@ module CTioga2
85
172
  def leading_spaces
86
173
  return " "
87
174
  end
88
-
175
+
176
+ # Colorizes some text with the given ANSI code.
177
+ #
178
+ # Word wrapping should be used *before*, as it will not work
179
+ # after.
180
+ def colorize(str, code)
181
+ # We split into lines, as I'm unsure color status is kept
182
+ # across lines
183
+ return str.split("\n").map {|s|
184
+ "\e[#{code}m#{s}\e[0m"
185
+ }.join("\n")
186
+ end
187
+
188
+ # Changes the style of the object.
189
+ def style(str, what)
190
+ if ! @color
191
+ return str
192
+ end
193
+ if @styles[what]
194
+ return colorize(str, @styles[what])
195
+ else
196
+ return str
197
+ end
198
+ end
199
+
89
200
  end
90
201
 
91
202
  end
@@ -16,7 +16,7 @@ require 'ctioga2/commands/commands'
16
16
 
17
17
  module CTioga2
18
18
 
19
- Version::register_svn_info('$Revision: 77 $', '$Date: 2009-06-05 00:20:49 +0200 (Fri, 05 Jun 2009) $')
19
+ Version::register_svn_info('$Revision: 216 $', '$Date: 2010-12-31 16:18:17 +0100 (Fri, 31 Dec 2010) $')
20
20
 
21
21
  module Commands
22
22
 
@@ -29,9 +29,16 @@ module CTioga2
29
29
  # The Doc object the HTML class should document
30
30
  attr_accessor :doc
31
31
 
32
- # The base URL for file where types are documented.
32
+ # The base URL for the file where the types are documented.
33
33
  attr_accessor :types_url
34
34
 
35
+ # The base URL for the file where the backends are documented.
36
+ #
37
+ # \todo maybe this should be turned into a directory, and each
38
+ # file would document a backend on its own ? That would make
39
+ # sense, but that would be rather difficult, I have to admit.
40
+ attr_accessor :backends_url
41
+
35
42
  # The base URL for file where commands and groups are
36
43
  # documented.
37
44
  attr_accessor :commands_url
@@ -40,6 +47,7 @@ module CTioga2
40
47
  @doc = doc
41
48
  @types_url = "types.html"
42
49
  @commands_url = "commands.html"
50
+ @backends_url = "backends.html"
43
51
  end
44
52
 
45
53
  # Ouputs HTML code to document all groups and commands
@@ -125,6 +133,34 @@ module CTioga2
125
133
  end
126
134
 
127
135
 
136
+ # Ouputs HTML code to all backends
137
+ def write_backends(out = STDOUT)
138
+ backends = @doc.backends.sort.map { |d| d[1]}
139
+
140
+
141
+ out.puts "<div class='quick-jump'>"
142
+ out.puts "Quick jump to a specific backend:\n"
143
+ out.puts "<ul>\n"
144
+ for b in backends
145
+ out.puts "<li><a href='#backend-#{b.name}'>#{b.name}</a></li>\n"
146
+ end
147
+ out.puts "</ul>\n"
148
+ out.puts "</div>"
149
+
150
+ for b in backends
151
+ out.puts
152
+ out.puts "<h3 id='backend-#{b.name}' class='backend'><code>#{b.name}</code>: #{b.long_name}</h3>\n"
153
+ out.puts markup_to_html(b.description)
154
+ out.puts
155
+ for param in b.param_list
156
+ out.puts "<h4 id='backend-#{b.name}-#{param.name}'>Parameter: #{param.name}</h4>"
157
+ out.puts "<p><code>/#{param.name}=<a href='#{@types_url}#type-#{param.type.name}'>#{param.type.name}</a></p>"
158
+ out.puts markup_to_html(param.description)
159
+ end
160
+ end
161
+ end
162
+
163
+
128
164
  protected
129
165
 
130
166
  # The string that represents a full command
@@ -182,7 +218,7 @@ module CTioga2
182
218
  # equivalent in HTML format. Alternativelely, it can take a
183
219
  # String and feed it to MarkedUpText.
184
220
  #
185
- # TODO: escape correctly the produced HTML code...
221
+ # \todo escape correctly the produced HTML code...
186
222
  def markup_to_html(items)
187
223
  if items.is_a? String
188
224
  mup = MarkedUpText.new(@doc, items)
@@ -192,7 +228,19 @@ module CTioga2
192
228
  for it in items
193
229
  case it
194
230
  when MarkedUpText::MarkupText
195
- str << it.to_s
231
+ el = nil
232
+ case it.kind
233
+ when :code
234
+ el = "code"
235
+ end
236
+ if el
237
+ prefix = "<#{el}>"
238
+ suffix = "</#{el}>"
239
+ else
240
+ prefix = ""
241
+ suffix = ""
242
+ end
243
+ str << "#{prefix}#{it.to_s}#{suffix}"
196
244
  when MarkedUpText::MarkupLink
197
245
  case it.target
198
246
  when Command
@@ -201,6 +249,10 @@ module CTioga2
201
249
  link = "#{@commands_url}#group-#{it.target.id}"
202
250
  when CommandType
203
251
  link = "#{@types_url}#type-#{it.target.name}"
252
+ when Data::Backends::BackendDescription
253
+ link = "#{@backends_url}#backend-#{it.target.name}"
254
+ when String # plain URL target
255
+ link = "#{it.target}"
204
256
  else
205
257
  raise "The link target should be either a group, a command or a type, but is a #{it.target.class}"
206
258
  end