Skip to content

Commit

Permalink
ENH add markdown Table
Browse files Browse the repository at this point in the history
  • Loading branch information
hayd committed Jan 22, 2015
1 parent 7fbea9d commit f70f685
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 4 deletions.
82 changes: 79 additions & 3 deletions base/markdown/GitHub/GitHub.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,83 @@ function github_paragraph(stream::IO, md::MD, config::Config)
return true
end

# TODO: tables
typealias Row Vector

@flavor github [list, indentcode, blockquote, fencedcode, hashheader, github_paragraph,
en_dash, inline_code, asterisk_bold, asterisk_italic, image, link]
type Table
rows::Vector{Row}
align
end

function github_table(stream::IO, md::MD, config::Config)
withstream(stream) do
rows = Row[]
n = 0
align = :r # default is to align right
while !eof(stream)
n += 1
pos = position(stream)
skipwhitespace(stream)
line = readline(stream) |> chomp

if n == 1
pipe_border = line[1] == '|'
if !('|' in line)
return false
end
end

row = map(strip, split(line, "|"))
if pipe_border
if row[1] == row[end] == ""
row = row[2:end-1]
else
return false
end
end

if n == 2 && all(['-' in r && issubset(Set(r), Set(" -:"))
for r in row])
# handle possible --- line
align = Symbol[]
for r in row
if r[1] == ':'
if r[end] == ':'
push!(align, :c)
else
push!(align, :l)
end
else
if r[end] == ':'
push!(align, :r)
else
# default is align right
push!(align, :r)
end
end
end

elseif n == 1 || length(rows[1]) == length(row)
push!(rows, Row(map(x -> parseinline(IOBuffer(_full(x)), config), row)))
elseif length(row) > 1
seek(stream, pos)
break
else
seek(stream, 0)
return false
end
end
if length(rows) < 2
seek(stream, 0)
return false
end
push!(md, Table(rows, align))
return true
end
end

_full{T}(s::SubString{T}) = convert(T, s)
_full(s::AbstractString) = s

@flavor github [list, indentcode, blockquote, fencedcode, hashheader,
github_paragraph, github_table,
en_dash, inline_code, asterisk_bold, asterisk_italic, image, link]
2 changes: 1 addition & 1 deletion base/markdown/Julia/Julia.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ We start by borrowing GitHub's `fencedcode` extension – more to follow.

include("interp.jl")

@flavor julia [blocktex, blockinterp, hashheader, list, indentcode, fencedcode,
@flavor julia [github_table, blocktex, blockinterp, hashheader, list, indentcode, fencedcode,
blockquote, paragraph,

escapes, latex, interp, en_dash, inline_code, asterisk_bold,
Expand Down
15 changes: 15 additions & 0 deletions base/markdown/render/html.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ function html(io::IO, md::List)
end
end

function html(io::IO, md::Table)
withtag(io, :table) do
for (i, row) in enumerate(md.rows)
withtag(io, :tr) do
for c in md.rows[i]
t = i == 1 ? :th : :td
withtag(io, t) do
htmlinline(io, c)
end
end
end
end
end
end

html(io::IO, x) = tohtml(io, x)

# Inline elements
Expand Down
24 changes: 24 additions & 0 deletions base/markdown/render/latex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,30 @@ function writemime(io::IO, ::MIME"text/latex", md::List)
end
end

function writemime(io::IO, ::MIME"text/latex", md::Table)
wrapblock(io, "tabular") do
if typeof(md.align) == Symbol
align = string(md.align) ^ length(md.rows[1])
else
align = md.align
end
println(io, "{$(join(align, " | "))}")
for (i, row) in enumerate(md.rows)
for (j, cell) in enumerate(row)
if j != 1
print(io, " & ")
end
latex_inline(io, cell)
end
println(io, " \\\\")
if i == 1
println("\\hline")
end
end
end
end


# Inline elements

function writemime(io::IO, ::MIME"text/latex", md::Plain)
Expand Down
40 changes: 40 additions & 0 deletions base/markdown/render/plain.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,46 @@ function plain(io::IO, list::List)
end
end

function plain(io::IO, md::Table)
println("asdsa")
col_widths = reduce(max, map(cell -> map(ansi_length, cell), md.rows))

for (n, row) in enumerate(md.rows)
for (i, h) in enumerate(row)
a = typeof(md.align) == Symbol ? md.align : md.align[i]
# TODO use not terminal version of print_align
error("NotImplemented")
print_align(io, h, col_widths[i], a)
print(io, " ")
end
println(io, "")

if n == 1
for (j, w) in enumerate(col_widths)
if j != 1
print(io, "|")
end
a = typeof(md.align) == Symbol ? md.align : md.align[j]
print(io, _dash(w, a) * " ")
end
println(io, "")
end
end
end

function _dash(width, align)
if align == :l
return ":" * "-" ^ max(1, width - 1)
elseif align == :r
return "-" ^ max(1, width - 1) * ":"
elseif align == :c
return "-" ^ width
else
throw(ArgumentError("Unrecognized alignment $align"))
end
end


plain(io::IO, x) = tohtml(io, x)

# Inline elements
Expand Down
19 changes: 19 additions & 0 deletions base/markdown/render/terminal/formatting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,25 @@ function print_centred(io::IO, s...; columns = 80, width = columns)
end
end

function print_align(io::IO, text, width, align=:r)
n = ansi_length(text)
if align == :c # center
lpad = div(width - n, 2)
elseif align == :r # right
lpad = width - n
elseif align == :l # left
lpad = 0
else
throw(ArgumentError("Alignment $align not recognised"))
end
print(io, " " ^ lpad)
for t in text
terminline(io, t)
end
print(io, " " ^ (width - lpad - n))
end


function centred(s, columns)
pad = div(columns - ansi_length(s), 2)
" "^pad * s
Expand Down
30 changes: 30 additions & 0 deletions base/markdown/render/terminal/render.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,36 @@ function term(io::IO, md::Code, columns)
end
end

function term(io::IO, md::Table, columns)
col_widths = reduce(max, map(cell -> map(ansi_length, cell), md.rows))

for (n, row) in enumerate(md.rows)
for (i, h) in enumerate(row)
a = typeof(md.align) == Symbol ? md.align : md.align[i]
print_align(io, h, col_widths[i], a)
print(io, " ")
end
println(io, "")

if n == 1
for w in col_widths
print(io, ("-" ^ w) * " ")
end
println(io, "")
end
end
end

function ansi_length(md::Vector{Any})
total = 0
for c in md
total += ansi_length(c)
end
total
end
ansi_length(c::Code) = ansi_length(c.code)
ansi_length(l::Link) = ansi_length(l.text)

term(io::IO, x, _) = writemime(io, MIME"text/plain"(), x)

# Inline Content
Expand Down

0 comments on commit f70f685

Please sign in to comment.