5

I have recently discovered the asymptote package to create 3D figures, I have installed the executable version on my computer and configured TexStudio to run it, only it is done manually using tools> Orders> Asymptote, since the compilation settings for several of the files is not the same I use the Arara tool, I have tried to write a new yaml file in the folder of rules, although I obtain that the compiler tells me that it is executed, but it fails, I need an orientation of how to write correctly the yaml code ...

Here is my attempt ..

!config
# Asymptote rule for arara
# author: None
# last edited by: None
# requires arara 3.0+
identifier: asymptote
name: Asymptote
command: <arara> asy @{options} "@{getBasename(file)}.asy"
arguments:
- identifier: style
  flag: <arara> @{parameters.style}
  default: asy
- identifier: options
  flag: <arara> @{parameters.options}

I'm using this example code to achieve it:

% arara: pdflatex: {synctex: yes, action: nonstopmode}
% arara: asymptote
% arara: pdflatex: {synctex: yes, action: nonstopmode}

\documentclass[12pt]{article}
\usepackage[inline]{asymptote}

\begin{document}

    \begin{center}
        \begin{asy}[width=0.5\textwidth]
        settings.outformat = "png";
        settings.render = 16;
        settings.prc = false;
        real unit = 2cm;
        unitsize(unit);

        import graph3;

        void drawsafe(path3 longpath, pen p, int maxlength = 400) {
        int length = length(longpath);
        if (length <= maxlength) draw(longpath, p);
        else {
        int divider = floor(length/2);
        drawsafe(subpath(longpath, 0, divider), p=p, maxlength=maxlength);
        drawsafe(subpath(longpath, divider, length), p=p, maxlength=maxlength);
        }
        }

        struct helix {
        path3 center;
        path3 helix;
        int numloops;
        int pointsperloop = 12;
        /* t should range from 0 to 1*/
        triple centerpoint(real t) {
        return point(center, t*length(center));
        }
        triple helixpoint(real t) {
        return point(helix, t*length(helix));
        }
        triple helixdirection(real t) {
        return dir(helix, t*length(helix));
        }
        /* the vector from the center point to the point on the helix */
        triple displacement(real t) {
        return helixpoint(t) - centerpoint(t);
        }
        bool iscyclic() {
        return cyclic(helix);
        }
        }

        path3 operator cast(helix h) {
        return h.helix;
        }

        helix helixcircle(triple c = O, real r = 1, triple normal = Z) {
        helix toreturn;
        toreturn.center = c;
        toreturn.helix = Circle(c=O, r=r, normal=normal, n=toreturn.pointsperloop);
        toreturn.numloops = 1;
        return toreturn;
        }

        helix helixAbout(helix center, int numloops, real radius) {
        helix toreturn;
        toreturn.numloops = numloops;
        from toreturn unravel pointsperloop;
        toreturn.center = center.helix;
        int n = numloops * pointsperloop;
        triple[] newhelix;
        for (int i = 0; i <= n; ++i) {
        real theta = (i % pointsperloop) * 2pi / pointsperloop;
        real t = i / n;
        triple ihat = unit(center.displacement(t));
        triple khat = center.helixdirection(t);
        triple jhat = cross(khat, ihat);
        triple newpoint = center.helixpoint(t) + radius*(cos(theta)*ihat + sin(theta)*jhat);
        newhelix.push(newpoint);
        }
        toreturn.helix = graph(newhelix, operator ..);
        return toreturn;
        }

        int loopfactor = 20;
        real radiusfactor = 1/8;
        helix wrap(helix input, int order, int initialloops = 10, real initialradius = 0.6, int loopfactor=loopfactor) {
        helix toreturn = input;
        int loops = initialloops;
        real radius = initialradius;
        for (int i = 1; i <= order; ++i) {
        toreturn = helixAbout(toreturn, loops, radius);
        loops *= loopfactor;
        radius *= radiusfactor;
        }
        return toreturn;
        }

        currentprojection = perspective(12,0,6);

        helix circle = helixcircle(r=2, c=O, normal=Z);

        /* The variable part of the code starts here. */
        int order = 1;    // This line varies.
        real helixradius = 0.5;
        real safefactor = 1;
        for (int i = 1; i < order; ++i)
        safefactor -= radiusfactor^i;
        real saferadius = helixradius * safefactor;

        helix todraw = wrap(circle, order=order, initialradius = helixradius);    // This line varies (optional loopfactor parameter).

        surface torus = surface(Circle(c=2X, r=0.99*saferadius, normal=-Y, n=32), c=O, axis=Z, n=32);
        material toruspen = material(diffusepen=gray, ambientpen=white);
        draw(torus, toruspen);

        drawsafe(todraw, p=0.5purple+linewidth(1pt));  // This line varies (linewidth only).

        \end{asy}
    \end{center}
