Skip to content

Commit 8dcc70f

Browse files
authored
Merge pull request #6 from Datax-package/latexify
Version 3.0.0
2 parents 59b0e7e + d304bcd commit 8dcc70f

4 files changed

Lines changed: 115 additions & 158 deletions

File tree

Project.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
name = "LaTeXDatax"
22
uuid = "644dedec-337d-45c6-9a86-27a5fed2b77d"
33
authors = ["David Gustavsson <david.e.gustavsson@gmail.com> and contributors"]
4-
version = "2.2.0"
4+
5+
version = "3.0.0"
6+
57

68
[deps]
7-
Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0"
8-
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
9+
Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
910
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
11+
UnitfulLatexify = "45397f5d-5981-4c77-b2b3-fc36d6e9b728"
1012

1113
[compat]
12-
Formatting = "0.4"
13-
Requires = "1.1"
14+
Latexify = "0.14.7"
1415
Unitful = "1.5"
16+
UnitfulLatexify = "1.3.0"
1517
julia = "1"
1618

1719
[extras]

README.md

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,21 @@ the accompanying package `datax.sty`.
88

99
## Usage
1010
```julia
11-
using LaTeXDatax
12-
filename = "datafile.tex"; # default is "data.tex"
11+
using LaTeXDatax, Unitful
1312
a = 25;
14-
b = "Something";
15-
c = (300,"\\mega\\meter\\per\\second");
1613

17-
using Unitful
18-
d = 4.2u"Hz";
19-
20-
@datax a b c d filename
21-
# or, equivalently,
22-
data(a=a, b="Something", c=c, d=d, filename="datafile.tex");
14+
@datax a b=3a c=3e8u"m/s" d="Raw string" filename:="data.tex"
2315
```
2416

2517
```latex
2618
\documentclass{article}
2719
\usepackage{siunitx}
28-
\usepackage[dataxfile=datafile.tex]{datax}
20+
\usepackage[dataxfile=data.tex]{datax}
2921
3022
\begin{document}
3123
The speed of light is \datax{c}.
3224
\end{document}
3325
```
3426

35-
More detailed usage information is in the docstrings of the code, run `?datax`
36-
and `?@datax` in REPL to read them.
27+
More detailed usage information is in the docstrings of the code, run `?@datax`
28+
in REPL to read them.

src/LaTeXDatax.jl

Lines changed: 85 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,114 @@
11
module LaTeXDatax
2-
using Requires, Formatting
2+
using Unitful, UnitfulLatexify, Latexify
33

4-
export datax,@datax
4+
export @datax
55

