<> == The Basics == === Be Consistent === The important reason for having a style guide is to be consistent. This style guide can't cover every possible thing you may need to write a wiki page about, so just remember to be consistent in your own documentation. === If you invent a new style, remember that it has to be applied everywhere === There will be times where of a new way of formatting something that improves its readability, or you have to come up with some standard way of presenting something new. Remember though: if you come up with a new way of formatting a particular item, that formatting has to be applied to all occurrences of that item throughout the wiki (and documented here). === Common Names === Capitalization: the following are capitalized * [[Master]] * [[Parameter Server]] The following are not capitalized: * [[tf]] === Heading Levels === ''Pages'': Start with heading-level 2 (i.e. `==`). Heading 1 is reserved for the actual page title, which is automatically used ''Heading level 5'': Any heading level beyond level 4 gets more difficult to interpret. Consider other ways of formatting content. For an example of this, see Sample 1 and Sample 2 below. ----- === Sample 1 === ==== BLTs ==== BLTs consist of three ingredients, which are discussed below. ====== Bacon ====== Bacon is delicious. ====== Lettuce ====== Lettuce is to make it healthy. ====== Tomato ====== Tomatoes bring out the red in the bacon. ==== Grilled Cheese ==== Now I will talk about my other favorite sandwich, the Grilled Cheese. ----- === Sample 2 === ==== BLTs ==== BLTs consist of three ingredients, which are discussed below. ''Bacon'' Bacon is delicious. ''Lettuce'' Lettuce is to make it healthy. ''Tomato'' Tomatoes bring out the red in the bacon. ==== Grilled Cheese ==== Now I will talk about my other favorite sandwich, the Grilled Cheese. ----- == Code == === Code Style Guides === There are existing code style guides for ROS packages: * [[PyStyleGuide|Python Style Guide]] * [[CppStyleGuide|C++ Style Guide]] * [[JavaScriptStyleGuide|JavaScript Style Guide]] === Code API === Code API is generally done in Doxygen, Epydoc, or Sphinx. This documentation is automatically linked from the Wiki page for a ROS [[Packages|Package]]. While your wiki documentation can refer to the Code API, the comprehensive documentation should be done by the automatic generation capabilities of the language you are using. See [[rosdoc]] for more information. === Code (e.g. C++ classes, Python methods, etc...) === Example: ''Remember to invoke `rospy.is_shutdown()` regularly...'' All code should be written in `monospace` using the backtick operator, e.g. {{{`ros::Publisher`}}}. All methods should be clarified as `method_calls()` -- the parens operators make it very clear what you are referring to. === C++ class::Names === When referring to a C++ class, make it clear by including the namespace, e.g. `my_package::Class`, not `Class`. You should only use C++ class names in your documentation when the documentation specifically applies to C++ classes. In other words, in general, do not use C++-style syntax when referring to: * Message types (e.g. `sensor_msgs::LaserScan` vs. <>) * ROS concepts (e.g. `ros::Publisher` vs. publisher) === Python class names === The same rules apply as with C++ class names: include the module name when referring to a class, e.g. `rospy.Publisher`, so that it is clear that you are referring to the Python entity. == ROS == === ROS Names === Example: ''Node `foo` publishes messages to the `bar` topic''. ROS names are `monospace`. This includes [[tf]] frames, parameter names, service names, topic names, etc... == ROS Message Types and Service Types == Example: ''The node receives <> messages...'' NOTE: be careful to distinguish between ROS [[Messages]], i.e. the data, vs. ROS [[msg|Message types]], the format of the data. When referring to message types, you should always use the `MsgLink` macro, e.g. {{{ <> }}} produces the link, <>. Similarly, use the `SrvLink` macro for services, e.g.: {{{ <> }}} Look here for macros: [[WikiMacros]] === ROS Concepts === Example: ''When working with ROS [[Topics|topics]]...''. When referring to ROS concepts like [[Topics|topics]], [[Services|services]], and [[Packages]], it is generally good form to indicate to the reader that you are talking about the ROS-meaning of these terms. When you '''introduce''' these concepts in your text, use a "ROS" prefix . After you have introduced the concept, you can use it without the prefix (unless you need to disambiguate). The reason we do this is that concepts like "package" have meaning in ROS, Java, Debian, Python, and many other places. This immediately clarifies to a reader who may have entered at your page. === ROS API === Each ROS [[Nodes|node]] in your documentation needs to have ROS API documentation. To help make this consistent and allow us to make some stylistic changes in the future, we do this using the [[CS/NodeAPI]] clearsilver template. Clearsilver uses a hierarchical data format called [[http://www.clearsilver.net/docs/man_hdf.hdf|HDF]]. Your node API ends up being specified in a consistent HDF representation inside a code block. The code block will always start with: {{{{{ {{{ #!clearsilver CS/NodeAPI }}}}} In the event of a single node, you should specify HDF strings for the `name` and `description` of the node. Additionally, the following sections can optionally be specified * `sub` - topics the node subscribes to * Expects sub-fields: `name`, `type`, `desc` * `pub` - topics the node publishes * Expects sub-fields: `name`, `type`, `desc` * `srv` - services the node provides * Expects sub-fields: `name`, `type`, `desc` * `srv_called` - services the node calls * Expects sub-fields: `name`, `type`, `desc` * `param` - parameters the node checks * Expects sub-fields: `name`, `type`, `desc`, `default` * `param_set` - parameters the node sets * Expects sub-fields: `name`, `type`, `desc`, `default` * `req_tf` - tf frames the node expects * Expects sub-fields: `from`, `to`, `desc` * `prov_tf` - tf frames the node provides * Expects sub-fields: `from`, `to`, `desc` * `goal` - action goal the node provides * Expects sub-fields: `name`, `type`, `desc` * `feedback` - action feedback the node provides * Expects sub-fields: `name`, `type`, `desc` * `result` - action result the node provides * Expects sub-fields: `name`, `type`, `desc` * `act_called` - actions the node calls * Expects sub-fields: `name`, `type`, `desc` As a minimal example, the code: {{{{ {{{ #!clearsilver CS/NodeAPI name = my_node desc = does something interesting sub { 0.name = topic_name1 0.type = std_msgs/String 0.desc = it publishes this topic 1.name = topic_name2 1.type = std_msgs/String 1.desc = it also publishes to this topic } }}} }}}} will produce the following: ----- {{{ #!clearsilver CS/NodeAPI name = my_node desc = does something interesting sub { 0.name = topic_name1 0.type = std_msgs/String 0.desc = it publishes this topic 1.name = topic_name2 1.type = std_msgs/String 1.desc = it also publishes to this topic } }}} ----- A full specification of all the possible sub-sections would look like: {{{{ {{{ #!clearsilver CS/NodeAPI name = node_name desc = does... sub { 0.name = foo/topic_name1 0.type = std_msgs/String 0.desc = topic_desciption 1 } pub { 0.name = foo/topic_name 0.type = std_msgs/String 0.desc = topic description, including any important rate information } srv { 0.name = foo/service_name 0.type = nav_msgs/GetMap 0.desc = service description } srv_called { 0.name = foo/service_name 0.type = nav_msgs/GetMap 0.desc = service description } param { 0.name = ~parameter_name 0.type = type 0.desc = parameter description 0.default = value } param_set { 0.name = ~parameter_name 0.type = type 0.desc = parameter description 0.default = value } req_tf { 0.from = foo 0.to = bar 0.desc = description of transform } prov_tf { 0.from = baz 0.to = mumble 0.desc = description of transform } }}} }}}} And produce: ----- {{{ #!clearsilver CS/NodeAPI name = node_name desc = does... sub { 0.name = foo/topic_name1 0.type = std_msgs/String 0.desc = topic_desciption 1 } pub { 0.name = foo/topic_name 0.type = std_msgs/String 0.desc = topic description, including any important rate information } srv { 0.name = foo/service_name 0.type = nav_msgs/GetMap 0.desc = service description } srv_called { 0.name = foo/service_name 0.type = nav_msgs/GetMap 0.desc = service description } param { 0.name = ~parameter_name 0.type = type 0.desc = parameter description 0.default = value } param_set { 0.name = ~parameter_name 0.type = type 0.desc = parameter description 0.default = value } req_tf { 0.from = foo 0.to = bar 0.desc = description of transform } prov_tf { 0.from = baz 0.to = mumble 0.desc = description of transform } }}} ----- Additionally, these variables can be pushed down into a variable called `node`, or, in the event of multiple nodes, an array, specified in HDF by `node.0`, `node.1`, etc. {{{{ == Nodes == {{{ #!clearsilver CS/NodeAPI node.0 { name = One node desc = ... } node.1 { name = Another Node desc = ... } }}} }}}} Which produces: ----- == Nodes == {{{ #!clearsilver CS/NodeAPI node.0 { name = One node desc = ... } node.1 { name = Another Node desc = ... } }}} ----- Occasionally, it may be necessary to specify a list of one of the sub-sections without a node: {{{{ {{{ #!clearsilver CS/NodeAPI pub { 0.name = foo/topic_name1 0.type = std_msgs/String 0.desc = topic_desciption 1 } }}} }}}} Or, to break up a sub-section into multiple groupings: {{{{ {{{ #!clearsilver CS/NodeAPI param { group.0 { 0.name = ~parameter_name 0.type = type 0.desc = parameter description 0.default = value } group.1 { name = DEPRECATED desc = description of parameters which should no longer be used. 0.name = ~old_parameter_name 0.type = type 0.desc = old parameter description 0.default = value } }}} }}}} Which ends up looking like: {{{ #!clearsilver CS/NodeAPI param { group.0 { 0.name = ~parameter_name 0.type = type 0.desc = parameter description 0.default = value } group.1 { name = DEPRECATED desc = description of parameters which should no longer be used. 0.name = ~old_parameter_name 0.type = type 0.desc = old parameter description 0.default = value } }}} If you have a description that is long or requires multi-line formatting, HDF's [[http://en.wikipedia.org/wiki/Here_document|heredoc]] syntax is useful: {{{{ {{{ #!clearsilver CS/NodeAPI #!clearsilver CS/NodeAPI param { 0.name = charles 0.type = string 0.default = dickens 0.desc << EOM It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to heaven, we were all going direct the other way - in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only. EOM } }}} }}}} Which looks like: {{{ #!clearsilver CS/NodeAPI param { 0.name = charles 0.type = string 0.default = dickens 0.desc << EOM It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to heaven, we were all going direct the other way - in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only. EOM } }}} The heading for a sub-section can be suppressed by `no_header=True`. One common use case: when maintaining a node's documentation over multiple ROS distros with the [[WikiMacros#Version|Version]] macro, some parameters (topics, etc) may only exist in certain distros. You could separate them as follows: {{{{{ <> {{{ #!clearsilver CS/NodeAPI param { 0.name = common_parameter 0.type = string 0.default = foo 0.desc = This parameter present in all versions. }}} {{{{#!wiki version indigo jade {{{ #!clearsilver CS/NodeAPI param { no_header=True 1.name = new_parameter 1.type = string 1.default = bar 1.desc = This parameter added in ROS Jade. }}} }}}} }}}}} Which looks like: <> {{{ #!clearsilver CS/NodeAPI param { 0.name = common_parameter 0.type = string 0.default = foo 0.desc = This parameter present in all versions. }}} {{{{#!wiki version indigo jade {{{ #!clearsilver CS/NodeAPI param { no_header=True 1.name = new_parameter 1.type = string 1.default = bar 1.desc = This parameter added in ROS Indigo. }}} }}}} For other examples of this, see the [[gmapping]] and [[image_transport]] packages. == Package/Stack Documentation == === Linking to Trac Tickets === The `TracLink` macro lets you link into Trac tickets so that visitors can easily file tickets, e.g.: {{{ <> }}} Expands to: <> === Thirdparty Packages === Thirdparty ROS [[Packages]] need documentation too. It is customary to include a "External Documentation" section, like the one below, so that users can quickly see that they should go elsewhere for proper documentation. {{{ === External Documentation === This is a third party package with [[http://www.continuousphysics.com/Bullet/BulletFull/index.html|external documentation]]. }}} == Files == === Filenames === Filenames are `monospace`. In general, it's a good idea to specify filenames relative to the package they are in, e.g. `roslaunch/example.launch`. == Using external editors == If you do any significant amount of wiki editing, you will grow to hate the in-browser text box. Do yourself a favor and use your favorite text editor instead. The simplest approach is to copy the text box content to your editor, make your changes, and copy back. Depending on your preferred browser, you may be able to streamline this: * Firefox: [[https://addons.mozilla.org/en-US/firefox/addon/its-all-text/| It's All Text!]] works nicely. * Chrome: No direct equivalent, but see [[http://superuser.com/questions/261689/its-all-text-for-chrome]] for suggestions. === Emacs === Follow the instructions at [[http://moinmo.in/EmacsForMoinMoin]] to install the handy !MoinMoin editing mode. Make sure to install both `moinmoin-mode.el` and `screen-lines.el`. If using ''It's All Text!'', add `.wiki` in the “File Extensions” list in the preferences setting dialog. Then you can right-click the edit button and choose “Edit as '.wiki'”. === Vim === See [[http://moinmo.in/VimHighlighting]].