When using the Publish feature of MATLAB, it typically publishes only what comes after the % signs or the function output. However, is there any command to take a variable and splice its value into text, possibly even creating LaTeX formulae from a MATLAB variable that holds a character string?
Here is an example of rendering LaTeX formulae (one hard-coded in comments, other stored as a string in a variable).
%% LaTeX Examples
% Below are some equations rendered in LaTeX.
% (try to publish this file).
%
%% The definition of e
% Here we use equation embedded in the file.
%
% $$ e = \sum_{k=0}^\infty {1 \over {k!} } $$
%
%% The Laplace transform
% Here we render an equation stored in a variable.
%
% offscreen figure
fig = figure('Menubar','none', 'Color','white', ...
'Units','inches', 'Position',[100 100 6 1.5]);
axis off
str = 'L\{f(t)\} \equiv F(s) = \int_0^\infty\!\!{e^{-st}f(t)dt}';
text(0.5, 0.5, ['$$' str '$$'], 'Interpreter','latex', 'FontSize',28, ...
'HorizontalAlignment','center', 'VerticalAlignment','middle')
snapnow
close(fig);
Here is how it looks like when the file is published as HTML:
You could wrap that last code in a helper function render_latex_string(str) and call it from different places.
To use variables from the workspace
when Publishing to html using disp() with a html encoded string will add the lines to the output (without using the formatting for code output).
for example
str = sprintf('some value: %f from the workspace',variable)
disp(['<html>',str,'</html>'])
Notes:
It is quite sensitive and you may need to add invisible section breaks between
code output and lines produced in this way.
Adding paragraph tags is useful to improve formatting
Sadly (to my knowledge) the publishing markdown interpreter is not used on these lines, they are "injected" into the output, therefore latex equations will not work.
Code
%% HTML option
% This option is anly available with HTML output...
a=1;
str = ['The current value of a is ', num2str(a)];
%%%
%
% When publishing to HTML using the |disp| function with HTML tags
% surrounding the string can allow workspace variables to appear within
% text.
%
% For example the following line is created by evaluating code, it is not a
% comment in the m-file
%
disp(['<html><p>',str,'</p></html>']);
%% Changing the value
% Now if we change a to 2...
a=2,str = ['The new value of a is ', num2str(a)];
%%
% Re-runing a similar code should show the updated value
disp(['<html><p>',str,'</p></html>'])
Output
The code above generates the following:
Related
In my code, I have a lot of constant values and parameters that take significant space in my code.
For example in C++, I would make a header and a separate file where I would define these parameters as, e.g., "const-type" and share the header with main or other .cpp files.
How do you keep such structuring in MATLAB, is it worth it?
An example: Coefficients.m looks as follows:
classdef coefficients
properties(Constant)
% NIST data
A_N = 28.98641;
end
end
Another file: Gas.m where I would like to use A_N looks as follows:
function Gas()
clear all
clc
import Coefficients.* % Does not work
% A simple print
Values.A_N % Does not work
coefficients.A_N % Does not work
Constant.A_N % Does not work
end
Ok so assuming the class coefficients defined as:
classdef coefficients
properties(Constant)
% NIST data
A_N = 28.98641;
end
end
This code must be saved in a file named coefficients.m (The class name and file name have to match to avoid weird effect sometimes).
Then assuming the following Gas.m file:
function Gas()
% Usage with "disp()"
disp('The A_N coefficient taken from NIST data is:')
disp(coefficients.A_N)
% Usage with fprintf
fprintf('\nFrom NIST data, the coefficient A_N = %f\n',coefficients.A_N)
% Usage in calculation (just use it as if it was a variable/constant name
AN2 = coefficients.A_N^2 ;
fprintf('\nA_N coefficient squared = %.2f\n',AN2)
% If you want a shorter notation, you can copy the coefficient value in
% a variable with a shorter name, then use that variable later in code
A_N = coefficients.A_N ;
fprintf('\nA_N coefficient cubed = %.2f\n',A_N^3)
end
Then running this file (calling it from the command line) yields:
>> Gas
The A_N coefficient taken from NIST data is:
28.98641
From NIST data, the coefficient A_N = 28.986410
A_N coefficient squared = 840.21
A_N coefficient cubed = 24354.73
Or if you simply need to access the coefficient in the Matlab console:
>> coefficients.A_N
ans =
28.98641
Now all these examples assume that the class file coefficient.m is visible in the current Matlab scope. For Matlab, it means the file must be in the MATLAB search path (or the current folder works too).
For more info about what is the Matlab search path and how it works you can read:
What Is the MATLAB Search
Path?
Files and Folders that MATLAB
Accesses
In your case, I would make a folder containing all these sorts of classes, then add this folder to the Matlab path, so you never have to worry again about individual script, function or program calling for it.
See this link for tips on using a class definition for this. Highlights of the tips are:
Properties can be accessed directly to get the value
Properties can be added that give the units of the constant (highly advised!)
Comments can be added that act as help text for the constants
The doc command automatically creates a reference page for this classdef
E.g.,
classdef myconstants
properties(Constant)
% g is the gravity of Earth
% (https://en.wikipedia.org/wiki/Gravity_of_Earth)
g = 9.8;
g_units = 'm/s/s';
% c is the speed of light in a vacuum
c = 299792458;
c_units = 'm/s';
end
end
>> help myconstants.g
I created a GUI called "stack" in MATLAB. It has a .m file associated with it. This GUI is called on multiple occasions by another GUI in the same folder.
Now I discovered that "stack" is a built-in function in MATLAB which I need to use for something else in the same working directory. All calls to the stack function somehow invoke the GUI by calling the stack.m script.
I do not want to rename this because it is used in many places.
Is there a way to use the built-in function without needing to rename? Some way to reference the function and the script separately?
Disclaimer: Please, please, please, do not do this.
Assuming that your own stack.m is only in the search path because it is in the current folder, then the easiest fix is to create some dummy subfolder, navigate to it, execute Matlabs stack function (which is the only stack in the current searchpath) and navigate back.
Here I have exemplified it with magic:
function a= magic
n=5;
cd dummy
a= magic(n);
cd ..
where dummy is the name of the subfolder.
A slight modification of Nicky's answer for the sake of repeatability: before navigating to the map where your stack.m GUI is stored, run
builtinStack = #stack();
which creates a function handle. This way you can call builtinStack() like the MATLAB function is supposed to be called, without having to cd out of the directory every time you want to use it.
The use of builtin, as suggested by hoki doesn't work, since built-in functions are defined as
...Functions such as "ind2sub", "sub2ind", etc. are not MATLAB built-in functions.... Those functions that are shipped with MATLAB but are not defined as built-in functions can be referred to as "MATLAB functions" ...
As answered by MathWorks Technical Support. This means that functions like stack aren't built-in in the sense that they are build in a different language, compiled and then called from MATLAB, but are actually written in MATLAB and are shipped with the release. The main way to check this is typing edit <functionname>; when showing only comments the function is a built-in as defined by TMW, when it shows MATLAB code as well, like stack, it's not a built-in as per the above definition.
An example of a built-in function is sum, whose associated .m-file looks as follows:
%SUM Sum of elements.
% S = SUM(X) is the sum of the elements of the vector X. If X is a matrix,
% S is a row vector with the sum over each column. For N-D arrays,
% SUM(X) operates along the first non-singleton dimension.
%
% S = SUM(X,DIM) sums along the dimension DIM.
%
% S = SUM(...,TYPE) specifies the type in which the
% sum is performed, and the type of S. Available options are:
%
% 'double' - S has class double for any input X
% 'native' - S has the same class as X
% 'default' - If X is floating point, that is double or single,
% S has the same class as X. If X is not floating point,
% S has class double.
%
% S = SUM(...,NANFLAG) specifies how NaN (Not-A-Number) values are
% treated. The default is 'includenan':
%
% 'includenan' - the sum of a vector containing NaN values is also NaN.
% 'omitnan' - the sum of a vector containing NaN values
% is the sum of all its non-NaN elements. If all
% elements are NaN, the result is 0.
%
% Examples:
% X = [0 1 2; 3 4 5]
% sum(X, 1)
% sum(X, 2)
%
% X = int8(1:20)
% sum(X) % returns double(210), accumulates in double
% sum(X,'native') % returns int8(127), because it accumulates in
% % int8 but overflows and saturates.
%
% See also PROD, CUMSUM, DIFF, ACCUMARRAY, ISFLOAT.
% Copyright 1984-2015 The MathWorks, Inc.
% Built-in function.
i.e. it can also be seen from the last line that this is a built-in as per definition. Note that everything contained in the first 'comment' is seen when help sum is typed; in the sense that an empty line breaks the help file. The copyright and built-in information do thus not show up when simply typing help sum on the command line, so for checking whether a function is a built-in you need edit <functionname>.
I would like someone to explain to me those lines of code, please. It might be important to mention that this code is part of a display function.
if isa(obj,'PhArea')
disp(t)
elseif isequal(get(0,'FormatSpacing'),'compact')
disp([inputname(1) '='];
disp(t);
else%that is format loose
disp(' ')
disp([inputname(1) ' =']);
disp(' ');
disp(t)
end
This code just determines how to display the value of a variable t depending on the type of t as well as the current format settings.
% If this is a PhArea instance
if isa(t, 'PhArea)
% Then just display it
disp(t)
% If the user has enabled compact formatting (format compact)
elseif isequal(get(0, 'formatspacing'), 'compact')
% Display the variable's name and an equal sign (no spaces)
disp([inputname(1), '='])
% Display the variable itself
disp(t)
% Otherwise
else
% Display an empty line
disp(' ')
% Display the variable's name and an equal sign (with space)
disp([inputname(1), ' ='])
% Display an empty line
disp(' ')
% Display the variable
disp(t)
end
Update
The following line is the trickiest here.
isequal(get(0, 'formatspacing'), 'compact')
What this does is retrieves the current format spacing. The 0 is the graphics root object which is used to store information that applies to a given MATLAB session. When the user specifies that they want to use 'compact' format spacing, this configuration is stored within the root object.
format loose
get(0, 'formatspacing')
% loose
format compact
get(0, 'formatspacing')
% compact
So by retrieving the current setting as a string, you can then compare it (using isequal) to 'compact' to see if the user wants to use compact format spacing or not.
Background
Matlab has a publish function which outputs a, say, .html file based on the syntax of the comments. Sections which contain example code are indicated by a '%' followed by three spaces. An example function can be seen below, and the .html file generated by the publish function can be seen here.
function randomImage = GenerateRandomImage(n)
%% TestFunction
% generates a random image
%
% randomImage = GenerateRandomImage(n) returns an nxn array of random pixels
%
%% Example
% randomImage = GenerateRandomImage(10);
% figure; imagesc(abs(randomImage));
randomImage = rand(n);
end
Matlab will not automatically evaluate the example code, unless I create a separate script with the example code explicitly uncommitted. An example script is seen below. This time, it automatically includes the outputs of that script, such as the image produced by the example script shown here here.
%% TestFunction
% generates a random image
%
% randomImage = GenerateRandomImage(n) returns an nxn array of random pixels
%
%% Example
randomImage = GenerateRandomImage(10);
figure; imagesc(abs(randomImage));
The Question
Is it possible for the publish function to automatically evaluate the code snippits in the comments of a function and include those outputs in the html file?
The matlab publisher is explicitly meant to be performed on scripts, not function files, since its purpose is to produce a report, where individual sections (marked with %%) become headings, and lines beginning with % immediately under the %% become the description text for that section. Anything that follows after that, both code and comment lines, will be presented by the publisher in a nice little box as the code that was run for that section, and then the results of that code will be shown below that box, but contained within their section.
Putting code in the description text for that section, expecting it to be run is counter-intuitive. In fact, the only reason you might want to put a code snippet in the description is if you wanted to mention some code without running it.
For this reason the publisher provides special syntax (indent by 2 spaces for monotyped text, 3 spaces to add syntax-highlighting to your code).
Publisher is a nice tool, but unfortunately it's fairly limited. The main limitation for me is that you cannot choose which code sections to show results for and which ones not to; it's all or nothing. Therefore I usually resort to a "latex + saved matlab figures + makefile" approach instead for flexible reports. But publisher is nice if you want something quick and dirty; e.g. it's good for keeping a logbook / diary of your work.
Anyway, to answer your question, no, you can't put code in the description and expect it to run. Nor are you expected to 'publish' functions; the fact that a function file responds at all to publishing in the first place is probably more of a side-effect of how publisher gets called more than anything.
clc
clear all
ii=1;
S =cell(size(30,1)); % cell size.
for ii=1:1:3
rand_id= rand(1,1) *3; % Randomly generte a number between 1 to 3.
if (rand_id<1)
rand_id=1; % 0 is ommitted.
else rand_id=floor(rand_id);
end
% rand_id will be used to open a previously saved file randomly.
if (rand_id==1)
f_id_1=fopen('C1.txt','r'); % Open and read a file.
elseif (rand_id==2)
f_id_1=fopen('C2.txt','r'); % Open and read a file.
end
% saning the file to read the text.
events_1=textscan(f_id_1, '%s', 'Delimiter', '\n');
fclose(f_id_1);
events_1=events_1{1}; % saving the text.
rand_event=events_1{randi(numel(events_1))}; % selects one text randomly.
S{ii}=rand_event;
end
I wrote the above code to randomly select a file. The file contains number of sentences. My aim is to randomly pick a sentence . I did that. Now, my problem is I cant save all the picked sentences inside the loop.
When I declare S(ii)=rand_event It shows error. When I try S(ii)=rand_event(ii) It only returns 1, 2, 3 characters in the three loops.
Please help.
S(ii)
is considered to be a matrix with well defined dimensions. I guess that your 'sentences' have different length. One solution might be to use a cell array.
S{ii}=rand_event
Cell arrays use curly braces.