I am building an application which I would like to deploy as a CDF file, and I am struggling to make the CDF exports work correctly with functions pulled from a .m package file. What are good/best practices for handling such situations?
In particular, the code below encapsulates (at least partly) some of my difficulties. Make a package in the file TestPackage.m
with the definitions
BeginPackage["TestPackage`"]
f::usage="f[x] returns a plot.";
Begin["`Private`"]
f[x_]:=Plot[Sin[x y],{y,0,2 Pi},PlotRange->{-1,1},ImageSize->500]
End[]
EndPackage[]
and include it in the same directory as the following code in a notebook.
Needs["TestPackage`", NotebookDirectory[] <> "TestPackage.m"]
DynamicModule[
{a = 1},
Column[{
Slider[Dynamic[a]],
Dynamic[f[a]]
}]
, Initialization :> (
Needs["TestPackage`", NotebookDirectory[] <> "TestPackage.m"]
)
]
Export[NotebookDirectory[] <> "output.cdf", EvaluationNotebook[]]
The DynamicModule
correctly produces the desired output. If I close the notebook and reopen it, the plot renders correctly (which is not the case if the Initialization
Needs
is omitted). If I open the resulting output.cdf
using Mathematica, the plot also renders correctly.
However, if I open output.cdf
using the Wolfram CDF Player 10.1, the only thing that shows underneath the Slider
is TestPackage`f[1.]
(or whatever the value of a
is).
I also tried naively spewing the contents of the package onto the initialization rule, along the lines of
Initialization :> (
ImportString[Import[NotebookDirectory[] <> "TestPackage.m", "Text"],
"NB"]
)
but it produces exactly the same behaviour. Presumably there exists a way to do this, but this simply puts the above code into the CDF, which the player then refuses to execute.
How can I make this plot render correctly in the exported CDF version?
SaveDefinitions
option (just a guess. By far not an expert on this). $\endgroup$With
your package in text form toInitialization
andGet
+StringToStream
if you don't trustSaveDefinitions
. You should be able to incorporate password protected encoded packages with this method. Not perfect but nice enough for free player. $\endgroup$SaveDefinitions
does in fact fix this example. Which means that this doesn't capture whatever is wrong with my bigger code. Back to the drawing board on that, then. Still, if there's a way to replicate the package's definitions in the Initialization stage it should help there. $\endgroup$