66
"""
77
```julia
8-
datax(...)
8+
@datax
99
```
1010
11-
Print the arguments to a file readable by pgfkeys (Best for use with the
12-
`datax` LaTeX package). A string will be printed as is, a number will be
13-
wrapped in `siunitx`'s `\\num`, and a tuple `(value::Number, unit::String)` or
14-
a `Unitful` quantity will be wrapped in `\\SI`. If the argument is a `Tuple`
15-
and the first argument is a string, it is used as a c-printf style format
16-
string for the rest of the tuple (overriding the default format set by the
17-
"format" argument). There's also a macro form, `@datax`, which reuses the
18-
variable names from the script.
11+
Print the arguments to a data file to be read by pgfkeys. Best used with the
12+
[`datax` LaTeX package](https://ctan.org/pkg/datax). Variables can be supplied
13+
either by name or as assignments, and meta-arguments are supplied using the
14+
`:=` operator.
1915
20-
The variable names "filename" and "format" cannot be stored, but will instead
21-
be used as the name of the file and the default number format respectively.
16+
The meta-arguments include all the keyword arguments from `Latexify.jl` and
17+
`UnitfulLatexify.jl` (for instance `unitformat := :siunitx`, `fmt := "%.2e"`),
18+
as well as a few extra:
19+
20+
# Meta-arguments
21+
* `filename`: The path to a file that will be written.
22+
* `io`: an `IO` object to write to instead of a file. Overrides the `filename`
23+
argument. If neither this nor `filename` is given, `stdout` is used.
24+
* `permissions`: Defaults to `"w"`. Can be given as `"a"` to append to a file
25+
instead of overwriting. Only meaningful with a `filename` argument.
2226
2327
# Examples
2428
```julia
25-
datax(a=2,b=1.24,c="hi",d=(24,"\\meter"),e=15u"kg/s^2")
26-
```
27-
Save the given variables in siunitx form.
29+
julia> a = 2;
30+
julia> b = 3.2u"m";
31+
julia> @datax a b c=3*a d=27 unitformat:=:siunitx
32+
\\pgfkeyssetvalue{/datax/a}{\\num{2}}
33+
\\pgfkeyssetvalue{/datax/b}{\\SI{3.2}{\\meter}}
34+
\\pgfkeyssetvalue{/datax/c}{\\num{6}}
35+
\\pgfkeyssetvalue{/datax/d}{\\num{27}}
2836
29-
```julia
30-
datax(lambda=612.2u"nm",filename="other.tex",format="%.4e")
31-
datax(lambda=("%.4e",612.2,"\\nano\\meter"),filename="other.tex")
3237
```
33-
Save just the variable lambda, in the file "other.tex", in scientific notation
34-
with 4 digits of accuracy. The two lines are equivalent.
3538
"""
36-
function datax(;filename="data.tex",format="%.4g",overwrite=true,kwargs...)
37-
datax(Dict(kwargs);filename,format,overwrite)
39+
macro datax(args...)
40+
esc(datax_helper(args...))
3841
end
3942

40-
function datax(d::Dict{Symbol,<:Any};filename="data.tex",format::String="%.4g",overwrite=true)
41-
filename = pop!(d,:filename,filename)
42-
format = pop!(d,:format,format)
43-
overwrite = pop!(d,:overwrite,overwrite)
44-
permission = overwrite ? "w" : "a"
45-
open(filename,permission) do f
46-
println(f,"% Autogenerated by LaTeXDatax.jl, will be overwritten")
47-
for (k,v) in d
48-
print(f,"\\pgfkeyssetvalue{/datax/$k}{")
49-
printdata(f,v,format)
50-
print(f,"}\n")
43+
function datax_helper(args...)
44+
metaargs = Expr[]
45+
names = Symbol[]
46+
values = Any[]
47+
for a in args
48+
if a isa Symbol
49+
push!(names, a)
50+
push!(values, a)
51+
continue
5152
end
52-
end
53-
end
53+
if a.head == :(=)
54+
push!(names, a.args[1])
55+
push!(values, a.args[2])
56+
continue
5457

55-
"""
56-
```julia
57-
@datax ...
58-
```
59-
Print the arguments to a file readable by pgfkeys (Best for use with the
60-
`datax` LaTeX package). Like the `datax()` function, but use the variables'
61-
names.
58+
end
59+
if a.head == :(:=)
60+
push!(metaargs, Expr(:kw,a.args[1],a.args[2]))
61+
continue
62+
end
63+
error("I don't know what to do with argument $a")
64+
end
6265

63-
# Examples
64-
```julia
65-
a=2;
66-
b=3.2u"m";
67-
c="hi";
68-
filename="datafile.tex";
69-
format="%.2g";
70-
@datax a b c filename format
71-
```
72-
"""
73-
macro datax(args...)
74-
esc(datax_helper(args...))
75-
end
76-
function datax_helper(args...)
77-
names = Expr(:vect, QuoteNode.(args)...)
78-
values = Expr(:vect, args...)
66+
names = Expr(:tuple, QuoteNode.(names)...)
67+
values = Expr(:tuple, values...)
7968
quote
80-
datax(Dict($names .=> $values))
69+
LaTeXDatax.datax($names,$values;$(metaargs...))
70+
nothing
8171
end
8272
end
8373

