Generating Julia doc into Org-Mode documents

By: Picaud Vincent

Re-posted from: https://pixorblog.wordpress.com/2018/04/29/generating-julia-doc-into-org-mode-documents/

1 Context

This post presents J4Org.jl a Julia package I have started to develop to include Julia doc into Org-Mode documents. My goal was to be able to code and document Julia packages without leaving Emacs and to reduce as much as possible the burden of documentation.

2 Julia code documentation

Here is a short example. Imagine that your package is:

module Foo

export Point, foo
    
import Base: norm

#+Point L:Point_struct
# This is my Point structure
#
# *Example:*
#
# Creates a point $p$ of coordinates $(x=1,y=2)$.
#
# #+BEGIN_SRC julia :eval never :exports code
# p=Point(1,2)
# #+END_SRC
#
# You can add any valid Org-Mode directive. If you want to use
# in-documentation link, use [[norm_link_example][]]
#
struct Point
    x::Float64
    y::Float64
end

#+Point
# Creates Point at origin $(0,0)$ 
Point() = Point(0,0)

#+Point,Method L:norm_link_example
# A simple function that computes $\sqrt{x^2+y^2}$
#
# *Example:*
#!p=Point(1.0,2.0);
#!norm(p) 
#
# See: [[Point_struct][]]
#
norm(p::Point)::Float64 = sqrt(p.x*p.x+p.y*p.y)

#+Method,Internal
# An internal function
#
# For symbol that are not exported, do not forget the "Foo." prefix:
#!p=Point(1.0,2.0)
#!Foo.foo(2.0,p)
foo(r::Float64,p::Point) = Point(r*p.x,r*p.y)

end

The documentation template is very simple. Before each item you want to document add these comment lines:

#+Tag1,Tag2,... L:an_extra_link_if_required 
#
# Here you can put any Org mode text, for instance $sin(x)$
#
#!sin(5) # julia code to be executed
#
# [[internal_link][]]
struct A_Documented_Struct 
...
end 
  • #+Tag1,Tag2,… is mandatory, “#+” is followed by a list of tags. Later when you want to extract doc you can do filtering according these tags.
  • L:an_extra_link_if_required is not mandatory. It defines a reference if you want to create doc links. The previous statement defines a link target named an_extra_link_if_required.
  • [[internal_link][]] creates a link to a previously defined L:internal_link.
  • !sin(5) will execute Julia code and include the output in the doc.

Also note that you can keep compatibility with docstring as follows:

""" 
    foo() 

foo function...
"""
#+Tag
#
# foo function
foo() = ...

3 Org-Mode side

You need Org-Mode plus ob-julia.el to be installed. For illustration we use this minimal Org-Mode document:

#+PROPERTY: header-args:julia :session *my_session* :exports code :eval no-export
#+OPTIONS: ^:{}
#+TITLE: Getting Started with a minimal example

#+BEGIN_SRC julia :results output none :eval no-export :exports none
using J4Org 
initialize_boxing_module(usedModules=["Foo"]) 
documented_items=create_documented_item_array("Foo.jl")
#+END_SRC

* Example

Prints all documented items, except those tagged with "Internal" 
#+BEGIN_SRC julia :results output drawer :eval no-export :exports results
print_org_doc(documented_items,tag_to_ignore=["Internal"],header_level=0)
#+END_SRC
  • using J4Org uses this package
  • initialize_boxing_module(usedModules=[“Foo”]) defines what are the modules to use when executing Julia code extracted from the doc (the “#!” statements). Here we are documenting the Foo module, hence we must use it.
  • create_documented_item_array(“Foo.jl”) creates the list of documented items from file “Foo.jl”. You can use a list of files or a directory.
  • print_org_doc(documented_items,tag_to_ignore=[“Internal”],header_level=0) prints all documented items, except those tagged with “Internal”.

4 Result after html-export

When html-exported with Org-Mode this will generate this document:

Index: [P] Point [n] norm

  • Point
struct Point

This is my Point structure

Example:

Creates a point p of coordinates (x=1,y=2).

p=Point(1,2)

You can add any valid Org mode directive. If you want to use in-documentation link, use norm(…)

Foo.jl:8, back to index

Point()

Creates Point at origin (0,0)

Foo.jl:27, back to index

  • norm
norm(p::Point)::Float64

A simple function that computes \sqrt{x^2+y^2}

Example:

p=Point(1.0,2.0);
norm(p) 
2.23606797749979

See: struct Point

Foo.jl:31, back to index

5 Further information

You can visit J4Org.jl for further details. You can even install it (Pkg.add("J4Org")). I have used it to document DirectConvolution.jl (this Direct Convolution Package html page for instance).

Disclaimer: this package is still in early development.