Current section
Files
Jump to
Current section
Files
lib/org.ex
defmodule Org do
@moduledoc """
This package implements an org-mode lexer and parser.
org-mode is the markup language used by the powerful [org mode package for emacs](http://orgmode.org/).
This implementation supports only a small subset of the syntax at this point, but can already be useful for extracting information from well-formed documents.
Features supported are:
- Comments
- (nested) Sections
- Paragraphs
- Tables
"""
@type load_mode :: :document | :tokens
@doc "Loads a document from a file at given path"
@spec load_file(String.t, load_mode) :: Org.Document.t
def load_file(path, load_mode \\ :document) do
{:ok, data} = File.read(path)
load_string(data, load_mode)
end
@doc "Loads a document from the given source string"
@spec load_string(String.t, load_mode) :: Org.Document.t
def load_string(data, load_mode \\ :document)
def load_string(data, :document) do
Org.Parser.parse(data)
end
def load_string(data, :tokens) do
Org.Lexer.lex(data)
end
@doc ~S"""
Extracts a section at the given path of titles
Example:
iex> doc = Org.load_string(~S{
...>* First
...>** Second
...>*** Third
...>* Fourth
iex>})
iex> Org.section(doc, ["First"]).title
"First"
iex> Org.section(doc, ["First", "Second", "Third"]).title
"Third"
iex> Org.section(doc, ["Fourth"]).title
"Fourth"
"""
@spec section(Org.Document.t, list(String.t)) :: Org.Section.t
def section(doc, path) do
Org.Section.find_by_path(doc.sections, path)
end
@doc ~S"""
Extracts all tables from the given section or document
Example:
iex> doc = Org.load_string(~S{
...>First paragraph
...>| x | y |
...>| 1 | 7 |
...>Second paragraph
...>})
iex> Org.tables(doc)
[%Org.Table{rows: [%Org.Table.Row{cells: ["x", "y"]}, %Org.Table.Row{cells: ["1", "7"]}]}]
"""
@spec tables(Org.Section.t | Org.Document.t) :: list(Org.Table.t)
def tables(section_or_document) do
for %Org.Table{} = table <- Org.contents(section_or_document), do: table
end
@doc ~S"""
Extracts all paragraphs from the given section or document
Example:
iex> doc = Org.load_string(~S{
...>First paragraph
...>| x | y |
...>| 1 | 7 |
...>Second paragraph
...>})
iex> Org.paragraphs(doc)
[%Org.Paragraph{lines: ["First paragraph"]}, %Org.Paragraph{lines: ["Second paragraph"]}]
"""
@spec paragraphs(Org.Section.t | Org.Document.t) :: list(Org.Paragraph.t)
def paragraphs(section_or_document) do
for %Org.Paragraph{} = paragraph <- Org.contents(section_or_document), do: paragraph
end
@doc "Extracts all contents from given section or document"
@spec contents(Org.Document.t | Org.Section.t) :: list(Org.Content.t)
def contents(section_or_document)
def contents(%Org.Document{} = doc) do
Org.Document.contents(doc)
end
def contents(%Org.Section{} = section) do
Org.Section.contents(section)
end
end