84-
printdata(f::IO,v::String,fmt::String) = print(f,v)
85-
printdata(f::IO,v::Number,fmt::String) = print(f,"\\num{",sprintf1(fmt,v),"}")
86-
printdata(f::IO,v::AbstractArray{<:Number},fmt::String) = print(f,"\\numlist{",prod(sprintf1.(fmt,v).*";"),"}")
87-
printdata(f::IO,v::Tuple{<:Number,String},fmt::String) = print(f,"\\SI{",sprintf1(fmt,v[1]),"}{",v[2],"}")
88-
printdata(f::IO,v::Tuple{AbstractArray{<:Number},String},fmt::String) = print(f,
89-
"\\SIlist{",
90-
prod(
91-
sprintf1.(fmt,v[1]).*";")
92-
,"}{",
93-
v[2],
94-
"}"
95-
)
96-
printdata(f::IO,v::Tuple{String,Vararg},fmt::String) = printdata(f,length(v)>2 ? v[2:end] : v[2], v[1])
97-
98-
function __init__()
99-
@require Unitful="1986cc42-f94f-5a68-af5c-568840ba703d" begin
100-
101-
function printdata(f::IO,v::Unitful.Quantity,fmt::String)
102-
print(f,"\\SI{"*sprintf1(fmt,v.val)*"}{")
103-
siunitxprint(f,Unitful.unit(v))
104-
print(f,"}")
105-
end
106-
function printdata(f::IO,v::AbstractArray{T},fmt::String) where T<:Unitful.Quantity
107-
print(f,"\\SIlist{"*prod(sprintf1.(fmt,Unitful.ustrip(v)).*";")*"}{")
108-
siunitxprint(f,Unitful.unit(T))
109-
print(f,"}")
110-
end
74+
function datax(names, values; kwargs...)
75+
if haskey(kwargs, :io)
76+
datax(kwargs[:io], names, values; kwargs...)
77+
return nothing
78+
end
79+
if haskey(kwargs, :filename)
80+
datax(kwargs[:filename], names, values; kwargs...)
81+
return nothing
82+
end
83+
datax(stdout, names, values; kwargs...)
84+
return nothing
85+
end
11186

112-
function siunitxprint(f::IO,u::Unitful.FreeUnits)
113-
prefixes = Dict(
114-
-24 => "\\yocto",
115-
-21 => "\\zepto",
116-
-18 => "\\atto",
117-
-15 => "\\femto",
118-
-12 => "\\pico",
119-
-9 => "\\nano",
120-
-6 => "\\micro",
121-
-3 => "\\milli",
122-
-2 => "\\centi",
123-
-1 => "\\deci",
124-
0 => "",
125-
1 => "\\deka",
126-
2 => "\\hecto",
127-
3 => "\\kilo",
128-
6 => "\\mega",
129-
9 => "\\giga",
130-
12 => "\\tera",
131-
15 => "\\peta",
132-
18 => "\\exa",
133-
21 => "\\zetta",
134-
24 => "\\yotta"
135-
)
136-
for p in typeof(u).parameters[1]
137-
p.power<0 && print(f,"\\per")
138-
iszero(p.tens) || print(f,prefixes[p.tens])
139-
print(f,"\\$(lowercase(String(Unitful.name(p))))")
140-
abs(p.power)==1 || print(f,"\\tothe$(Int64(abs(p.power)))")
141-
end
142-
end
87+
datax(io::IO, names, values; kwargs...) = printkeyval.(Ref(io),names,values; kwargs...)
14388

