4

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
  • @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. Apr 25 '18 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? – marmot Apr 26 '18 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. Apr 26 '18 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. Apr 26 '18 at 15:52
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.

  • 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. Apr 26 '18 at 2:44
  • 1
    @JLeonV. see also github.com/cereda/arara, it's a good way to communicate with Paulo – cmhughes Apr 26 '18 at 14:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.