\end{document}

When compiling the process starts but returns the failure of the operation...

Running PDFLaTeX...

This is pdfTeX, Version 3.14159265-2.6-1.40.19 (MiKTeX 2.9.6670 64-bit)

entering extended mode

Status: SUCCESS

    Running Asymptote...

    FAILURE
4
  • @marmot, thanks for the advice, I'm reviewing that package, I think it requires other additional packages to run, it's not enough to declare \usepackage{asypictureB} and change the environment for \begin{asypicture}, for the shell option in arara I use the configuration % arara : pdflatex: {synctex: yes, action: nonstopmode, shell: yes}, which should be the same as you did, but I get errors, I also compile without using arara with the option pdflatex -shell-escape and I get the same errors, you could provide some MWE I would appreciate it ...
    – J Leon V.
    Commented Apr 25, 2018 at 22:54
  • 1
    I am certainly not at all familiar with arara, but I guess the problem is that the name of the relevant asy file is @{getBasename(file)}-1.asy and not @{getBasename(file)}.asy. And, of course, if there are more asy environments, it will be @{getBasename(file)}-1.asy, @{getBasename(file)}-2.asy etc. So may it simply be that you're missing a -1 in the name?
    – user121799
    Commented Apr 26, 2018 at 3:43
  • Wow, that's the solution, now as we proceed?, the correct code for the automated call of the arara is including the -1 that you suggest command: <arara> asy @{options} "@{getBasename(file)}-1.asy", and it works perfectly, thank you very much, you are a great supporter.
    – J Leon V.
    Commented Apr 26, 2018 at 4:34
  • Yes, it also works with that code, which therefore implies that it is a more general solution, if you can include it in your answer we can close it with that solution. because it is working perfectly.
    – J Leon V.
    Commented Apr 26, 2018 at 15:52

1 Answer 1

1

Temporary answer (to be superseded by arara 4.0): replace

command: <arara> asy @{options} "@{getBasename(file)}.asy"

by

command: <arara> asy @{options} "@{getBasename(file)}-*.asy"

COMMENT: I personally like to use the asypictureB package since it allows one to trigger all the asymptote compilations with a simple pdflatex -shell-escape call. In addition, it also allows you to "smuggle" (expanded) LaTeX macros in the asymptote picture by replacing the backslash \ by @. Applied to your example, the TeX file will be:

\documentclass[12pt]{article}
\usepackage{asypictureB}