89+
function datax(filename::String, names, values; permissions="w", kwargs...)
90+
if haskey(kwargs,:overwrite)
91+
if kwargs[:overwrite]
92+
permissions = "w"
93+
else
94+
permissions = "a"
95+
end
14496
end
97+
open(filename, permissions) do io
98+
permissions == "w" && println(io, "% Autogenerated by LaTeXDatax.jl, will be overwritten")
99+
datax(io, names, values; kwargs...)
100+
end
101+
end
102+
103+
function printkeyval(io::IO, name, value; kwargs...)
104+
print(io, "\\pgfkeyssetvalue{/datax/", name, "}{")
105+
printdata(io, value; kwargs...)
106+
print(io, "}\n")
107+
return nothing
145108
end
146109

110+
printdata(io::IO, v::String; kwargs...) = print(io, v)
111+
printdata(io::IO, v::Number; kwargs...) = print(io, latexify(v*u"one"; kwargs...))
112+
printdata(io::IO, v; kwargs...) = print(io, latexify(v; kwargs...))
113+
147114
end # module

test/runtests.jl

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,28 @@ using Test
44
@testset "LaTeXDatax.jl" begin
55
io = IOBuffer();
66

7-
# Basic printing
8-
LaTeXDatax.printdata(io,"String","%.4g")
7+
# Basic data printing
8+
LaTeXDatax.printdata(io,"String")
99
@test String(take!(io)) == "String"
10-
LaTeXDatax.printdata(io,4.1,"%.4g")
11-
@test String(take!(io)) == "\\num{4.1}"
12-
LaTeXDatax.printdata(io,[1.0,2.4,3.0],"%.4g")
13-
@test String(take!(io)) == "\\numlist{1;2.4;3;}"
1410

15-
# Print units
16-
LaTeXDatax.printdata(io,(1.0,"\\meter"),"%.4g")
17-
@test String(take!(io)) == "\\SI{1}{\\meter}"
18-
LaTeXDatax.printdata(io,([1,2,3],"\\kilogram"),"%.4g")
19-
@test String(take!(io)) == "\\SIlist{1;2;3;}{\\kilogram}"
11+
LaTeXDatax.printdata(io,1.25)
12+
@test String(take!(io)) == "\$1.25\$"
2013

21-
# Format strings
22-
LaTeXDatax.printdata(io,pi,"%.3g")
14+
LaTeXDatax.printdata(io,3.141592; fmt="%.2f", unitformat=:siunitx)
2315
@test String(take!(io)) == "\\num{3.14}"
24-
LaTeXDatax.printdata(io,("%.2g",pi),"%.4g")
25-
@test String(take!(io)) == "\\num{3.1}"
26-
LaTeXDatax.printdata(io,("%.5g",pi,"\\liter"),"%.4g")
27-
@test String(take!(io)) == "\\SI{3.1416}{\\liter}"
2816

29-
# Unitful
30-
LaTeXDatax.printdata(io,2u"m","%.4g")
31-
@test String(take!(io)) == "\\SI{2}{\\meter}"
32-
LaTeXDatax.printdata(io,[1.4,2.8]u"g/J","%.4g")
33-
@test String(take!(io)) == "\\SIlist{1.4;2.8;}{\\gram\\per\\joule}"
17+
# keyval printing
18+
LaTeXDatax.printkeyval(io, :a, 612.2u"nm")
19+
@test String(take!(io)) == "\\pgfkeyssetvalue{/datax/a}{\$612.2\\;\\mathrm{nm}\$}\n"
3420

21+
# complete macro
22+
a = 2;
23+
b = 3.2u"m";
24+
@datax a b c=3*a d=27 unitformat:=:siunitx io:=io
25+
@test String(take!(io)) == """
26+
\\pgfkeyssetvalue{/datax/a}{\\num{2}}
27+
\\pgfkeyssetvalue{/datax/b}{\\SI{3.2}{\\meter}}
28+
\\pgfkeyssetvalue{/datax/c}{\\num{6}}
29+
\\pgfkeyssetvalue{/datax/d}{\\num{27}}
30+
"""
3531
end

0 commit comments

Comments
 (0)