Commit 497907dd authored by scott snyder's avatar scott snyder
Browse files

Add twiki export. A few minor tweaks to the text. Bump version to 0.6.

parent eebe6de4
;;; ox-twiki.el --- org Twiki and Foswiki export
;; Copyright (C) 2013, 2016 Derek Feichtinger
;; Author: Derek Feichtinger <>
;; Keywords: org
;; Homepage:
;; Package-Requires: ((org "8") (cl-lib "0.5"))
;; Version: 0.1.20160306
;; Modified to support coding-rules twiki export (sss).
;; This file is not part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <>.
;;; Commentary:
;; ox-twiki.el lets you convert Org files to twiki buffers
;; using the ox.el export engine.
;; Put this file into your load-path and the following into your ~/.emacs:
;; (require 'ox-twiki)
;; Export Org files to twiki:
;; M-x org-twiki-export-as-twiki RET
;; You can set the following options inside of the document:
;; controls whether code blocks are exported as %CODE{}% twiki
;; blocks (requires the beautify twiki plugin).
;; originally based on ox-confluence by Sébastien Delafond
;;; Code:
(require 'ox)
(require 'ox-ascii)
(require 'cl-lib)
;; Define the backend itself
(org-export-define-derived-backend 'twiki 'ascii
:translate-alist '((bold . org-twiki-bold)
(example-block . org-twiki-example-block)
(fixed-width . org-twiki-fixed-width)
(footnote-definition . org-twiki-empty)
(footnote-reference . org-twiki-footnote-reference)
(headline . org-twiki-headline)
(inner-template . org-twiki-inner-template)
(italic . org-twiki-italic)
(item . org-twiki-item)
(link . org-twiki-link)
(paragraph . org-twiki-paragraph)
;; (plain-list . org-twiki-plain-list)
(section . org-twiki-section)
(src-block . org-twiki-src-block)
(strike-through . org-twiki-strike-through)
(table . org-twiki-table)
(table-cell . org-twiki-table-cell)
(table-row . org-twiki-table-row)
(target . org-twiki-target)
(template . org-twiki-template)
(underline . org-twiki-underline)
(verbatim . org-twiki-verbatim))
;; :menu-entry '(?w 1
;; ((?f "As Foswiki/Twiki buffer" org-twiki-export-as-twiki)))
'((:twiki-code-beautify "TWIKI_CODE_BEAUTIFY" nil org-twiki-code-beautify t)
(:twiki-header "TWIKI_HEADER" nil nil newline)
;;; User Configuration Variables
(defgroup org-export-twiki nil
"Options for exporting Org mode files to Twiki."
:tag "Org Export Twiki"
:group 'org-export)
(defcustom org-twiki-inline-image-rules
'(("file" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'"))
"Rules characterizing image files that can be inlined into a Twiki page.
A rule consists of an association list whose key is the type of
link to consider, and value is a regexp that will be matched
against link's path."
:group 'org-export-twiki
:version "24.3.1"
:package-version '(Org . "8.2.3")
:type '(alist :key-type (string :tag "Type")
:value-type (regexp :tag "Path")))
(defcustom org-twiki-code-mappings
'(("sh" . "bash")
("c++" . "cpp")
("c" . "cpp")
("css" . "css")
("java" . "java")
("js" . "javascript")
("perl" . "perl")
("python" . "python"))
"Mappings for translating babel blocks into twiki beautifier code blocks."
:group 'org-export-twiki
:version "24.3.1"
:package-version '(Org . "8.2.3")
:type '(alist :key-type (string :tag "org babel")
:value-type (string :tag "twiki export"))
(defcustom org-twiki-code-beautify nil
"If true, babel exports will be exported as %CODE% blocks.
This requires the twiki beautify plugin"
:group 'org-export-twiki
:version "24.3.1"
:package-version '(Org . "8.2.3")
:type 'boolean
;; debugging helpers
(defun org-enclose-element-property (plist property tag)
(format "<%s>%s</%s>" tag (org-element-property property plist) tag))
(defun plist-get-keys (pl)
(let (result)
(cl-loop for (key val) on pl by #'cddr
do (push key result))
;; All the functions we use
(defun org-twiki-bold (bold contents info)
(format "*%s*" contents))
(defun org-twiki-empty (empty contents info)
"Return an empty string."
(defun org-twiki-plain-list (plain-list contents info)
(defun org-twiki-item (item contents info)
(let* ((beg (org-element-property :begin item))
(struct (org-element-property :structure item))
(itemstruct (assoc beg struct))
(parent (org-element-property :parent item))
(ltype (org-element-property :type parent))
(indices (org-list-get-item-number
(org-element-property :begin item)
(org-list-prevs-alist struct)
(org-list-parents-alist struct))))
(make-string (* 3 (length indices)) ? )
(if (eq ltype 'ordered) "1. " "* ")
(case (org-element-property :checkbox item)
(on "%ICON{checked}% ")
(off "%ICON{unchecked}% ")
(trans "%ICON{unchecked}% "))
(defun org-twiki-example-block (example-block contents info)
(format "\n<verbatim>\n%s</verbatim>\n"
(org-export-format-code-default example-block info))
(defun org-twiki-italic (italic contents info)
(format "_%s_" contents))
(defun org-twiki-fixed-width (fixed-width contents info)
"A fixed-width line starts with a colon character and a
whitespace or an end of line. Fixed width areas can contain any
number of consecutive fixed-width lines."
(format "\n<verbatim>\n%s</verbatim>\n"
(org-element-property :value fixed-width))
(defun org-twiki-verbatim (verbatim contents info)
"Transcode VERBATIM from Org to Twiki.
CONTENTS is nil. INFO is a plist holding contextual
lines using the =string= markup end up here"
(format "=%s=" (org-element-property :value verbatim)))
(defun org-twiki-headline (headline contents info)
(let ((low-level-rank (org-export-low-level-p headline info))
(text (org-export-data (org-element-property :title headline)
(level (org-export-get-relative-level headline info)))
;; Else: Standard headline.
(format "---%s %s\n%s" (make-string level ?+) text
(if (org-string-nw-p contents) contents
(defun org-twiki-link (link desc info)
"Transcode a LINK object from Org to Twiki.
DESC is the description part of the link, or the empty string.
INFO is a plist holding contextual information. See
`org-export-data'. If the link is pointing to a local image
file, the twiki page will contain a src img link to an attachment
on the twiki."
;; TODO: Solve similar to ox-html.el using org-export-inline-image-p
(let ((raw-link (org-element-property :raw-link link)))
(if (org-export-inline-image-p link org-twiki-inline-image-rules)
(let ((fname
(replace-regexp-in-string "^.*:" "" raw-link))))
(format "<img src=\"%%ATTACHURLPATH%%/%s\" alt=\"%s\">"
fname fname))
(concat "[[" raw-link
(when (org-string-nw-p desc) (format "][%s" desc))
;; replace all newlines in paragraphs (includes list item text, which
;; also constitutes a paragraph
(defun org-twiki-paragraph (paragraph contents info)
(replace-regexp-in-string "\n" " " contents))
(defun org-twiki-section (section contents info)
(defun org-twiki-src-block (src-block contents info)
"Transcode an INLINE-SRC-BLOCK element from Org to Twiki.
CONTENTS holds the contents of the item. INFO is a plist holding
contextual information."
(let* ((srclang (org-element-property :language src-block))
(lang (assoc-default srclang org-twiki-code-mappings)))
(if (and lang (string= "t" (plist-get info :twiki-code-beautify)))
(format "%%CODE{\"%s\"}%%\n%s%%ENDCODE%%\n" lang
(org-export-format-code-default src-block info))
(format "\n<verbatim>\n%s</verbatim>\n"
(org-export-format-code-default src-block info)))))
(defun org-twiki-strike-through (strike-through contents info)
(format "-%s-" contents))
(defun org-twiki-table (table contents info)
(let ((caption (org-export-get-caption table)))
(when caption (format "%%TABLE{caption=\"%s\"}%%\n"
(org-export-data caption info)))
(defun org-twiki-table-row (table-row contents info)
(if (org-string-nw-p contents) (format "|%s" contents)
(defun org-twiki-table-cell (table-cell contents info)
(let ((table-row (org-export-get-parent table-cell)))
;; org-export-table-row-starts-header-p considers a table to have
;; a header, if it contains a horizontal line anywhere. So, even
;; a table with a single horizontal line before the last row will
;; be considered to have a header. Should be improved.
(when (org-export-table-row-starts-header-p table-row info)
(when (org-export-table-row-starts-header-p table-row info)
(defun org-twiki-target-to-twiki (target)
(let ((s (concat "Rule" (mapconcat 'capitalize (split-string target "-") ""))))
(if (> (length s) 32)
(substring s 0 32)
(defun org-twiki-target (target contents info)
(let ((tval (org-element-property :value target)))
(format "%s<<TARG#%s>>" tval (org-twiki-target-to-twiki tval))))
(defun org-twiki-template (contents info)
(let ((depth (plist-get info :with-toc))
(title (org-export-data (plist-get info :title) info)))
"---+!! " title "\n"
(org-element-normalize-string (plist-get info :twiki-header))
(when depth "%TOC%\n\n")
(defun org-twiki-fix-targets (contents)
(let ((pos 0) epos lpos)
(while (setq pos (string-match "<<TARG.*>>" contents pos))
(setq epos (match-end 0))
(if (string-match "\n" contents epos)
(setq lpos (match-end 0))
(setq lpos (length contents)))
(setq contents (concat (substring contents 0 pos)
(substring contents epos lpos)
(substring contents (+ pos 6) (- epos 2))
(substring contents lpos))))
(defun org-twiki-inner-template (contents info)
;; Document body
(org-twiki-fix-targets contents)
;; Footnotes
(let ((definitions (org-export-collect-footnote-definitions
(plist-get info :parse-tree) info))
;; Insert full links right inside the footnote definition
;; as they have no chance to be inserted later.
(org-ascii-links-to-notes nil))
(when definitions
(let ((title (org-ascii--translate "Footnotes" info)))
title "\n"
(string-width title)
(if (eq (plist-get info :ascii-charset) 'utf-8) ? ?_))))
(let ((text-width (- org-ascii-text-width org-ascii-global-margin)))
(lambda (ref)
(let ((id (format "[%s] " (car ref))))
;; Distinguish between inline definitions and
;; full-fledged definitions.
(let ((def (nth 2 ref)))
(if (eq (org-element-type def) 'org-data)
;; Full-fledged definition: footnote ID is
;; inserted inside the first parsed paragraph
;; (FIRST), if any, to be sure filling will
;; take it into consideration.
(let* ((first (car (org-element-contents def)))
(tinfo (org-twiki-footnote-name (cadr ref)))
(name (cdr tinfo))
(twiki-target (car tinfo)))
(if (not (eq (org-element-type first) 'paragraph))
(concat id "\n" (org-export-data def info))
(push id (nthcdr 2 first))
(format "#%s [%s] " twiki-target name)
(org-export-data def info)
;; Fill paragraph once footnote ID is inserted
;; in order to have a correct length for first
;; line.
(concat id (org-export-data def info))
text-width info))))))
definitions "\n\n"))))))
(defun org-twiki-underline (underline contents info)
(format "_%s_" contents))
;; CAR is twiki target
;; CDR is name to display
(defun org-twiki-footnote-name (target)
(let ((name (if (string-prefix-p "fn:" target)
(substring target 3)
(concat "Fn" (upcase (substring name 0 1)) (substring name 1))
(defun org-twiki-footnote-reference (footnote-reference contents info)
(let* ((target (org-element-property :label footnote-reference))
(tinfo (org-twiki-footnote-name target))
(name (cdr tinfo))
(twiki-target (car tinfo)))
(format "[[[#%s][%s]]]" twiki-target name)))
;; (defun org-twiki--block (language theme contents)
;; (concat "\{code:theme=" theme
;; (when language (format "|language=%s" language))
;; "}\n"
;; contents
;; "\{code\}\n"))
;; main interactive entrypoint
(defun org-twiki-export-as-twiki
(&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to a text buffer.
If narrowing is active in the current buffer, only export its
narrowed part.
If a region is active, export that region.
A non-nil optional argument ASYNC means the process should happen
asynchronously. The resulting buffer should be accessible
through the `org-export-stack' interface.
When optional argument SUBTREEP is non-nil, export the sub-tree
at point, extracting information from the headline properties
When optional argument VISIBLE-ONLY is non-nil, don't export
contents of hidden elements.
When optional argument BODY-ONLY is non-nil, strip title, table
of contents and footnote definitions from output.
EXT-PLIST, when provided, is a property list with external
parameters overriding Org default settings, but still inferior to
file-local settings.
Export is done in a buffer named \"*Org Twiki Export*\", which
will be displayed when `org-export-show-temporary-export-buffer'
is non-nil.
You can set the following options inside of the document:
controls whether code blocks are exported as %CODE{}% twiki
blocks (requires the beautify twiki plugin)."
(org-export-to-buffer 'twiki "*Org Twiki Export*"
async subtreep visible-only body-only ext-plist (lambda () (text-mode))))
(provide 'ox-twiki)
;;; ox-twiki.el ends here
#+MACRO: version 0.5
#+LaTeX_HEADER: \def\rulesversion{0.5}
#+MACRO: version 0.6
#+LaTeX_HEADER: \def\rulesversion{0.6}
#+TITLE: ATLAS C++ coding guidelines, version {{{version}}}
#+AUTHOR: Shaun Roe (CERN), Scott Snyder (BNL), and the former ATLAS Quality Control group
#+EMAIL: Correspondence to
......@@ -9,6 +9,8 @@
# the `Footnotes' section in HTML to `References'
#+LANGUAGE: en-references
#+TWIKI_HEADER: *Do not edit this page. Its contents are generated automatically from the source at [[]].*
# Put a frame around examples in LaTeX.
#+LaTeX_HEADER: \usepackage{fancyvrb}
#+LaTeX_HEADER: \RecustomVerbatimEnvironment{verbatim}{Verbatim}{frame=single}
......@@ -47,7 +49,7 @@ common errors and pitfalls in C++ programming, and thus have more
reliable code. But even more important: a computer program should
not only tell the machine what to do, but it should also tell /other people/
what you want the machine to do. (For much more elaboration on this idea,
look up references on ``literate programming,'' such as [fn:knuth84].)
look up references on ``literate programming,'' such as [fn:Knuth84].)
This is obviously important any time
when you have many people working on a given piece of software,
and such considerations would naturally lead to code that is easy
......@@ -56,16 +58,16 @@ form of publication, and take the same care as you would writing
up an analysis for colleagues.
This document is derived from the original ATLAS C++ coding standard,
[[][ATL-SOFT-2002-001]] [fn:atlas-old], which was last revised in 2003. This itself
[[][ATL-SOFT-2002-001]] [fn:Atlas02], which was last revised in 2003. This itself
derived from work done by the CERN ``Project support team''
and SPIDER project, as documented in [[][CERN-UCO/1999/207]] [fn:pst].
and SPIDER project, as documented in [[][CERN-UCO/1999/207]] [fn:PST99].
These previous guidelines have been significantly revised
to take into account the evolution of the C++ language [fn:cxx],
to take into account the evolution of the C++ language [fn:Cxx14],
current practices in ATLAS, and the experience gained
over the past decade.
Some additional useful information on C++ programming may be
found in [fn:meyers1], [fn:meyers2], and [fn:gof].
found in [fn:Meyers97], [fn:Meyers01], and [fn:GOF].
This note is not intended to be a fixed set of rigid rules.
Rather, it should evolve as experience warrants.
......@@ -424,6 +426,9 @@ vector<int> x; // Missing std!
Otherwise, the =using= may serve to hide problems with missing
namespace qualifications in the headers.
Starting with C++11, =using= can also be used in ways similar to =typedef=.
Such usage is not covered by this rule.
** Control flow
......@@ -431,7 +436,8 @@ vector<int> x; // Missing std!
When you write a for loop, it is highly confusing and error-prone to
change the loop variable within the loop body rather than inside the
expression executed after each iteration.
expression executed after each iteration. It may also inhibit many
of the loop optimizations that the compiler can perform.
- *Prefer range-based for loops.* [<<prefer-range-based-for>>]
......@@ -458,7 +464,7 @@ for (std::vector<int>::const_iterator it = v.begin();
In some cases you can't make this replacement; for example, if you
need to call methods on the iterator itself, or you need to manage
multiple iterators within the loop. But most simple loops over
STL ranges are most simply written with a range-based for.
STL ranges are more simply written with a range-based for.
- *All switch statements must have a default clause.* [<<switch-default>>]
......@@ -1651,7 +1657,7 @@ public:
For a detailed example of a reasonable application of multiple inheritance,
see [fn:meyers1], item 43.
see [fn:Meyers01], item 43.
- *Avoid the use of friend declarations.* [<<no-friend>>]
......@@ -2051,14 +2057,14 @@ public:
set of exceptions.
Experience has shown that exception specifications are generally not useful,
and they have been deprecated in C++11 [fn:sutter02]. They should not
and they have been deprecated in C++11 [fn:Sutter02]. They should not
be used in new code. In C++17, the use of non-empty exception specifications
is an error.
C++14 added a new =noexcept= keyword. However, the motivation for this was
really to address a specific problem with move constructors and
exception-safety, and it is not clear that it is
generally useful [fn:krzemienski14].
generally useful [fn:Krzemienski14].
For now, it is not recommended to use =noexcept=, unless you have
a specific situation where you know it would help.
......@@ -2074,7 +2080,7 @@ public:
overly-broad catch specification, you risk hiding other problems.
try {
return getObject ("foo");
// getObject may throw ExcNotFound if the "foo"
......@@ -2102,7 +2108,7 @@ public:
then the object thrown is copied to an instance of the base class.
For example, consider this program:
#include <stdexcept>
#include <iostream>
......@@ -2132,18 +2138,18 @@ int main()
It looks like the intention here is to have a custom message printed
when the exception is caught. But that's not what happens --- this
program actually prints:
Exception: std::exception
That's because in the =catch= clause, the =myex= instance is copied
to a =std::exception= instance, so any information about the derived
=myex= class is lost. If we change the catch to use a reference instead:
catch (const std::exception ex&) {
then the program prints what was probably intended.
Exception: Mine!
......@@ -2325,7 +2331,7 @@ public:
It may be tempting to use bit fields to save space in data written
to disk, or packing and unpacking raw data. However, this usage is
to disk, or in packing and unpacking raw data. However, this usage is
not portable. The C++ standard has this to say:
......@@ -2387,7 +2393,7 @@ some machines, left-to-right on others. -- end note ]
That way, they won't clutter up the header file.
- *Do not declare your own typedef for booleans. Use the bool type of C++ for booleans.* [<<use bool>>]
- *Do not declare your own typedef for booleans. Use the bool type of C++ for booleans.* [<<use-bool>>]
The =bool= type was not implemented in C. Programmers usually got around
the problem by typedefs and/or const declarations. This is no longer
......@@ -2432,7 +2438,7 @@ some machines, left-to-right on others. -- end note ]
library itself can't reasonably be fixed, it may be possible to put
a workaround in the wrapper package to suppress the warning.
See [fn:warnings] for help on how to get rid of many common types of warning.
See [fn:Warnings] for help on how to get rid of many common types of warning.
If it is really impossible to get rid of a warning, that fact should
be documented in the code.
......@@ -2529,7 +2535,7 @@ float ip_cut = 0.1 * Gaudi::Units::cm;
- *All code must comply with the 2014 version of the ISO C++ standard (C++14)*. [<<standard-cxx>>]
A draft of the standard which is essentially identical to the final version
may be found at [fn:cxx].
may be found at [fn:Cxx14].
At some point, compatibility with C++17 will also be required.
......@@ -2915,7 +2921,7 @@ private:
See the ATLAS Doxygen page [fn:doxygen].
See the ATLAS Doxygen page [fn:Doxygen].
Remember that the =/* */= style of comment does not nest. If you want
to comment out a block of code, using =#if 0= / =#endif= is safer
......@@ -2994,17 +3000,17 @@ The comment includes the fact that it is the perpendicular distance.
* Footnotes
[fn:atlas-old] [[][ATLAS Quality Control Group, /ATLAS C++ Coding Standard/, ATL-SOFT-2002-001, 2003.]]
[fn:pst] [[][CERN Project Support Team, /C++ Coding Standard/, CERN-UCO/1999/207, 2000.]]
[fn:knuth84] [[][D. Knuth, /The Computer Journal/, *27* (2), 97--111.]]
[fn:meyers1] S. Meyers, /Effective C++, 2nd Edition/, Addison-Wesley.
[fn:meyers2] S. Meyers, /Effective STL, 2nd Edition/, Addison-Wesley, 2001.
[fn:gof] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, /Design Patterns, Elements of Reusable Object-Oriented Software/, Addison-Wesley.
[fn:sutter02] [[][H. Sutter, /C++ Users Journal/, *20* (7), 2002.]]
[fn:krzemienski14] [[][A. Krzemie\nacute{}ski, /noexcept --- what for?/, 2014.]]