\begin{document}

    \begin{center}
        \begin{asypicture}{name=AsyPlot}
        settings.outformat = "png";
        settings.render = 16;
        settings.prc = false;
        real unit = 2cm;
        unitsize(unit);

        import graph3;

        void drawsafe(path3 longpath, pen p, int maxlength = 400) {
        int length = length(longpath);
        if (length <= maxlength) draw(longpath, p);
        else {
        int divider = floor(length/2);
        drawsafe(subpath(longpath, 0, divider), p=p, maxlength=maxlength);
        drawsafe(subpath(longpath, divider, length), p=p, maxlength=maxlength);
        }
        }

        struct helix {
        path3 center;
        path3 helix;
        int numloops;
        int pointsperloop = 12;
        /* t should range from 0 to 1*/
        triple centerpoint(real t) {
        return point(center, t*length(center));
        }
        triple helixpoint(real t) {
        return point(helix, t*length(helix));
        }
        triple helixdirection(real t) {
        return dir(helix, t*length(helix));
        }
        /* the vector from the center point to the point on the helix */
        triple displacement(real t) {
        return helixpoint(t) - centerpoint(t);
        }
        bool iscyclic() {
        return cyclic(helix);
        }
        }

        path3 operator cast(helix h) {
        return h.helix;
        }

        helix helixcircle(triple c = O, real r = 1, triple normal = Z) {
        helix toreturn;
        toreturn.center = c;
        toreturn.helix = Circle(c=O, r=r, normal=normal, n=toreturn.pointsperloop);
        toreturn.numloops = 1;
        return toreturn;
        }

        helix helixAbout(helix center, int numloops, real radius) {
        helix toreturn;
        toreturn.numloops = numloops;
        from toreturn unravel pointsperloop;
        toreturn.center = center.helix;
        int n = numloops * pointsperloop;
        triple[] newhelix;
        for (int i = 0; i <= n; ++i) {
        real theta = (i % pointsperloop) * 2pi / pointsperloop;
        real t = i / n;
        triple ihat = unit(center.displacement(t));
        triple khat = center.helixdirection(t);
        triple jhat = cross(khat, ihat);
        triple newpoint = center.helixpoint(t) + radius*(cos(theta)*ihat + sin(theta)*jhat);
        newhelix.push(newpoint);
        }
        toreturn.helix = graph(newhelix, operator ..);
        return toreturn;
        }

        int loopfactor = 20;
        real radiusfactor = 1/8;
        helix wrap(helix input, int order, int initialloops = 10, real initialradius = 0.6, int loopfactor=loopfactor) {
        helix toreturn = input;
        int loops = initialloops;
        real radius = initialradius;
        for (int i = 1; i <= order; ++i) {
        toreturn = helixAbout(toreturn, loops, radius);
        loops *= loopfactor;
        radius *= radiusfactor;
        }
        return toreturn;
        }

        currentprojection = perspective(12,0,6);

        helix circle = helixcircle(r=2, c=O, normal=Z);

        /* The variable part of the code starts here. */
        int order = 1;    // This line varies.
        real helixradius = 0.5;
        real safefactor = 1;
        for (int i = 1; i < order; ++i)
        safefactor -= radiusfactor^i;
        real saferadius = helixradius * safefactor;

        helix todraw = wrap(circle, order=order, initialradius = helixradius);    // This line varies (optional loopfactor parameter).

        surface torus = surface(Circle(c=2X, r=0.99*saferadius, normal=-Y, n=32), c=O, axis=Z, n=32);
        material toruspen = material(diffusepen=gray, ambientpen=white);
        draw(torus, toruspen);

        drawsafe(todraw, p=0.5purple+linewidth(1pt));  // This line varies (linewidth only).

        \end{asypicture}
    \end{center}
\end{document}

produces when compiled with pdflatex -shell-escape

enter image description here

COMMENT:I did not create the torus, all I did is to use asypictureB.

2
  • thanks for the code, however small the modification is, it is well appreciated, with this I can confirm that it is my installation or some configuration that is not well done, I will investigate about it, while I will wait for someone to help me with the command of arara , since it works manually and I'm looking to automate that, thanks anyway. so the upvotes, I think we have to maintain its use, it has helped me to confirm that something is wrong so why not ...
    – J Leon V.
    Commented Apr 26, 2018 at 2:44
  • 1
    @JLeonV. see also github.com/cereda/arara, it's a good way to communicate with Paulo
    – cmhughes
    Commented Apr 26, 2018 at 14:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .