Imported Upstream version 2.3.2
authorDimitrios Eftaxiopoulos <eftaxi12@otenet.gr>
Sat, 7 Feb 2015 19:26:59 +0000 (21:26 +0200)
committerDimitrios Eftaxiopoulos <eftaxi12@otenet.gr>
Sat, 7 Feb 2015 19:26:59 +0000 (21:26 +0200)
66 files changed:
CMakeLists.txt
ChangeLog.txt
examples/full_test.cpp
include/config.h.in
include/mgl2/addon.h
include/mgl2/base.h
include/mgl2/define.h
include/mgl2/font.h
include/mgl2/opengl.h
include/mgl2/parser.h
include/mgl2/qmathgl.h
json/mathgl.Graph.js
lang/CMakeLists.txt
mgltex/mgltex.dtx
mgltex/mgltex.ins [new file with mode: 0644]
mgltex/mgltex.installer [deleted file]
mgltex/mgltex.pdf
mgltex/mgltex.sty
mgltex/sample.tex
src/addon.cpp
src/axis.cpp
src/base.cpp
src/base_cf.cpp
src/canvas.cpp
src/complex.cpp
src/complex_io.cpp
src/cont.cpp
src/data.cpp
src/data_ex.cpp
src/data_gr.cpp
src/data_io.cpp
src/data_png.cpp
src/evalp.cpp
src/exec.cpp
src/export.cpp
src/export_2d.cpp
src/export_3d.cpp
src/fft.cpp
src/fit.cpp
src/font.cpp
src/interp.hpp
src/opengl.cpp
src/parser.cpp
src/pixel.cpp
src/plot.cpp
src/surf.cpp
texinfo/core_en.texi
texinfo/core_ru.texi
texinfo/doc_en.texi
texinfo/doc_ru.texi
texinfo/ex_mgl_en.texi
texinfo/ex_mgl_ru.texi
texinfo/version.texi
texinfo/version_hist.txt
texinfo/web_en.texi
texinfo/web_ru.texi
todo.txt
udav/calc_dlg.cpp
udav/mgl.xml [new file with mode: 0644]
udav/open_dlg.cpp
udav/udav.desktop
udav/udav_wnd.cpp
utils/mglconv.cpp
widgets/fltk.cpp
widgets/glut.cpp
widgets/qt.cpp

index 4a4076e2b50d8f5eb169b2a544203b056b0324f1..b369da1f51651652c0aae167e3c78c17eff84849 100644 (file)
@@ -1,4 +1,7 @@
 cmake_minimum_required(VERSION 2.8.9)
+if(POLICY CMP0043)
+    cmake_policy(SET CMP0043 OLD)
+endif()
 
 project( MathGL )
 
@@ -69,6 +72,11 @@ option(enable-all-swig "Enable all SWIG based interfaces")
 option(enable-rvalue "Enable move constructor support (need C++11)" OFF)
 option(enable-pthread "Enable POSIX threads support" OFF)
 option(enable-openmp "Enable OpenMP support" ON)
+
+if(enable-pthread AND enable-openmp)
+       message(SEND_ERROR "You can't enable POSIX threads and OpenMP at the same time!")
+endif(enable-pthread AND enable-openmp)
+
 option(enable-lgpl "Enable only LGPL part of MathGL")
 option(enable-mgl2 "Use names 'libmgl2-*' instead of 'libmgl-*'")
 option(enable-ltdl "Enable loading modules support")
@@ -116,6 +124,7 @@ MGL_DEPENDENT_OPTION(enable-octave-install "Octave interface will install for al
 include_directories( ${MathGL_SOURCE_DIR}/include ${MathGL_BINARY_DIR}/include)
 set(MGL_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/include/mgl2")
 set(MGL_CGI_PATH "${CMAKE_INSTALL_PREFIX}/share/mathgl" CACHE STRING "Set CGI install directory")
+set(MGL_DEF_FONT "STIX" CACHE STRING "Set default font name")
 
 if(NOT WIN32)
 #      set(MGL_CGI_PATH "${CMAKE_INSTALL_PREFIX}/share/mathgl")
index 5c2363f62e98a7d062e611e148ccb3fbcf1f3dd2..716ad27e11fb2f5b0864cd0e1801c4df170ef05f 100644 (file)
@@ -1,4 +1,14 @@
-2.3.1 Released 20 October 2014
+2.3.2 Released 2 February 2015
+
+* Update mgltex (thanks to Diego Sejas Viscarra)
+* Add reading files with complex numbers by 'read' command.
+* Parallelize reading textual data files.
+* Add 'i','j','k' variables for data filling.
+* Add saving images in QMathGL even if corresponding format support is disabled.
+* Add cmake option MGL_DEF_FONT to change default font name or use built-in one (if MGL_DEF_FONT is empty).
+* Compatibility changes and bugfixes.
+
+2.3.1 Released 21 October 2014
 
 * Add MGL command 'load' for loading MGL commands from external DLL (or .so) module.
 * Add Logo() function to draw bitmap (logo), which is stretched along whole axis range
index c6605dc579992c5b35c5bb409b9912c6f3636e84..4f2a46532b3c6e3feb4ac5dfb2a2251d9dd9c580 100644 (file)
@@ -64,7 +64,6 @@ void mgls_prepare3v(mglData *ex, mglData *ey, mglData *ez);
 void save(mglGraph *gr,const char *name,const char *suf);\r
 void test(mglGraph *gr)\r
 {\r
-//     gr->Rotate(40,60);      gr->Fog(1);     gr->Box();      return;\r
        mglParse par;\r
        par.Execute(gr,"load '/home/balakin/mathgl-code/mathgl-2x/build/examples/libmgl_module.so':baxis\n");\r
 //     par.Execute(gr,"subplot 1 1 0:#rotate 40 60\nperspective 1.22:box:axis\n");\r
@@ -365,7 +364,7 @@ void smgl_fexport(mglGraph *gr)     // test file export
        gr->WriteOBJ("fexport.obj");\r
        gr->WritePRC("fexport.prc");\r
        gr->WriteJSON("fexport.json");\r
-       \r
+\r
        gr->ExportMGLD("fexport.mgld");\r
        gr->Clf();\r
        gr->ImportMGLD("fexport.mgld");\r
@@ -417,7 +416,11 @@ int main(int argc,char **argv)
        {\r
                mgl_set_test_mode(true);        test(gr);\r
                time(&en);      printf("time is %g sec\n",difftime(en,st));\r
+#if MGL_HAVE_PNG\r
                gr->WritePNG("test.png","",false);\r
+#else\r
+               gr->WriteBMP("test.bmp");\r
+#endif\r
                gr->WriteSVG("test.svg");\r
                gr->WriteEPS("test.eps");\r
                printf("Messages:%s\n",gr->Message());\r
index de1ea33d4ca0794591a2b1f7fce13efdd38ef36c..51d37307e75f61a5cb33a918929e7a11db46d789 100644 (file)
@@ -3,6 +3,12 @@
 
 #define MGL_USE_DOUBLE ${MGL_USE_DOUBLE}
 
+#ifdef WIN32   // a man ask to use built-in font under Windows
+#define MGL_DEF_FONT_NAME      ""
+#else
+#define MGL_DEF_FONT_NAME      "${MGL_DEF_FONT}"
+#endif
+
 #if defined(_MSC_VER) || defined(__BORLANDC__)
 #define MGL_SYS_NAN            0
 #define MGL_HAVE_TYPEOF        0
index b083469fd365e3bbb54b5e9545ff3d18784afbf0..5896c362ccba6e803c03c97cd4f96cb504303d4b 100644 (file)
@@ -40,9 +40,9 @@ void MGL_EXPORT mgl_fft_freq(double *freq,long nn);
 /// Remove double spaces from the string
 void MGL_EXPORT mgl_strcls(char *str);
 /// Get position of substring or return -1 if not found
-int MGL_EXPORT_PURE mgl_strpos(const char *str,char *fnd);
+long MGL_EXPORT_PURE mgl_strpos(const char *str,char *fnd);
 /// Get position of symbol or return -1 if not found
-int MGL_EXPORT_PURE mgl_chrpos(const char *str,char fnd);
+long MGL_EXPORT_PURE mgl_chrpos(const char *str,char fnd);
 
 /// Get uncommented string from file (NOTE: it is not thread safe!!!)
 MGL_EXPORT char *mgl_fgetstr(FILE *fp);
index dea1383684c04063e20780f1ce19515c99a1f1e8..40244fcfa0e5bcb8f1e68980aca61e6beb5ebfa8 100644 (file)
@@ -44,7 +44,7 @@ mglPoint GetZ(HCDT z, int i, int j, int k=0);
 template <class T> class mglStack\r
 {\r
        T** dat;\r
-       size_t pb;      ///< size of buffer (real size is 2^pb == 1<<pb)\r
+       size_t pb;      ///< size of buffer (real size is 2^pb == 1L<<pb)\r
        size_t np;      ///< allocated pointers\r
        size_t m;       ///< used pointers (allocated size is m*nb)\r
        size_t n;       ///< used cells\r
@@ -54,12 +54,12 @@ public:
        {\r
                np=st.np;       dat = (T**)malloc(np*sizeof(T*));\r
                pb=st.pb;       m=n=0;  reserve(st.n);\r
-               for(size_t i=0;i<m;i++) memcpy(dat[i],st.dat[i],(1<<pb)*sizeof(T));\r
+               for(size_t i=0;i<m;i++) memcpy(dat[i],st.dat[i],(1L<<pb)*sizeof(T));\r
                n=st.n;         mutex = 0;\r
        }\r
        mglStack(size_t Pbuf=10)\r
        {       np=16;  pb=Pbuf;        dat = (T**)malloc(np*sizeof(T*));\r
-               dat[0] = new T[1<<pb];  n=0;    m=1;    mutex = 0;      }\r
+               dat[0] = new T[1L<<pb]; n=0;    m=1;    mutex = 0;      }\r
        ~mglStack()     {       clear();        delete [](dat[0]);      free(dat);      }\r
        inline void set_mutex(void *m)  {       mutex = m;      }\r
        void reserve(size_t num)\r
@@ -70,7 +70,7 @@ public:
                        num = 1+ (num>>pb);\r
                        if(num>np)\r
                        {       dat = (T**)realloc(dat, num*sizeof(T*));        np=num; }\r
-                       for(size_t i=m;i<num;i++)       dat[i] = new T[1<<pb];\r
+                       for(size_t i=m;i<num;i++)       dat[i] = new T[1L<<pb];\r
                        m = num;\r
                }\r
        }\r
@@ -85,7 +85,7 @@ public:
 #endif\r
                }\r
                for(size_t i=0;i<m;i++) delete [](dat[i]);\r
-               dat[0] = new T[1<<pb];  n=0;    m=1;\r
+               dat[0] = new T[1L<<pb]; n=0;    m=1;\r
                if(mutex)\r
                {\r
 #if MGL_HAVE_PTHREAD\r
@@ -107,7 +107,7 @@ public:
        const mglStack<T> &operator=(const mglStack<T> &st)\r
        {\r
                pb=st.pb;       clear();        reserve(st.n);\r
-               for(size_t i=0;i<st.m && i<m;i++)       memcpy(dat[i],st.dat[i],(1<<pb)*sizeof(T));\r
+               for(size_t i=0;i<st.m && i<m;i++)       memcpy(dat[i],st.dat[i],(1L<<pb)*sizeof(T));\r
                n = st.n;       return st;\r
        }\r
 };\r
index ef8b17c19ad6b98fc995a8c85760e286d7d760b8..ef91810e4f8c2482d7d6b2c1f07f31619ae8ad26 100644 (file)
@@ -94,7 +94,7 @@ typedef unsigned long uintptr_t;
 #include <wchar.h>\r
 \r
 #if defined(_MSC_VER)\r
-#if (_MSC_VER<1800)\r
+#if (_MSC_VER<=1800)\r
 #define collapse(a)    // MSVS don't support OpenMP 3.*\r
 #define strtoull _strtoui64\r
 #define hypot  _hypot\r
@@ -177,16 +177,6 @@ typedef float mreal;
 #define mgl_sign(a)            ((a)<0 ? -1:1)\r
 #endif\r
 //-----------------------------------------------------------------------------\r
-#define SMOOTH_NONE            0\r
-#define SMOOTH_LINE_3  1\r
-#define SMOOTH_LINE_5  2\r
-#define SMOOTH_QUAD_5  3\r
-//-----------------------------------------------------------------------------\r
-#define MGL_HIST_IN            0\r
-#define MGL_HIST_SUM   1\r
-#define MGL_HIST_UP            2\r
-#define MGL_HIST_DOWN  3\r
-//-----------------------------------------------------------------------------\r
 enum{  // types of predefined curvelinear coordinate systems\r
        mglCartesian = 0,       // no transformation\r
        mglPolar,\r
@@ -274,8 +264,14 @@ extern uint64_t mgl_mask_val[16];
 #include <complex.h>\r
 #if MGL_USE_DOUBLE\r
 typedef double _Complex mdual;\r
+#ifndef _Complex_I\r
+#define _Complex_I (double _Complex){0, 1}\r
+#endif\r
 #else\r
 typedef float _Complex mdual;\r
+#ifndef _Complex_I\r
+#define _Complex_I (float _Complex){0, 1}\r
+#endif\r
 #endif\r
 #define mgl_abs(x)     cabs(x)\r
 #endif\r
index 2e08a018675b61cdd63bba0f8b37ad14ec12399d..dcb23b52d54ddbee7fc16d4b166b7d236fc63629 100644 (file)
 #define MGL_COLOR_MASK         0xffffff00\r
 #define MGL_FONT_STYLE         0x3f000000\r
 //-----------------------------------------------------------------------------\r
-#ifdef WIN32   // a man ask to use built-in font under Windows\r
-#define MGL_DEF_FONT_NAME      0\r
-#else\r
-#define MGL_DEF_FONT_NAME      "STIX"\r
-#endif\r
-//-----------------------------------------------------------------------------\r
 struct mglGlyphDescr\r
 {\r
        wchar_t id;             ///< Unicode ID for glyph\r
index c95a310febfeeec2b16a9eb596fa9abc595ee7ba..a8590435e091a32cd555f86dbb3b7ce82b627f47 100644 (file)
@@ -30,7 +30,7 @@ public:
 \r
        void SetQuality(int =0) {       Quality=2;      }\r
        void Finish();\r
-       void SetSize(int ,int ) {}\r
+       void SetSize(int ,int ,bool clf=true)   {       if(clf) Clf();  }\r
        void View(mreal tetX,mreal tetY,mreal tetZ);\r
        void Zoom(mreal x1, mreal y1, mreal x2, mreal y2);\r
 /*     int NewFrame();\r
@@ -43,6 +43,7 @@ public:
        void Light(int n, bool enable);\r
        void AddLight(int n,mglPoint r,mglPoint d, char c='w', mreal bright=0.5, mreal ap=0);\r
        void Clf(mglColor Back=NC);\r
+       void Clf(const char *col);\r
 \r
 protected:\r
        // provide fastest variant for usual points (not glyphs or marks)\r
index 0fe0f23710110a48cef4fb657d6aef62c90a34ed..3ff6fa43e735c09b1bd0f1702dc0beb4caf1a6a6 100644 (file)
@@ -100,6 +100,7 @@ public:
        bool Stop;                      ///< Stop command was. Flag prevent further execution\r
        mglCommand *Cmd;        ///< Table of MGL commands (can be changed by user). It MUST be sorted by 'name'!!!\r
        long InUse;                     ///< Smart pointer (number of users)\r
+       const mglBase *curGr;   ///< Current grapher\r
 \r
        mglParser(bool setsize=false);\r
        virtual ~mglParser();\r
index e416d7d56dd3c59a2d2570a33104f09bddb5ce1f..53241dfe1097bdcc75eee06724f15754ad3a2778 100644 (file)
@@ -181,6 +181,7 @@ protected:
        mglDraw *draw;          ///< Class for drawing -- need to call directly due to inheritance mechanism\r
        QString mousePos;       ///< Last mouse position\r
        QPixmap pic;            ///< Pixmap for drawing (changed by update)\r
+       QImage img;                     ///< Last used HQ image\r
        double tet, phi;        ///< Rotation angles\r
        double per;                     ///< Value of perspective ( must be in [0,1) )\r
        bool alpha;                     ///< Transparency state\r
@@ -223,7 +224,7 @@ public:
 };\r
 //-----------------------------------------------------------------------------\r
 /// Convert bitmap from mglCanvasWnd to QPixmap\r
-void mglConvertFromGraph(QPixmap &pic, mglCanvas *gr, uchar **buf);\r
+void mglConvertFromGraph(QPixmap &pic, mglCanvas *gr, uchar **buf, QImage *out=NULL);\r
 /// Make menu, toolbars and return popup menu for MainWindow\r
 MGL_EXPORT QMenu *mglMakeMenu(QMainWindow* Wnd, QMathGL* QMGL, QSpinBox*& tet, QSpinBox*& phi);\r
 //-----------------------------------------------------------------------------\r
index 5ae698496a2f051e129ab0e6e1ea0403ccc64873..d505b47934ba3798864ea944f561a91a608ad82c 100644 (file)
@@ -25,8 +25,8 @@ mathgl.Graph = function(canvas, backend) {
        this.__fov = 0;         // perspective
        this.__x1 = 0;  this.__y1 = 0;  this.__z1 = 0;
        this.__x2 = 1;  this.__y2 = 1;  this.__z2 = 1;
-}
-
+       this.__activeTimeoutHandlers = [];
+};
 
 /**
  * Initialize current view by given MGL script.
@@ -47,6 +47,28 @@ mathgl.Graph.prototype.init = function(mgl) {
        this.__view.attachCanvas(this.__canvas);
 }
 
+/**
+ * Method uses to wrap native JS setTimeout function to make possible deactivate active callbacks in destroy method
+ *
+ * @param func {Function} Callback function, will be executed after delay
+ * @param delay {Number} Delay before callback call
+ */
+mathgl.Graph.prototype.__setTimeout = function(func, delay) {
+       var me = this;
+       var timeoutFunc = function() {
+               func.call();
+               var index = me.__activeTimeoutHandlers.indexOf(this.setTimeoutId);
+               if (index > -1) {
+                       // remove timeout from activeTimeoutHandlers list
+                       me.__activeTimeoutHandlers.splice(index, 1);
+               }
+       }
+
+       var timeoutId = setTimeout(mathgl.bind(timeoutFunc, timeoutFunc), delay);
+       // keep timeout handler inside function
+       timeoutFunc.setTimeoutId = timeoutId;
+       this.__activeTimeoutHandlers.push(timeoutId);
+};
 
 /**
  * Load graph state from JSON string.
@@ -136,7 +158,7 @@ mathgl.Graph.prototype.__renderStart = function() {
        if (!this.__isDraftRenderingInScheduled) {
                // enqueue draft rendering step
                this.__isDraftRenderingInScheduled = true;
-               setTimeout(mathgl.bind(this.__renderDraft, this), 0);
+               this.__setTimeout(mathgl.bind(this.__renderDraft, this), 0);
        }
 }
 
@@ -149,7 +171,7 @@ mathgl.Graph.prototype.__renderDraft = function() {
        // enqueue precise rendering step
        if (!this.__isPreciseRenderingScheduled) {
                this.__isPreciseRenderingScheduled = true;
-               setTimeout(mathgl.bind(this.__renderPrecise, this), this.__preciseRenderingDelay);
+               this.__setTimeout(mathgl.bind(this.__renderPrecise, this), this.__preciseRenderingDelay);
        }
        this.__draftFinishedTimestamp = new Date();
 }
@@ -167,7 +189,7 @@ mathgl.Graph.prototype.__renderPrecise = function() {
        // rechedule pricese rendering if it is not
        var current = new Date();
        if (current - this.__draftFinishedTimestamp < this.__preciseRenderingDelay) {
-               setTimeout(mathgl.bind(this.__renderPrecise, this), this.__preciseRenderingDelay - (current - this.__draftFinishedTimestamp));
+               this.__setTimeout(mathgl.bind(this.__renderPrecise, this), this.__preciseRenderingDelay - (current - this.__draftFinishedTimestamp));
                return;
        }
        this.__drawMesh(true);
@@ -626,6 +648,11 @@ mathgl.Graph.prototype.redraw = function() {
 }
 
 mathgl.Graph.prototype.destroy = function() {
+       // clear active timeouts
+       for (var i = 0, l = this.__activeTimeoutHandlers.length; i<l; i++) {
+               var th = this.__activeTimeoutHandlers.pop();
+               clearTimeout(th);
+       }
        this.__view.destroy();
        this.__view = null;
        this.__backend = null;
index c15a950b4add2a401decabffdcfd390681aded9e..d6b84c107ceb5db9ba79d08c195d0079bf79b940 100644 (file)
@@ -37,7 +37,7 @@ if(enable-python)
                message(SEND_ERROR "Couldn't find numpy.")
        endif(NOT NUMPY_INCLUDE_PATH)
 
-       include_directories(${PYTHON_INCLUDE_DIR})
+       include_directories(${PYTHON_INCLUDE_DIR}  ${NUMPY_INCLUDE_PATH})
        execute_process(
                COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(prefix='${CMAKE_INSTALL_PREFIX}')"
                OUTPUT_VARIABLE MGL_PYTHON_SITE_PACKAGES
@@ -98,27 +98,27 @@ if(enable-octave)
        execute_process(COMMAND ${oct_prog} -p API_VERSION
        OUTPUT_VARIABLE oct_api
        OUTPUT_STRIP_TRAILING_WHITESPACE)
-       execute_process(COMMAND ${oct_prog} -p OCTINCLUDEDIR
+       execute_process(COMMAND ${oct_mk} -p INCFLAGS
        OUTPUT_VARIABLE oct_inc
        OUTPUT_STRIP_TRAILING_WHITESPACE)
+       separate_arguments(oct_inc)
 message(STATUS "${oct_prog} ${oct_host} ${oct_api}")
        set(oct_arch ${oct_host}-${oct_api})
        set(pkg_name mathgl)
        set(mgl_pkg_dir ${MathGL_BINARY_DIR}/lang/${pkg_name}/inst/${oct_arch})
 
-       include_directories(${oct_inc} ${oct_inc}/..)
+       add_compile_options(${oct_inc})
        SET(SWIG_MODULE_mgl-oct_EXTRA_DEPS numpy.i ${src_imp_dep})
        SWIG_ADD_MODULE(mgl-oct octave mathgl.i)
        SWIG_LINK_LIBRARIES(mgl-oct mgl)
        set_target_properties(mgl-oct PROPERTIES OUTPUT_NAME mathgl PREFIX "" SUFFIX ".oct" BUILD_WITH_INSTALL_RPATH ON)
-       get_target_property(mgl-oct_filename mgl-oct LOCATION)
        add_custom_command(OUTPUT mathgl.tar.gz
                COMMAND ${CMAKE_COMMAND} -E make_directory ${mgl_pkg_dir}
                COMMAND ${CMAKE_COMMAND} -E copy ${MathGL_SOURCE_DIR}/COPYING ${MathGL_BINARY_DIR}/lang/${pkg_name}
                COMMAND ${CMAKE_COMMAND} -E copy ${MathGL_SOURCE_DIR}/lang/DESCRIPTION ${MathGL_BINARY_DIR}/lang/${pkg_name}
                COMMAND ${CMAKE_COMMAND} -E copy ${MathGL_SOURCE_DIR}/lang/INDEX ${MathGL_BINARY_DIR}/lang/${pkg_name}
                COMMAND ${CMAKE_COMMAND} -E copy ${MathGL_SOURCE_DIR}/lang/PKG_ADD_template ${MathGL_BINARY_DIR}/lang/${pkg_name}
-               COMMAND ${CMAKE_COMMAND} -E copy ${mgl-oct_filename} ${mgl_pkg_dir}
+               COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:mgl-oct> ${mgl_pkg_dir}
                COMMAND ${oct_tar} cpzf mathgl.tar.gz ${pkg_name}
                WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/lang
                DEPENDS mgl-oct
index 77e480aa7f26f60b746e2727a51f88d04525b015..34dedaecfef747222d65bbc018073d439f9827c3 100644 (file)
 % \fi
 % 
 % \iffalse
-%<package>\def\mgl@name{mgltex}
-%<package>\def\mgl@date{2014/09/16}
-%<package>\def\mgl@version{1.0}
-%<package>\def\mgl@description{Embed MGL code into LaTeX documents}
-%<package>
+%
 %<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{\mgl@name}[\mgl@date\space v.\mgl@version\space\mgl@description]
+%<package>\ProvidesPackage{mgltex}[/2014/11/22 v2.0 Embed MGL scripts in LaTeX documents]
 % 
 %<*driver>
 \documentclass{ltxdoc}
-\usepackage{mgltex}
-\def\linefill#1{%
-  \leavevmode\leaders\hrule height #1\hfill\kern0em%
-}
+\usepackage{color}
+\usepackage[comments]{mgltex}
 \EnableCrossrefs
 \CodelineIndex
 \RecordChanges
@@ -41,7 +35,7 @@
 %</driver>
 % \fi
 % 
-% \CheckSum{0}
+% \CheckSum{1297}
 % 
 % \CharacterTable
 %  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
 %   Right brace   \}     Tilde         \~}
 % 
 % \changes{v1.0}{2014/09/27}{Initial version}
+% \changes{v.2.0}{2014/11/15}{Possible bugfix by adding \texttt{\textbackslash expandafter} to commands to ignore/write lines of MGL code}
+% \changes{v.2.0}{2014/11/15}{Add environment \texttt{mglsignature} that adds a commentary every MGL script}
+% \changes{v.2.0}{2014/11/15}{Eliminate line ignoring commands to create more elegant scripts, due to the a new command that adds comments to the scripts}
 % 
 % \GetFileInfo{mgltex.sty}
 % 
-% \DoNotIndex{}
+% \DoNotIndex{\def,\bgroup,\egroup,\newcommand,\newenvironment,\\,\@onlypreamble,\@undefined,\@vobeyspaces,\list}
+% \DoNotIndex{\if,\else,\fi,\begingroup,\endgroup,\end,\edef,\xdef,\gdef,\scapechar,\active,\arabic,\catcode,\bfseries}
+% \DoNotIndex{\@flushglue,\@for,\@ifnextchar,\@makeother,\{,\},\^,\ ,\AtBeginDocument,\AtEndDocument,\centering}
+% \DoNotIndex{\closein,\closeout,\csname,\endcsname,\CurrentOption,\DeclareGraphicsExtensions,\define@key,\DeclareOption}
+% \DoNotIndex{\detokenize,\do,\dospecials,\endlinechar,\endlist,\escapechar,\ExecuteOptions,\expandafter,\footnotesize}
+% \DoNotIndex{\framebox,\Gin@extensions,\Huge,\ifeof,\IfFileExists,\ifx,\immediate,\include,\includegraphics,\item,\itemsep}
+% \DoNotIndex{\itshape,\jobname,\labelsep,\leftskip,\let,\long,\mbox,\newcounter,\newread,\newtoks,\newwrite,\noexpand}
+% \DoNotIndex{\obeyspaces,\openin,\openout,\PackageError,\PackageWarning,\parfillskip,\parindent,\parskip}
+% \DoNotIndex{\PassOptionsToPackage,\ProcessOptions,\read,\relax,\RequirePackage,\rightskip,\setcounter,\setkeys,\setlength}
+% \DoNotIndex{\space,\stepcounter,\string,\TeX,\the,\vbox,\verbatim@font,\write,\z@,\z@skip,\newif,\PackageInfo,\today}
+% \DoNotIndex{\obeylines,\or\ifcase,\small}
 % 
 % \title{The \textsf{\mglTeX} package\thanks{This document corresponds to \textsf{\mglTeX}~\fileversion, dated \filedate.}}
 % \author{Diego Sejas Viscarra\\\texttt{diego.mathematician@gmail.com}}
@@ -71,7 +78,9 @@
 % \maketitle
 % 
 % \begin{abstract}
-%   \noindent 
+%   \noindent MathGL is a fast and efficient library by Alexey Balakin for the creation of high-quality publication-ready scientific graphics. Although it defines interfaces for many programming languages, it also implements its own programming language, called \emph{MGL}, which can be used independently. With the package \textsf{\mglTeX}, MGL scripts can be embedded within any \LaTeX{} document, and the corresponding images are automatically created and included.
+
+% This manual documents the use of the commands and environments of~\mglTeX.
 % \end{abstract}
 % 
 % \section{Introduction}
 % \begin{itemize}
 %   \item |draft|: The generated images won't be included in the document. This option is useful when fast compilation of the document is needed.
 %   \item |final|: This overrides the |draft| option.
+%   \item |on|: To create the MGL scripts and corresponding images of the document every time \LaTeX{} is run.
+%   \item |off|: To avoid creating the MGL scripts and corresponding images of the document, but still try to include the images.
+%   \item |comments|: To allow the contents of the |mglcomment| environments to be shown in the \LaTeX{} document.
+%   \item |nocomments|: To not show the contents of the |mglcomment| environments in the \LaTeX{} document.
 %   \item |png|, |jpg|, |jpeg|: To export images to the corresponding bitmap format.
 %   \item |eps|, |epsz|: To export to uncompressed/compressed EPS format as primitives.
 %   \item |bps|, |bpsz|: To export to uncompressed/compressed EPS format as bitmap.
 %   \item |pdf|: To export to 3D PDF format.
+%   \item |tex|: To export to \LaTeX{}/\emph{tikz} document.
 % \end{itemize}
-% It must be noted that the options that specify the format to save the images are exclusive, in the sense that if one specifies more than one format, only the last one will be used.
+% It must be noted that the options |on| and |off| are exclusive, in the sense that if one specifies both of them, only the last one will be used. Likewise, the options that specify the format to save the graphics are exclusive.
+% 
+% Observe the option |off| is useful to save compilation time of a document. For example, if the graphics of an article are in final version, instead of compilling them over and over again every time \LaTeX{} runs, they can be created only once with the |on| option, and then only included (but not recompiled) with the |off| option.
 % 
 % The are two ways to compile a document with \textsf{\mglTeX}: The first way is to run
 % \begin{center}
 %   \end{tabular}
 % \end{center}
 % 
+% \DescribeEnv{mglcommon} This is used to create a common ``setup'' script that will be executed together with each of the other scripts. It is useful to define constants, parameters, etc. that will be available to every script. 
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\begin{mglcommon}|\\[0.5em]
+%       \hss\meta{MGL code}\hss\\[0.5em]
+%     |\end{mglcommon}|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+% 
+% For example, one could make
+% \begin{verbatim}
+% \begin{mglcommon}
+% define gravity 9.81 # [m/s^2]
+% \end{mglcommon}
+% \end{verbatim}
+% to make the constant \emph{gravity} available to every script.
+% 
+% Observe this environment should be used only to define constants, parameters and things like that, but not graphical objects like axis or grids, because every image created with the |mgl| environment clears every graphical object before creating the image.\footnote{This problem occurs only with the \texttt{mgl} environment, so you could use \texttt{mglcommon} to create many graphics with the same axis, grid, etc., with environments like \texttt{mglcode}, but in that case the best option is to use the \texttt{mglsetup} environment together with the \texttt{\textbackslash{}mglplot} command.}
+% 
+% \DescribeEnv{mglsignature} This environment is used to declare a signature (or commentary) that will be included at the beginning of every script generated by \mglTeX. It is verbatim-like environment, so no \LaTeX{} cammand will be executed, but copied literally. However, the default signature is ``This script was generated from \meta{document}.mgl on date \meta{today}''.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\begin{mglsignature}|\\[0.5em]
+%       \hss\meta{Signature for MGL scripts}\hss\\[0.5em]
+%     |\end{mglsignature}|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+% 
+% \DescribeEnv{mglcomment} This environment is used to embed commentaries in the \LaTeX{} document. The commentary won't appear in the case of the user passing the option |nocomments| to the package, but it will be written \emph{verbatim} is the user passes the option |comments|.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\begin{mglcomment}|\\[0.5em]
+%       \hss\meta{Commentary}\hss\\[0.5em]
+%     |\end{mglcomment}|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+% In the case of the user allowing commentaries, this will result in the appearance of the following commentary in the \LaTeX{} document:
+% \begin{center}
+% \makeatletter
+% \verbatim@font
+% \makeatother
+% <------------------ MGL comment ------------------>\\
+% \meta{Commentary}\\
+% <------------------ MGL comment ------------------>\\
+% \end{center}
+% 
 % \subsection{Fast creation of graphics}
-% \noindent\textsf{\mglTeX} defines a convenient way to work with many graphics that have exactly the same settings (for example, same angles of rotation, same type of grid, etc.): instead of writing repetitive code every time it's needed, it can be stored in memory with the |mglplotsettings| environment, and then can be used when needed with the |\mglplot| command.
+% \noindent\textsf{\mglTeX} defines a convenient way to work with many graphics that have exactly the same settings (for example, same angles of rotation, same type of grid, etc.): instead of writing repetitive code every time it's needed, it can be stored in memory with the |mglsetup| environment, and then can be used when needed with the |\mglplot| command.
 % 
-% \DescribeEnv{mglplotsettings} This environment stores its contents in memory for later use. It accepts one mandatory argument, which is a keyword (name) to be associated to the corresponding block of code, so different blocks of code can be stored with different names.
+% \DescribeEnv{mglsetup} This environment stores its contents in memory for later use. It accepts one optional argument, which is a keyword (name) to be associated to the corresponding block of code, so different blocks of code can be stored with different names.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
-%     |\begin{mglplotsettings}|\marg{keyword}\\[0.5em]
+%     |\begin{mglsetup}|\oarg{keyword}\\[0.5em]
 %       \hss\meta{MGL code}\hss\\[0.5em]
-%     |\end{mglplotsettings}|\\[0.25em]
+%     |\end{mglsetup}|\\[0.25em]
 %     \hline
 %   \end{tabular}
 % \end{center}
 % 
-% \DescribeMacro{\mglplot} This command is used for fast generation of graphics with default settings, and can be used in parallel with the |mglplotsettings| environment. It accepts one mandatory argument which consists of MGL instructions, separated by the symbol ``:'', which can span through various text lines. It also accepts the same optional arguments as the |mgl| environment, plus an additional one, called |settings|, which can be used to specify a keyword used in a |mglplotsettings| environment. If the |settings| option is specified, the code in the mandatory argument will be appended to the block of code of the corresponding |mglplotsettings| environment.
+% \DescribeMacro{\mglplot} This command is used for fast generation of graphics with default settings, and can be used in parallel with the |mglsetup| environment. It accepts one mandatory argument which consists of MGL instructions, separated by the symbol ``:'', which can span through various text lines. It also accepts the same optional arguments as the |mgl| environment, plus an additional one, called |settings|, which can be used to specify a keyword used in a |mglsetup| environment. If the |settings| option is specified, the code in the mandatory argument will be appended to the block of code of the corresponding |mglsetup| environment.
 % \begin{center}
 %   \begin{tabular}{l}
 %     \hline\\[-0.75em]
 % \end{center}
 % This command must be used in the preamble of the document, since the first MGL script is created at the moment of the |\begin{document}| command; trying to use it somewhere else will issue an error. On the other hand, it is the responsibility of the user to create the \meta{directory}, since \textsf{\mglTeX} won't do it automatically.
 % 
+% \DescribeMacro{\mglquality} This command can be used to specify the quality for the graphics created with \mglTeX. An info message specifying the characteristics of the chosen quality is printed in the .log file.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglquality|\marg{quality}\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+% The available qualities are described below:
+% \begin{center}
+%   \begin{tabular}{cl}
+%     \hline
+%     Quality & Description\\
+%     \hline
+%     \hline
+%     $0$ & No face drawing (fastest)\\
+%     \hline
+%     $1$ & No color interpolation (fast)\\
+%     \hline
+%     $2$ & High quality (normal)\\
+%     \hline
+%     $3$ & High quality with 3d primitives (not implemented yet)\\
+%     \hline
+%     $4$ & No face drawing, direct bitmap drawing (low memory usage)\\
+%     \hline
+%     $5$ & No color interpolation, direct bitmap drawing (low memory usage)\\
+%     \hline
+%     $6$ & High quality, direct bitmap drawing (low memory usage)\\
+%     \hline
+%     $7$ & High quality with 3d primitives, direct bitmap drawing (not implemented yet)\\
+%     \hline
+%     $8$ & Draw dots instead of primitives (extremely fast)\\
+%     \hline
+%   \end{tabular}
+% \end{center}
+% 
+% \DescribeMacro{\mgltexon} This command has the same effect as the package option |on|, i.e., create all the scripts and corresponding graphics, but its effect is local, meaning that it work only from the point it is used on.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mgltexon|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+% 
+% \DescribeMacro{\mgltexoff} This command has the same effect as the package option |off|, i.e., DO NOT create the scripts and corresponding graphics, and include images anyway, but its effect is also local, meaning that it work only from the point it is used on.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mgltexoff|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+% 
+% Observe the commands |\mgltexon| and |\mgltexoff| can be used to save compilation time of a document. For example, when writing an article, if the graphics of the first section are already in final version, instead of compilling them every time \LaTeX{} is called, they can be created only once, and then the section can be wrapped with |mgltexoff| and |mgltexon|, so the graphics do not get recompiled again (wasting time), but only included.
+% 
+% \DescribeMacro{\mglcomments} This command has the same effect as the package option |comments|, i.e., show all the commentaries contained int the |mglcomment| environments, but its effect is local, meaning that it work only from the point it is used on.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglcoments|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+% \DescribeMacro{\mglnocomments} This command has the same effect as the package option |nocomments|, i.e., DO NOT show the contentsof the |mglcomment| environments, but its effect is also local, meaning that it work only from the point it is used on.
+% \begin{center}
+%   \begin{tabular}{l}
+%     \hline\\[-0.75em]
+%     |\mglnocomments|\\[0.25em]
+%     \hline
+%   \end{tabular}
+% \end{center}
+% 
+% Observe the commands |\mglcomments| and |\mglnocomments| can be used to activate/deactivate commentaries on the document: just like \LaTeX{} commentaries, but with the possibilty of making them visible/invisible. This feature could be used, for example, to show remainders or commentaries for readers of test versions of an article.
+% 
 % \DescribeMacro{\mglTeX} This command just pretty-prints the name of the package.
 % \begin{center}
 %   \begin{tabular}{l}
 %   \end{tabular}
 % \end{center}
 % 
+% \subsection{User-definable macros}
+% \noindent There are two macros that the user is allowed to modify:
+% 
+% \DescribeMacro{\mgltexsignature}
+% As an alternative to the |mglsignature| environment for declaring signatures, the user can manually redefine the signature macro |\mgltexsignature|, according to the following rules:
+% \begin{itemize}
+%   \item The positions of the comment signs for the MGL language have to be manually specified in the signature using the |\mglcomm| macro.
+%   \item The new-line character is declared as ``|^^J|''.
+%   \item A percent sign (|%|) has to be added at the end of every physical line of |\mgltexsignature|, otherwise an inelegant space at the beginning of every line will appear.
+%   \item Any \LaTeX{} command can be used in this case.
+% \end{itemize}
+% For example, the default signature:
+% \begin{quote}
+%   \mglcomm\\
+%   \mglcomm\ This script was generated from \meta{document}.mgl on date \meta{today}\\
+%   \mglcomm
+% \end{quote}
+% can be achieved with
+% \begin{verbatim}
+%   \def\mgltexsignature{%
+%     \mglcomm^^J%
+%     \mglcomm\ This script was generated from \jobname.mgl on date \today^^J%
+%     \mglcomm%
+%   }
+% \end{verbatim}
+% 
+% \DescribeMacro{\mglcommonscript}
+% It is the name for the common script that takes the contents of the |mglcommon| environment. For example, the default name of the script (``mgl\_common\_script'') is defined by doing
+% \begin{verbatim}
+%   \def\mglcommonscript{mgl_common_script}
+% \end{verbatim}
+% 
 % \subsection{Behavior of \textsf{\mglTeX}}
 % \noindent As a convenient feature, the environments |mglcode|, |mglscript| and |mglblock| will automatically check if they are being used to create different scripts with the same name, in which case \textsf{\mglTeX} will issue a warning; however, if one of these environments overwrite an external script (not embedded in the document), it won't be noticed. Likewise, the user will be warned if the environment |mglfunc| is being used to create different MGL functions with the same name.
 % 
 %   }
 % \end{center}
 % Notice that the first time \LaTeX{} is executed, many of these boxes will appear in the document because the graphics from the MGL scripts are created, but not all are included (until \LaTeX{} is run for the second time).
-% 
-% \StopEventually{}
+% \section{Warning for the user}
+% \mglTeX{} assummes that the |\begin{|\meta{environment}|}| and |\end{|\meta{environment}|}| commands will occupy their own physical line of \LaTeX{} code. So the correct form to use the environments is the following:
+% \begin{verbatim}
+%   \begin{<environment>}
+%     <contents of the environment>
+%   \end{<environment>}
+% \end{verbatim}
+% The following forms of use could cause problems:
+% \begin{verbatim}
+%   \begin{<environment>}<contents of the environment>\end{<environment>}
+% \end{verbatim}
+% \begin{verbatim}
+%   \begin{<environment>}<contents of the environment>
+%   \end{<environment>}
+% \end{verbatim}
+% \begin{verbatim}
+%   \begin{<environment>}
+%   <contents of the environment>
+%   \end{<environment>}<text>
+% \end{verbatim}
+% One of the reasons for this is that some of the environments in \mglTeX{} are programmed to ignore the empty space following the |\begin{|\meta{environment}|}|, which would cause an inelegant empty line in the script, so the first two incorrect forms would cause \mglTeX{} to ignore a complete line of code. The other reason is the method used to detect the |\end{|\meta{environment}|}| command, which could fail in the case of the third incorrect use.
+% \StopEventually{\PrintChanges\PrintIndex}
 % \section{Implementation}
+% \noindent This section documents the implementation of \mglTeX. Its purpose is to facilitate the comprehension and maintenance of the package.
+% \subsection{Initialization}
+% \noindent The \textsf{keyval} package is loaded to facilitate the declaration of \meta{key}=\meta{value} options for commands and environments; the \textsf{graphicx} package is loaded in order to manipulate and include the images created by MGL code.
 %    \begin{macrocode}
 
 \RequirePackage{keyval}
 \RequirePackage{graphicx}
+%    \end{macrocode}
+
+% We declare the options of the package. The first two are |draft| and |final|, which are passed directly to the \textsf{graphicx} package.
+%    \begin{macrocode}
 
 \DeclareOption{draft}{%
   \PassOptionsToPackage{\CurrentOption}{graphicx}%
 \DeclareOption{final}{%
   \PassOptionsToPackage{\CurrentOption}{graphicx}%
 }
+%    \end{macrocode}
+% 
+% The next two options are |on| and |off|, where |on| indicates \mglTeX{} to create every script and every corresponding image every time \LaTeX{} is executed, while |off| tells not to do it, but to include the images anyway. First we declare a flag (boolean variable) |\@mgltex@on@| to know if the used passed the |on| or the |off| option.
+%    \begin{macrocode}
+\newif\if@mgltex@on@
+%    \end{macrocode}
+% If the user passes the option |on|, |\@mgltex@on@| is true, and the command |\mgl@write| (which takes care of writing code to the scripts) is the normal \LaTeX{} |\immediate\write| commands;
+% \changes{v.2.0}{2014/11/15}{Add package options \texttt{on} and \texttt{off}}
+%    \begin{macrocode}
+\DeclareOption{on}{%
+  \@mgltex@on@true%
+  \def\mgl@write#1#2{%
+    \immediate\write#1{#2}%
+  }
+}
+%    \end{macrocode}
+% if the user passes the option |off|, |\@mgltex@on@| is false, and the command |\mgl@write| does nothing (doesn't write to scripts).
+%    \begin{macrocode}
+\DeclareOption{off}{%
+  \@mgltex@on@false%
+  \def\mgl@write#1#2{}%
+}
+%    \end{macrocode}
+% The next options are |comments| and |nocomments|, where |comments| indicates \mglTeX{} to show the comments included inside |\mglcomments| environments, while |nocomments| tells not to do it. First we create a flag that will indicate which of these options is passed by the user.
+%    \begin{macrocode}
+\newif\if@mgl@comments@
+%    \end{macrocode}
+% If the user passes the option |comments|, |\@mgl@comments@| is true, and the |\mglcomments| environments print their contents;
+% \changes{v2.0}{2014/11/22}{Add package options \texttt{comments} and \texttt{nocomments}}
+%    \begin{macrocode}
+\DeclareOption{comments}{%
+  \@mgl@comments@true%
+}
+%    \end{macrocode}
+% if the user passes the option |nocomments|, |\@mgl@comments@| is false, and the |\mglcomments| environments won't print their contents.
+%    \begin{macrocode}
+\DeclareOption{nocomments}{%
+  \@mgl@comments@false%
+}
+%    \end{macrocode}
+% We then indicate the supported extensions to save the images created by the package, and the corresponding package options. The chosen extension is stored in the |\mgl@image@ext| macro for future use.
+%    \begin{macrocode}
 
-\DeclareGraphicsExtensions{.png,.eps,.jpg,.jpeg,.bps,.pdf,.epsz,.eps.gz,.bpsz,.bps.gz,.gif}
-%\DeclareGraphicsExtensions{.png,.eps,.jpg,.jpeg,.bps,.pdf,.gif}
-%\DeclareGraphicsRule{*}{eps}{*}{}
-%\DeclareGraphicsRule{.eps.gz}{eps}{.eps.bb}{`gunzip -c #1}%   gzipped EPS
-%\DeclareGraphicsRule{.epsz}{eps}{.eps.bb}{`gunzip -c #1}%   gzipped EPS
-%\DeclareGraphicsRule{.bps.gz}{eps}{.bps.bb}{`gunzip -c #1}%   gzipped EPS
-%\DeclareGraphicsRule{.bpsz}{eps}{.bps.bb}{`gunzip -c #1}%   gzipped EPS
+\DeclareGraphicsExtensions{%
+  .png,.eps,.jpg,.jpeg,.bps,.pdf,.epsz,.eps.gz,.bpsz,.bps.gz,.gif%
+}
 
 \DeclareOption{jpg}{\def\mgl@image@ext{.jpg}}
 \DeclareOption{jpeg}{\def\mgl@image@ext{.jpeg}}
 \DeclareOption{gif}{\def\mgl@image@ext{.gif}}
 
 \DeclareOption{tex}{\def\mgl@image@ext{.tex}}
-%\DeclareOption{svg}{\def\mgl@image@ext{.svg}}
-%\DeclareOption{svgz}{\def\mgl@image@ext{.svgz}}
-%\DeclareOption{bmp}{\def\mgl@image@ext{.bmp}}
-%\DeclareOption{tga}{\def\mgl@image@ext{.tga}}
-%\DeclareOption{mgld}{\def\mgl@image@ext{.mgld}}
-%\DeclareOption{json}{\def\mgl@image@ext{.json}}
-%\DeclareOption{jsonz}{\def\mgl@image@ext{.jsonz}}
-%\DeclareOption{obj}{\def\mgl@image@ext{.obj}}
-%\DeclareOption{xyz}{\def\mgl@image@ext{.xyz}}
-%\DeclareOption{stl}{\def\mgl@image@ext{.stl}}
-%\DeclareOption{off}{\def\mgl@image@ext{.off}}
-%\DeclareOption{prc}{\def\mgl@image@ext{.prc}}
-
-\ExecuteOptions{final,eps}
+%    \end{macrocode}
+% 
+% Other options produce an error message.
+%    \begin{macrocode}
+\DeclareOption*{\@unknownoptionerror}
+%    \end{macrocode}
+% 
+% The default options for the package are set to |final| and |eps|, then the options passed by the user are processed. 
+%    \begin{macrocode}
+
+\ExecuteOptions{final,on,nocomments,eps}
 \ProcessOptions*
+%    \end{macrocode}
+% 
+% Declare the \meta{key}=\meta{value} pairs for the |mgl| environment and companions. The pairs corresponding to the |\includegraphics| command are repeated, and saved in the |\graph@keys| macro; the new option is |imgext|, which can be used to overwrite the default extension chosen for the package. Notice that |imgext| can be any supported extension by MathGL but, of course, not all of them are supported by \LaTeX.
+%    \begin{macrocode}
 
 \define@key{mgl@keys}{bb}{\g@addto@macro{\graph@keys}{bb=#1,}}
 \define@key{mgl@keys}{bbllx}{\g@addto@macro{\graph@keys}{bbllx=#1,}}
 \define@key{mgl@keys}{read}{\g@addto@macro{\graph@keys}{read=#1,}}
 \define@key{mgl@keys}{command}{\g@addto@macro{\graph@keys}{command=#1,}}
 \define@key{mgl@keys}{imgext}{\def\mgl@image@ext{.#1}}
+%    \end{macrocode}
+
+% We do the same for the |\mglplot| command. The options for the |\includegraphics| command are repeated and stored in the |\graph@keys| macro; the new options are |imgext|, which is the same as the one for the |mgl| environment, and |setup|, which is used to specify a keyword associated to a block of MGL code stored by the |mglsetup| environment.
+%    \begin{macrocode}
 
 \define@key{mglplot@keys}{bb}{\g@addto@macro{\graph@keys}{bb=#1,}}
 \define@key{mglplot@keys}{bbllx}{\g@addto@macro{\graph@keys}{bbllx=#1,}}
 \define@key{mglplot@keys}{ext}{\g@addto@macro{\graph@keys}{ext=#1,}}
 \define@key{mglplot@keys}{read}{\g@addto@macro{\graph@keys}{read=#1,}}
 \define@key{mglplot@keys}{command}{\g@addto@macro{\graph@keys}{command=#1,}}
-\define@key{mglplot@keys}{outext}{\def\mglplot@output@ext{.#1}}
-\define@key{mglplot@keys}{settings}{\def\mglplot@settings{#1}}
-
-\def\mgl@dir{}
-\def\mgldir#1{%
-  \def\mgl@dir{#1}%
-}
-\@onlypreamble\mgldir
-
-\newwrite\mgl@script
-\AtBeginDocument{%
-  \immediate\openout\mgl@script="\mgl@dir\jobname.mgl"%
-}
-\AtEndDocument{%
-  \immediate\write\mgl@script{}%
-  \immediate\write\mgl@script{stop}%
-  \mgl@func%
-  \immediate\closeout\mgl@script%
-  \immediate\write18{mglconv -n "\mgl@dir\jobname.mgl"}%
-}
+\define@key{mglplot@keys}{imgext}{\def\mglplot@image@ext{.#1}}
+\define@key{mglplot@keys}{setup}{\def\mglplot@setup{#1}}
+%    \end{macrocode}
 
-\def\mglplotsettings@defined{}
-\newcommand\mglplotsettings[1][generic]{%
-  \test@mglplotsettings@defined{#1}%
-  \expandafter\def\csname mgl@setup@#1\endcsname{\immediate\write\mgl@script{}}%
-  \g@addto@macro{\mglplotsettings@defined}{#1,}%
-  \let\do\@makeother \dospecials%
-  \endlinechar`\^^M \catcode`\^^M\active%
-  \catcode`\ =10%
-  \expandafter\mglplotsettings@write@line%
-}
-\def\test@mglplotsettings@defined#1{%
-  \def\this@setup{#1}%
-  \@for\mglplotsettings@name:=\mglplotsettings@defined\do{%
-    \ifx\this@mglplotsettings\mglplotsettings@name%
-      \PackageWarning{\mgl@name}{Redefining "#1" setup for \noexpand\mglplot}%
-    \fi%
-  }%
-}
-\begingroup%
-  \catcode`\^^M\active%
-  \gdef\mglplotsettings@write@line#1^^M{%
-    \def\next@action{%
-      \expandafter\g@addto@macro\csname mgl@setup@\this@setup\endcsname{\immediate\write\mgl@script{#1}}%
-      \mglplotsettings@write@line%
-    }%
-    \test@end@mglplotsettings{#1}%
-    \next@action%
-  }%
-\endgroup
-\begingroup%
-  \escapechar=-1 \relax%
-  \xdef\end@mglplotsettings{\string\\end\string\{mglplotsettings\string\}}%
-\endgroup
-\def\test@end@mglplotsettings#1{%
-  \edef\this@line{#1}%
-  \ifx\this@line\end@mglplotsettings%
-    \def\next@action{\end{mglplotsettings}}%
-  \fi%
-}
-\def\endmglplotsettings{}
+% A special extension for images created with MathGL is ``.tex'', so we store it within a macro for future use.
+%    \begin{macrocode}
 
 \def\TeX@ext{.tex}
-\newcounter{mgl@image@no}
-
-\def\mglplot{%
-  \@ifnextchar[{\@mglplot}{\@mglplot[]}%
-}
-\def\@mglplot[#1]{%
-  \def\mglplot@settings{generic}%
-  \def\graph@keys{}%
-  \setkeys{mglplot@keys}{#1}%
-  \stepcounter{mgl@image@no}%
-  \ifx\csname mgl@setup@\mglplot@settings\endcsname\@undefined%
-    \PackageError{\mgl@name}{Setup "\mglplot@settings" undefined}{}%
-  \else%
-    \csname mgl@setup@\mglplot@settings\endcsname%
-  \fi%
-  \@@mglplot%
-}
-\long\def\@@mglplot#1{%
-  \immediate\write\mgl@script{\detokenize{#1}}%
-  \immediate\write\mgl@script{write '\mgl@dir\jobname-mgl-\arabic{mgl@image@no}\mgl@image@ext'}%
-  \immediate\write\mgl@script{reset}%
-  \mgl@include@image{\mgl@dir\jobname-mgl-\arabic{mgl@image@no}}%
-}
-
-\newcommand\mgl[1][]{%
-  \def\graph@keys{}%
-  \setkeys{mgl@keys}{#1}%
-  \let\do\@makeother \dospecials%
-  \endlinechar`\^^M \catcode`\^^M\active%
-  \catcode`\ =10%
-  \mgl@write@line%
-}
-\begingroup%
-  \escapechar=-1 \relax%
-  \xdef\end@mgl{\string\\end\string\{mgl\string\}}%
-\endgroup
-\begingroup%
-  \catcode`\^^M\active%
-  \gdef\mgl@write@line#1^^M{%
-    \def\next@action{%
-      \immediate\write\mgl@script{#1}%
-      \mgl@write@line%
-    }%
-    \test@end@mgl{#1}%
-    \next@action%
-  }%
-\endgroup
-\def\test@end@mgl#1{%
-  \edef\this@line{#1}%
-  \ifx\this@line\end@mgl%
-    \def\next@action{\end{mgl}}%
-  \fi%
-}
-\def\endmgl{%
-  \stepcounter{mgl@image@no}%
-  \immediate\write\mgl@script{write '\mgl@dir\jobname-mgl-\arabic{mgl@image@no}\mgl@image@ext'}%
-  \immediate\write\mgl@script{reset}%
-  \mgl@include@image{\mgl@dir\jobname-mgl-\arabic{mgl@image@no}}%
-}
+%    \end{macrocode}
+% \subsection{Environments for MGL code embedding}
+% \begin{macro}{\mgl@include@image}
+% This is the command that will include graphics created by MGL code. We can't use |\includegraphics| directly for two reasons: first, MathGL has the capacity of creating graphics with \LaTeX{} commands (with the aid of the \textsf{tikz} package), in which case there is no image, but a ``.tex'' file, which has to be included; the second reason is that |\includegraphics| issues an error when the specified image doesn't exist, and remember that the first \LaTeX{} run only creates the images at the end of the document, but they cannot be included yet, so there would be a lot of errors in the process of compilation.
+%    \begin{macrocode}
 \def\mgl@include@image#1{%
+%    \end{macrocode}
+% If the extension of the graphics is ``.tex'',
+%    \begin{macrocode}
   \ifx\mgl@image@ext\TeX@ext%
+%    \end{macrocode}
+% first check if the file exists;
+%    \begin{macrocode}
     \IfFileExists{#1.tex}{%
+%    \end{macrocode}
+% if so, include it,
+%    \begin{macrocode}
       \include{#1}%
     }{%
+%    \end{macrocode}
+% otherwise use the command |\mgl@img@not@found| to create a warning.
+%    \begin{macrocode}
       \mgl@img@not@found{#1}%
     }%
+%    \end{macrocode}
+% If the extension of the graphics is not ``.tex'',
+%    \begin{macrocode}
   \else%
+%    \end{macrocode}
+% we define the next action to be performed as warning that requested image doesn't exist. This is stored in the |\next@action| macro, and will be overwriten if the image is found.
+%    \begin{macrocode}
   \def\next@action{\mgl@img@not@found{#1}}%
+%    \end{macrocode}
+% For every extension supported by \mglTeX{},
+%    \begin{macrocode}
     \@for\img@ext:=\Gin@extensions\do{%
+%    \end{macrocode}
+% if the file with the current extension exists,
+%    \begin{macrocode}
       \IfFileExists{#1\img@ext}{%
+%    \end{macrocode}
+% overwrite the |\next@action| macro so it uses the |\includegraphics| command to include the image, otherwise do nothing.
+%    \begin{macrocode}
         \def\next@action{%
           \expandafter\includegraphics\expandafter[\graph@keys]{#1}%
         }%
       }{}%
     }%
+%    \end{macrocode}
+% Execute |\next@action|.
+%    \begin{macrocode}
     \next@action%
   \fi%
 }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mgl@img@not@found}
+% \changes{v2.0}{2014/11/22}{Fixed incompatibility of command \texttt{\textbackslash{}mgl@img@not@found} with environment \texttt{tabular}}
+% When this command is called with the name of a MGL image as argument, it issues a package warning indicating that the MGL image can't be found, and creates the following box in the corresponding position:
+% \begin{center}
+% \framebox[10em]{%
+%   \centering%
+%   \bfseries\Huge%
+%   \vbox{MGL\\image\\not\\found}%
+% }%
+% \end{center}
+%    \begin{macrocode}
 \def\mgl@img@not@found#1{%
-  \PackageWarning{\mgl@name}{MGL image "#1" not found}%
+  \PackageWarning{mgltex}{MGL image "#1" not found}%
   \framebox[10em]{%
     \centering%
     \bfseries\Huge%
-    \vbox{MGL\\image\\not\\found}%
+    \begin{tabular}{c}MGL\\image\\not\\found\end{tabular}%
   }%
 }
+%    \end{macrocode}
+% \end{macro}
+% \begin{environment}{mgl}
+% This environment writes its contents to the main script \meta{document}.mgl.
+% 
+% First, declare a counter for numeration and naming of the images created from the main script \meta{document}.mgl.
+%    \begin{macrocode}
 
-\bgroup%
-  \escapechar=-1\relax%
-  \xdef\end@mgladdon{\string\\end\string\{mgladdon\string\}}%
-\egroup%
-\newenvironment{mgladdon}{%
-  \def\test@end@mgl##1{%
-    \edef\this@line{##1}%
-    \ifx\this@line\end@mgladdon%
-      \def\next@action{\end{mgladdon}}%
-    \fi%
-  }%
-  \mgl[]%
-}{}
-
-\def\mgl@script@written{}
+\newcounter{mgl@image@no}
+%    \end{macrocode}
+% Create an output stream for the main script \meta{document}.mgl.
+%    \begin{macrocode}
+
+\newwrite\mgl@script
+%    \end{macrocode}
+% Open the main script at the beginning of the document (at the moment of the |\begin{document}| command).
+%    \begin{macrocode}
+\AtBeginDocument{%
+  \if@mgltex@on@%
+    \immediate\openout\mgl@script="\mgl@dir\jobname.mgl"%
+    \mglsignature@write\mgl@script%
+  \fi%
+}
+%    \end{macrocode}
+% At the end of the document (at the moment of the |\end{document}| command):
+%    \begin{macrocode}
+\AtEndDocument{%
+%    \end{macrocode}
+% write an empty line on the main script (just for elegance),
+%    \begin{macrocode}
+  \mgl@write\mgl@script{}%
+%    \end{macrocode}
+% write the MGL \emph{stop} command to stop the MathGL compiler.
+%    \begin{macrocode}
+  \mgl@write\mgl@script{stop}%
+%    \end{macrocode}
+% The |\mgl@func| is a buffer that contains instructions to write MGL functions declared with |mglfunc| environment. Here, we execute those instructions.
+%    \begin{macrocode}
+  \mgl@func%
+%    \end{macrocode}
+% Close the main script.
+%    \begin{macrocode}
+  \immediate\closeout\mgl@script%
+%    \end{macrocode}
+% Use the program |mglconv| (part of MathGL) to compile the main script.
+%    \begin{macrocode}
+  \mgl@write{18}{mglconv -n "\mgl@dir\jobname.mgl"}%
+}
+
+%    \end{macrocode}
+% \begin{macro}{\mgl}
+% The beginning of the |mgl| environment.
+%    \begin{macrocode}
+
+\newcommand\mgl[1][]{%
+%    \end{macrocode}
+% First, process the \meta{key}=\meta{value} options for the environment.
+%    \begin{macrocode}
+  \def\graph@keys{}%
+  \setkeys{mgl@keys}{#1}%
+%    \end{macrocode}
+% Now, make every ``special'' character (\textbackslash, \$, etc.) of category $13$ (other), i.e., make them common characters.
+%    \begin{macrocode}
+  \let\do\@makeother \dospecials%
+%    \end{macrocode}
+% Add an end-line character at the end of every read line. This end-line character is declared active (category 12).
+%    \begin{macrocode}
+  \endlinechar`\^^M \catcode`\^^M\active%
+%    \end{macrocode}
+% Spaces characters are category 10; the spaces at the beginning of every read line are ignored.
+%    \begin{macrocode}
+  \catcode`\ =10%
+%    \end{macrocode}
+% Finally, the command that reads/writes each line of the contents of the environment is called.
+%    \begin{macrocode}
+  \mgl@write\mgl@script{quality \mgl@quality}%
+  \expandafter\mgl@write@line%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\end@mgl}
+% Define a macro that contains the |\end{mgl}| command as text, so the end of the environment can be tested by comparison with it. From now on, we adopt the convention that the macro |\end@|\meta{environment} contains the |\end{|\meta{environment}|}| command as text.
+%    \begin{macrocode}
+\begingroup%
+  \escapechar=-1 \relax%
+  \xdef\end@mgl{\string\\end\string\{mgl\string\}}%
+\endgroup
+%    \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\mgl@write@line}
+% This command reads each line from the |mgl| environment and writes it to the general script \meta{document}.mgl. We start by wrapping the new command with a \LaTeX{} group because we will change the code of the end-line character to ``active'' \emph{locally}, so we can indicate |\mgl@write@line| that its argument stretches until the end of the line.
+%    \begin{macrocode}
+\begingroup%
+%    \end{macrocode}
+
+% Declare the end-line character as active.
+%    \begin{macrocode}
+  \catcode`\^^M\active%
+%    \end{macrocode}
+% The command |\mgl@write@line| reads its argument until it finds the end-line character, i.e., it reads a complete line of text, which is MGL code in this case.
+%    \begin{macrocode}
+  \gdef\mgl@write@line#1^^M{%
+%    \end{macrocode}
+% The next action to be performed is write the read line of code to the main script \meta{document}.mgl and recursively call |\mgl@write@line|, so it reads the next line of text. These instructions are stored in the |\next@action| macro.
+%    \begin{macrocode}
+    \def\next@action{%
+      \mgl@write\mgl@script{#1}%
+      \mgl@write@line%
+    }%
+%    \end{macrocode}
+% The |\test@end@mgl| command test if the end of the |mgl| environment has been reached in the current line. If so, it overwrites the |\next@action| macro so it doesn't read the next line of text, but executes the |\end{mgl}| command (see bellow).
+%    \begin{macrocode}
+    \test@end@mgl{#1}%
+%    \end{macrocode}
+% Execute the |\next@action| macro.
+%    \begin{macrocode}
+    \next@action%
+  }%
+\endgroup
+%    \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\test@end@mgl}
+% This command checks if its argument is equal to |\end@mgl|; if so, overwrites  the |\next@action| macro (see above) so that it executes the end of the |mgl| environment (|\end{mgl}|). Here, we adopt another convention: the |\test@end@|\meta{environment} checks if its argument is equal to |\end@|\meta{environment}, i.e., tests whether the |\end{|\meta{environment}|}| command has been reached, in which case, it executes that command.
+%    \begin{macrocode}
+\def\test@end@mgl#1{%
+  \edef\this@line{#1}%
+  \ifx\this@line\end@mgl%
+    \def\next@action{\end{mgl}}%
+  \fi%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\endmgl}
+% The end of the environment is quite simple: the |mgl@image@no| counter is increased by one, then the MGL command to save the corresponding image is written; the name given to the image is ``\meta{document}-mgl-\meta{mgl@image@no}.\meta{mgl@image@ext}''; the MGL \emph{reset} command is written in the main script to clean the image and restart graphic parameters for the following image to be created. Finally, the |\mgl@include@image| command (see below) is called to include the image created.
+%    \begin{macrocode}
+\def\endmgl{%
+  \stepcounter{mgl@image@no}%
+  \mgl@write\mgl@script{%
+    write '\mgl@dir\jobname-mgl-\arabic{mgl@image@no}\mgl@image@ext'%
+  }%
+  \mgl@write\mgl@script{reset}%
+  \mgl@write\mgl@script{}%
+  \mgl@include@image{\mgl@dir\jobname-mgl-\arabic{mgl@image@no}}%
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{environment}
+% \begin{environment}{mgladdon}
+% This is just a modification of the |mgl| environment. First, we define the |\end@mgladdon| to contain the |\end{mgladdon}| command as text as specified above, then we redefined |\test@end@mgl| command to check for the end of the |mgladdon| environment instead of |mgl|, finally we call the |\mgl| command with no options. The end of |mgladdon| is defined to do nothing.
+%    \begin{macrocode}
+
+\bgroup%
+  \escapechar=-1\relax%
+  \xdef\end@mgladdon{\string\\end\string\{mgladdon\string\}}%
+\egroup%
+\newenvironment{mgladdon}{%
+  \def\test@end@mgl##1{%
+    \edef\this@line{##1}%
+    \ifx\this@line\end@mgladdon%
+      \def\next@action{\end{mgladdon}}%
+    \fi%
+  }%
+  \mgl[]%
+}{}
+%    \end{macrocode}
+% \end{environment}
+% \begin{environment}{mglcode}
+% This is like |mgl|, but it writes its contents to its own file, whose name is passed as mandatory argument.
+% \begin{macro}{\mgl@script@written}
+
+% The names of all the scripts written from the \LaTeX{} document will be stored in this macro, so we can later check if some script is being overwritten. This macro will be used in other environments.
+%    \begin{macrocode}
+\def\mgl@script@written{}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mgl@out@stream}
+% Declare an output stream for MGL scripts other than the main one. This stream will be used in other environments.
+%    \begin{macrocode}
 \newwrite\mgl@out@stream
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglcode}
+% The beginning of the |mglcode| environment.
+%    \begin{macrocode}
 \newcommand\mglcode[2][]{%
   \def\graph@keys{}%
+%    \end{macrocode}
+% Process the \meta{key}=\meta{value} options. These are the same for the |mgl| environment.
+%    \begin{macrocode}
   \setkeys{mgl@keys}{#1}%
+%    \end{macrocode}
+% Test if a script with the same name is already created from the \LaTeX{} document. If so, a warning is issue, but we proceed anyway.
+%    \begin{macrocode}
   \test@mgl@script@written{#2}%
+%    \end{macrocode}
+% Add the script's name to the |\mgl@script@written| macro.
+%    \begin{macrocode}
   \xdef\mgl@script@written{\mgl@script@written#2,}%
+%    \end{macrocode}
+% Open the script for writing.
+%    \begin{macrocode}
   \def\this@script{#2}%
-  \immediate\openout\mgl@out@stream=\mgl@dir\this@script.mgl%
+  \if@mgltex@on@%
+    \immediate\openout\mgl@out@stream=\mgl@dir\this@script.mgl%
+    \mglsignature@write\mgl@out@stream%
+  \fi%
+%    \end{macrocode}
+%   Here, we do the same changes of categories as in the |mgl| environment, except for the spaces, which in this case will be respected, even the ones at the beginning of each like, i.e., we will write each line \emph{verbatim}.
+%    \begin{macrocode}
   \let\do\@makeother \dospecials%
   \endlinechar`\^^M \catcode`\^^M\active%
   \obeyspaces%
-  \mglcode@write@line%
+%    \end{macrocode}
+% Call the command that will write each line of the contents of the environment.
+%    \begin{macrocode}
+  \expandafter\mglcode@write@line%
 }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\test@mgl@script@written}
+% The macro that checks is we are overwriting any script.
+%    \begin{macrocode}
 \def\test@mgl@script@written#1{%
+%    \end{macrocode}
+% For every script already written (whose name is stored in |\mgl@script@written|), check if the current script's name matches; if so, issue a warning telling we are overwriting, but proceed.
+%    \begin{macrocode}
   \edef\this@script{#1}%
   \@for\mgl@script@name:=\mgl@script@written\do{%
     \ifx\this@script\mgl@script@name%
-      \PackageWarning{\mgl@name}{Overwriting MGL script "\this@script.mgl"}%
+      \PackageWarning{mgltex}{Overwriting MGL script "\this@script.mgl"}%
     \fi%
   }%
 }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglcode@write@line}
+% This writes each line of the contents of the |mglcode| environment. However, contrary to the case of the |\mgl@write@line| command, it doesn't read line by line, but character by character, and stores each word in |\mgl@word| and each line in |\mgl@line|.
+%    \begin{macrocode}
+\newtoks\mgl@word
+\newtoks\mgl@line
 \def\mglcode@write@line#1{%
+%    \end{macrocode}
+% The next action (stored as |\next@action|) is to read the following character, unless overwritten later.
+%    \begin{macrocode}
   \let\next@action\mglcode@write@line%
+%    \end{macrocode}
+% If the current character is an end-line character,
+%    \begin{macrocode}
   \expandafter\if#1\^^M%
-    \immediate\write\mgl@out@stream{\the\mgl@line}%
-    \mgl@line{}%
+%    \end{macrocode}
+% write the contents of |\mgl@line|, i.e., the current line, and clean |\mgl@word| and |\mgl@line|;
+%    \begin{macrocode}
+    \mgl@write\mgl@out@stream{\the\mgl@line}%
     \mgl@word{}%
+    \mgl@line{}%
+%    \end{macrocode}
+% if the current character is a space, clean |\mgl@word|, but add the space to |\mgl@line|;
+%    \begin{macrocode}
   \else\expandafter\if#1\space%
     \mgl@word{}%
     \mgl@line\expandafter{\the\mgl@line#1}%
+%    \end{macrocode}
+% otherwise, the current character is alphanumeric and is added both to |\mgl@word| and |\mgl@line|, and
+%    \begin{macrocode}
   \else%
     \mgl@word\expandafter{\the\mgl@word#1}%
     \mgl@line\expandafter{\the\mgl@line#1}%
+%    \end{macrocode}
+% we test if the current word (|\mgl@word|) is |\end{mglcode}|, in which case, |\next@action| is overwritten to |\end{mglcode}|.
+%    \begin{macrocode}
     \test@end@mglcode{\the\mgl@word}%
   \fi\fi%
+%    \end{macrocode}
+% Finally, execute |\next@action|.
+%    \begin{macrocode}
   \next@action%
 }
+%    \end{macrocode}
+% \end{macro}
+% 
+% \begin{macro}{\test@end@mglcode}
+% The |\test@end@mglcode| checks if it's argument is equal to |\end@mglcode|, in which case overwrites |\next@action| to |\end{mglcode}|.
+%    \begin{macrocode}
 \begingroup%
   \escapechar=-1\relax%
   \xdef\end@mglcode{\string\\end\string\{mglcode\string\}}%
     \def\next@action{\end{mglcode}}%
   \fi%
 }
+%    \end{macrocode}
+% \end{macro}
+% 
+% \begin{macro}{\endmglcode}
+% The end of the |mglcode| environment. It closes the output stream |\mgl@out@stream|, and calls the \textsf{mglconv} program (part of MathGL) to execute the script. Finally, the |\mgl@include@image| command is used to include the image created.
+%    \begin{macrocode}
 \def\endmglcode{%
   \immediate\closeout\mgl@out@stream%
-  \immediate\write18{mglconv "\mgl@dir\this@script.mgl" -o "\mgl@dir\this@script\mgl@image@ext"}%
+  \mgl@write{18}{%
+    mglconv "\mgl@dir\this@script.mgl" -s "\mgl@dir\mglcommonscript.mgl" -o "\mgl@dir\this@script\mgl@image@ext"%
+  }%
   \mgl@include@image{\mgl@dir\this@script}%
 }
+%    \end{macrocode}
+% \end{macro}
+% \end{environment}
+% 
+% \begin{environment}{mglscript}
+% This is just a modification of the |mglcode| environment. First, we define the |\end@mglscript| macro; then we modify the |\test@end@mglcode| to check for |\end{mglscript}| instead of |\end{mglcode}|; finally, we call the |\mglcode| macro with the same mandatory argument as |mglscript|. The |\end{mglscript}| just closes the output stream |\mgl@out@stream|, but doesn't create nor includes any image.
+%    \begin{macrocode}
 
 \bgroup%
   \escapechar=-1\relax%
 }{%
   \immediate\closeout\mgl@out@stream%
 }
+%    \end{macrocode}
+% \end{environment}
+% 
+% \begin{environment}{mglfunc}
+% This environment is used to create MGL functions in the main script \meta{document}.mgl.
+% \begin{macro}{\mglfunc@defined}
+% Within this macro we will store the names of the MGL functions already defined from the \LaTeX{} document, so that we can check if we are overwriting one of them
+%    \begin{macrocode}
 
 \def\mglfunc@defined{}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mgl@func}
+% This is a buffer to store the instructions to write the MGL functions code when the |\end{document}| command is called. This is done this way, because the functions have to be after the \emph{stop} command from the MGL language, which stops the execution of the MGL compiler, so no code should be after the \emph{stop}, except for functions.
+%    \begin{macrocode}
 \def\mgl@func{}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglgunc}
+% The beginning of the |mglfunc| environment.
+%    \begin{macrocode}
+
 \newcommand\mglfunc[2][0]{%
+%    \end{macrocode}
+% First, check if a function with the current name is already defined, in which case we issue a warning, but proceed anyway.
+%    \begin{macrocode}
   \test@mglfunc@defined{#2}%
+%    \end{macrocode}
+% Add the name of the current function to the list of functions defined.
+%    \begin{macrocode}
   \g@addto@macro{\mglfunc@defined}{#2,}%
+%    \end{macrocode}
+% \end{macro}
+% Here we do the same changes of categories as in the |mgl| environment.
+%    \begin{macrocode}
   \let\do\@makeother \dospecials%
   \endlinechar`\^^M \catcode`\^^M\active%
   \catcode`\ =10%
-  \g@addto@macro{\mgl@func}{\immediate\write\mgl@script{}}%
-  \g@addto@macro{\mgl@func}{\immediate\write\mgl@script{func '#2' #1}}%
-  \expandafter\mglfunc@ignore@line%
+%    \end{macrocode}
+% Write an empty line in the main script just for elegance (and to visually separate different functions, too).
+%    \begin{macrocode}
+  \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{}}%
+%    \end{macrocode}
+% Write the heading of the function.
+%    \begin{macrocode}
+  \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{func '#2' #1}}%
+%    \end{macrocode}
+% Call the command that will write each line of the contents of the environment.
+%    \begin{macrocode}
+  \expandafter\mglfunc@write@line%
 }
+%    \end{macrocode}
+% \begin{macro}{\test@mglfunc@defined}
+% This command tests if a function with a given name---given as argument---is already defined from the \LaTeX{} document; if so, a warning will be issued indicating multiple definitions for the same function, but we will proceed anyway.
+%    \begin{macrocode}
 \def\test@mglfunc@defined#1{%
   \def\this@func{#1}%
   \@for\mglfunc@name:=\mglfunc@defined\do{%
     \fi%
   }%
 }
+%    \end{macrocode}
+% \end{macro}
+% We declare \emph{locally} the end-line character as active.
+%    \begin{macrocode}
 \begingroup%
   \catcode`\^^M\active%
-  \gdef\mglfunc@ignore@line#1^^M{%
-    \expandafter\mglfunc@write@line%
-  }
+%    \end{macrocode}
+% \begin{macro}{\mglfunc@write@line}
+% This is the command that reads each line of code of the |mglfunc| environment, and stores in the buffer |\mgl@func| the instructions to write each of these lines.
+%    \begin{macrocode}
   \gdef\mglfunc@write@line#1^^M{%
+%    \end{macrocode}
+% The next action (|\next@action|) is to store in the buffer the instruction to write the current line, and then call recursively the |\mglfunc@write@line| command, unless overwritten below.
+%    \begin{macrocode}
     \def\next@action{%
-      \g@addto@macro{\mgl@func}{\immediate\write\mgl@script{#1}}%
-      \mglfunc@write@line%
+      \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{#1}}%
+      \expandafter\mglfunc@write@line%
     }%
+%    \end{macrocode}
+% Check for the end of the |mglfunc| environment, in which case, |\next@action| is redefined to be |\end{mglfunc}|.
+%    \begin{macrocode}
     \test@end@mglfunc{#1}%
+%    \end{macrocode}
+% Execute |\next@action|.
+%    \begin{macrocode}
     \next@action%
   }%
+%    \end{macrocode}
+% \end{macro}
+%    \begin{macrocode}
 \endgroup
+%    \end{macrocode}
+% \begin{macro}{\end@mglfunc}
+% \begin{macro}{\test@end@mglfunc}
+% By now, we already know now these two commands work.
+%    \begin{macrocode}
 \begingroup%
   \escapechar=-1 \relax%
   \xdef\end@mglfunc{\string\\end\string\{mglfunc\string\}}%
     \def\next@action{\end{mglfunc}}%
   \fi%
 }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\endmglfunc}
+% Just stores in the buffer the instruction that closes the MGL function with the \emph{return} command.
+%    \begin{macrocode}
 \def\endmglfunc{%
-  \g@addto@macro{\mgl@func}{\immediate\write\mgl@script{return}}%
+  \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{return}}%
 }
 
-\def\mglblock#1{%
-  \test@mgl@script@written{#1}%
-  \xdef\mgl@script@written{\mgl@script@written#1,}%
-  \def\this@script{#1}%
+% \begin{environment}{mglcommon}
+% Writes its contents to a common script that will be executed together with each of the other scripts. It is useful to define constants ---for example--- that will be available to all other scripts.
+% \begin{macro}{\mglcommonscript}
+% \changes{v2.0}{2014/11/22}{Add \texttt{\backslash{}mglcommonscript} user-definable macro}
+% We define a macro to store the name of the setup script that will contain common code to all other scripts. The default name is \emph{common\_script}.mgl.
+%    \begin{macrocode}
+
+\def\mglcommonscript{mgl_common_script}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\end@mglcommon}
+% We already know the purpose of this macro.
+%    \begin{macrocode}
+\bgroup%
+  \escapechar=-1\relax%
+  \xdef\end@mglcommon{\string\\end\string\{mglcommon\string\}}%
+\egroup%
+%    \end{macrocode}
+% \end{macro}
+% 
+% The |mglcommon| environment redefines the |\test@end@mglcode| so it detects the |\end{mglcommon}| command instead, and uses the |\mglcode| to create the common script.
+%    \begin{macrocode}
+\newenvironment{mglcommon}{%
+  \def\test@end@mglcode##1{%
+    \edef\this@word{##1}%
+    \ifx\this@word\end@mglcommon%
+      \def\next@action{\end{mglcommon}}%
+    \fi%
+  }%
+  \mglcode{\mglcommonscript}%
+}{%
+  \mgl@write\mgl@out@stream{quality \mgl@quality}%
+  \immediate\closeout\mgl@out@stream%
+}
+%    \end{macrocode}
+% This environment can be used only in the preamble.
+%    \begin{macrocode}
+\@onlypreamble\mglcommon
+%    \end{macrocode}
+% \end{environment}
+% \begin{environment}{mglsignature}
+% This environment is used to declare signature text that will be written as comment on every script generated by \mglTeX.
+% \begin{macro}{\mglcomm}
+% We store the comment sign for MGL in this macro. For that, we need to declare \emph{locally} the symbol ``\#'' as one of category $12$.
+%    \begin{macrocode}
+\bgroup
+  \catcode`#=12
+  \gdef\mglcomm{#}
+\egroup
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mgltexsignature}
+% \changes{v2.0}{2014/11/22}{Add \texttt{\textbackslash{}mgltexsignature} user-definable macro}
+% The buffer where the signature will be stored. Here, we declare a default signature.
+%    \begin{macrocode}
+\def\mgltexsignature{%
+  \mglcomm^^J%
+  \mglcomm\space This file was autogenerated from the document \jobname.tex on date \today^^J%
+  \mglcomm%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglsignature}
+% The beginning of the |mglsignature| environment.
+%    \begin{macrocode}
+\newcommand\mglsignature{%
+%    \end{macrocode}
+% Delete |\mgltexsignature| contents.
+%    \begin{macrocode}
+  \def\mgltexsignature{}%
+%    \end{macrocode}
+% We do the same changes of category as in the |mglcode| environment.
+%    \begin{macrocode}
   \let\do\@makeother \dospecials%
   \endlinechar`\^^M \catcode`\^^M\active%
-  \obeyspaces%
-  \immediate\openout\mgl@out@stream="\mgl@dir\this@script.mgl"%
-  \mglblock@ignore@line%
-}
-\def\mglblock@ignore@line#1{%
-  \mglblock@write@line%
-}
-\def\mglblock@write@line#1{%
-  \let\next@action\mglblock@write@line%
-  \expandafter\if#1\^^M%
-    \immediate\write\mgl@out@stream{\the\mgl@line}%
-    \mgl@line{}%
-    \mgl@word{}%
-  \else\expandafter\if#1\space%
-    \mgl@word{}%
-    \mgl@line\expandafter{\the\mgl@line#1}%
-  \else%
-    \mgl@word\expandafter{\the\mgl@word#1}%
-    \mgl@line\expandafter{\the\mgl@line#1}%
-    \test@end@mglblock{\the\mgl@word}%
-  \fi\fi%
-  \next@action%
+  \@vobeyspaces%
+%    \end{macrocode}
+% Call the command that will store each line of the signature in the |\mgltexsignature| macro.
+%    \begin{macrocode}
+  \expandafter\mglsignature@write@line%
 }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\end@mglsignature}
+% We already know the purpose of this command.
+%    \begin{macrocode}
 \begingroup%
-  \escapechar=-1\relax%
-  \xdef\end@mglblock{\string\\end\string\{mglblock\string\}}%
-\endgroup%
-\def\test@end@mglblock#1{%
-  \edef\this@word{#1}%
-  \ifx\this@word\end@mglblock%
-    \def\next@action{\end{mglblock}}%
+  \escapechar=-1 \relax%
+  \xdef\end@mglsignature{\string\\end\string\{mglsignature\string\}}%
+\endgroup
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglsignature@write@line}
+% This command stores each line of the signature in the |\mgltexsignature| buffer.
+%    \begin{macrocode}
+\begingroup%
+%   \catcode`\\=0%
+  \catcode`\^^M\active%
+  \gdef\mglsignature@write@line#1^^M{%
+%    \end{macrocode}
+% Unless overwritten later, the next action (|\next@action|) is to store the current line of the signature in the |\mgltexsignature| buffer, ending with a new-line character, and call |\mglsignature@write@line| recursively.
+%    \begin{macrocode}
+    \def\next@action{%
+      \g@addto@macro{\mgltexsignature}{\mglcomm\space#1^^J}
+      \mglsignature@write@line%
+    }%
+%    \end{macrocode}
+% We check if the current line is |\end{mglsignature}|, in which case, overwrite |\next@action| to that command.
+%    \begin{macrocode}
+    \test@end@mglsignature{#1}%
+%    \end{macrocode}
+% Execute |\next@action|.
+%    \begin{macrocode}
+    \next@action%
+  }%
+\endgroup
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\test@end@mglsignature}
+% We already know the purpose of this command.
+%    \begin{macrocode}
+\def\test@end@mglsignature#1{%
+  \edef\this@line{#1}%
+  \ifx\this@line\end@mglsignature%
+    \def\next@action{\end{mglsignature}}%
   \fi%
 }
-\newread\mgl@in@stream
-\def\endmglblock{%
-  \immediate\closeout\mgl@out@stream%
-  \immediate\openin\mgl@in@stream="\mgl@dir\this@script.mgl"%
-  \begingroup%
-  \list{\itshape\footnotesize\arabic{mgl@verb@line@no}.}{}%
-  \setlength{\labelsep}{1em}%
-  \itemsep\z@skip%
-  \leftskip\z@skip\rightskip\z@skip%
-  \verbatim@font%
-  \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\endmglsignature}
+% The end of the |mglsignature| environment. It just adds a comment sign to |\mgltexsignature| for elegance.
+%    \begin{macrocode}
+\def\endmglsignature{%
+  \g@addto@macro{\mgltexsignature}{\mglcomm}
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglsignature@write}
+% It takes care of writing the signature to the output stream which is passed as its argument.
+%    \begin{macrocode}
+\def\mglsignature@write#1{\mgl@write#1{\mgltexsignature}}
+%    \end{macrocode}
+% \end{macro}
+% \end{environment}
+% \begin{environment}{mglcomment}
+% \changes{v2.0}{2014/11/22}{Add the |mglcomment| environment.}
+% An environment to contain multiline comments that won't be printed to the document nor to any script in the case of the user passes the option |nocomments| to the package, and it'll print the comments if the |comments| option is passed to the package.
+% 
+% \begin{macro}{\mglcomment}
+% The beginning of the |mglcomment| environment. Here, we change categories of special characters (like \#, \@, etc.) and indicate to obey lines and spaces.
+%    \begin{macrocode}
+
+\def\mglcomment{%
+  \let\do\@makeother\dospecials%
+  \obeylines%
   \@vobeyspaces%
-  \mglblock@read@line%
+  \verbatim@font%
+  \small%
+%    \end{macrocode}
+% Call the command that will ignore all the commentary.
+%    \begin{macrocode}
+  \mgl@comment%
 }
-\def\mglblock@read@line{%
-  \stepcounter{mgl@verb@line@no}%
-  \read\mgl@in@stream to \this@line%
-  \ifeof\mgl@in@stream%
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mgl@comment}
+% This command reads everything up to the |\end{mglcomment}| and ignores it if the |nocomments| option is passed to the package, or prints it otherwise. (We use the trick to consider everything up to the |\end{mglcomment}| the argument of |\mgl@comment|.)
+%    \begin{macrocode}
+\begingroup%
+%    \end{macrocode}
+% We do some adequate changes of code locally, so that \texttt{\textbackslash}, \texttt{\{} and \texttt{\}} are special, and \texttt{\textbar}, \texttt{[} and \texttt{]} take their functions, respectively.
+%    \begin{macrocode}
+  \catcode`|=0\catcode`[= 1\catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\\=12%
+%    \end{macrocode}
+% Define |\mgl@comment| to do nothing with its argument if the |nocomments| option has been passed to the package; otherwise, if the |comments| options has been passed, it will print the commentary, with delimiters to indicate where it starts and where it ends. Then call the end of the environment.
+%    \begin{macrocode}
+  |gdef|mgl@comment#1\end{mglcomment}[%
+    |if@mgl@comments@%
+      |begin[center]%
+        <------------------ MGL comment ------------------>%
+        #1%
+        <------------------ MGL comment ------------------>%
+      |end[center]%
+    |fi%
+    |end[mglcomment]]%
+|endgroup%
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\endmglcomment}
+% The end of the environment; it does nothing.
+%    \begin{macrocode}
+\def\endmglcomment{}
+%    \end{macrocode}
+% \end{macro}
+% \end{environment}
+
+% \subsection{Fast creation of graphics}
+% \begin{environment}{mglsetup}
+% This environment is used to store lines of code that need to be repeated many times. Later, the |\mglplot| command (see below) uses this lines of code without the need to repeat them.
+% \begin{macro}{\mglsetup@defined}
+% A macro to list the names of all the setups already defined.
+%    \begin{macrocode}
+
+\def\mglsetup@defined{}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglsetup}
+% The beginning of the |mglsetup| environment. It accepts one optional argument, which is a name (keyword) to be associated to the block of code.
+%    \begin{macrocode}
+\newcommand\mglsetup[1][generic]{%
+%    \end{macrocode}
+% Test if there already exists a setup with the current name; if so, issue a warning of redefinition of the setup, but proceed anyway.
+%    \begin{macrocode}
+  \test@mglsetup@defined{#1}%
+%    \end{macrocode}
+% Add the name of the current setup to |\mglsetup@defined|.
+%    \begin{macrocode}
+  \g@addto@macro{\mglsetup@defined}{#1,}%
+%    \end{macrocode}
+% Define a new buffer which will contain the instructions to write the contents of the environment when the |\mglplot|. command is used. If the |mglsetup| environment is called like |\mglsetup\oarg{\meta{keyword}}|, the buffer will be called |\mgl@setup@\meta{keyword}|; if no name is given, use ``generic'' as keyword.
+%    \begin{macrocode}
+  \expandafter\def\csname mgl@setup@#1\endcsname{\mgl@write\mgl@script{}}%
+  \expandafter\def\csname mgl@setup@#1\endcsname{\mgl@write\mgl@script{quality \mgl@quality}}%
+%    \end{macrocode}
+% Here, we do the same changes of category for special characters as we did in the |mgl| environment.
+%    \begin{macrocode}
+  \let\do\@makeother \dospecials%
+  \endlinechar`\^^M \catcode`\^^M\active%
+  \catcode`\ =10%
+%    \end{macrocode}
+% Call the command that will store in the buffer the instructions to write the lines of MGL code.
+%    \begin{macrocode}
+  \expandafter\mglsetup@write@line%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\test@mglsetup@defined}
+% For every name stored in |\mglsetup@defined|, check if its argument (the name of the current setup) matches, in which case we will issue a warning, but proceed.
+%    \begin{macrocode}
+\def\test@mglsetup@defined#1{%
+  \def\this@setup{#1}%
+  \@for\mglsetup@name:=\mglsetup@defined\do{%
+    \ifx\this@mglsetup\mglsetup@name%
+      \PackageWarning{\mgl@name}{Redefining "#1" setup for \noexpand\mglplot}%
+    \fi%
+  }%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglsetup@write@line}
+% This works exactly as the |\mgl@write@line|, but instead of writing directly to a script, it stores the writing instructions in the buffer.
+%    \begin{macrocode}
+\begingroup%
+  \catcode`\^^M\active%
+  \gdef\mglsetup@write@line#1^^M{%
     \def\next@action{%
-      \immediate\closein\mgl@in@stream%
-      \endlist%
-      \endgroup%
+      \expandafter\g@addto@macro\csname mgl@setup@\this@setup\endcsname{%
+        \mgl@write\mgl@script{#1}%
+      }%
+      \expandafter\mglsetup@write@line%
     }%
+    \test@end@mglsetup{#1}%
+    \next@action%
+  }%
+\endgroup
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\end@mglsetup}
+% \begin{macro}{\test@end@mglsetup}
+% We already know how these two macros work
+%    \begin{macrocode}
+\begingroup%
+  \escapechar=-1 \relax%
+  \xdef\end@mglsetup{\string\\end\string\{mglsetup\string\}}%
+\endgroup
+\def\test@end@mglsetup#1{%
+  \edef\this@line{#1}%
+  \ifx\this@line\end@mglsetup%
+    \def\next@action{\end{mglsetup}}%
+  \fi%
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\endmglsetup}
+% The end of the |mglsetup| environment. It does nothing.
+%    \begin{macrocode}
+\def\endmglsetup{}
+%    \end{macrocode}
+% \end{macro}
+% \end{environment}
+
+% \begin{macro}{\mglplot}
+% This macro uses the blocks of code stored by |mglsetup| environments to complete the code contained in its mandatory argument.
+% 
+% If there is an optional argument, make |\@mglplot| process it, otherwise pass no argument to |\@mglplot|.
+%    \begin{macrocode}
+
+\def\mglplot{%
+  \@ifnextchar[{\@mglplot}{\@mglplot[]}%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@mglplot}
+% This command receives one mandatory argument, but enclosed between brackets; so it receives the optional argument of |\mglplot|.
+%    \begin{macrocode}
+\def\@mglplot[#1]{%
+%    \end{macrocode}
+% Unless overwritten by the user with the |setup=\meta{setup}| option,  the default setup is ``generic''; initialize the |\graph@keys| macro; process the \meta{key}=\meta{value} pairs passed by the user; increase the counter |mgl@image@no| for numbering and naming of images.
+%    \begin{macrocode}
+  \def\mglplot@setup{generic}%
+  \def\graph@keys{}%
+  \setkeys{mglplot@keys}{#1}%
+  \stepcounter{mgl@image@no}%
+%    \end{macrocode}
+% If the given setup is undefined, issue a package error; otherwise, execute the buffer of the setup, which will write the contents of the corresponding |mglsetup| blocks to the general script.
+%    \begin{macrocode}
+  \ifx\csname mgl@setup@\mglplot@setup\endcsname\@undefined%
+    \PackageError{\mgl@name}{Setup "\mglplot@setup" undefined}{}%
   \else%
-    \def\next@action{%
-      \item\mbox{\this@line}%
-      \mglblock@read@line%
-    }%
+    \csname mgl@setup@\mglplot@setup\endcsname%
   \fi%
-  \next@action%
+%    \end{macrocode}
+% Call |\@@mglplot| (see below).
+%    \begin{macrocode}
+  \@@mglplot%
 }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@mglplot}
+% This command writes its argument verbatim to the main script, then writes the command to save the corresponding image, and the \emph{reset} command to prepare MathGL for the next image; finally, it uses the |\mgl@include@image| to include the corresponding graphics in the document.
+%    \begin{macrocode}
+\long\def\@@mglplot#1{%
+  \mgl@write\mgl@script{\detokenize{#1}}%
+  \mgl@write\mgl@script{%
+    write '\mgl@dir\jobname-mgl-\arabic{mgl@image@no}\mgl@image@ext'%
+  }%
+  \mgl@write\mgl@script{reset}%
+  \mgl@include@image{\mgl@dir\jobname-mgl-\arabic{mgl@image@no}}%
+}
+%    \end{macrocode}
+% \end{macro}
+% \subsection{Verbatim-like environments}
+% \begin{macro}{mgl@verb@line@no}
+% \noindent We create a counter to number the lines of code in verbatim-like environments.
+%    \begin{macrocode}
 
 \newcounter{mgl@verb@line@no}
+%    \end{macrocode}
+% \end{macro}
+% \begin{environment}{mglverbatim}
+% This environment writes its contents \emph{verbatim} to the \LaTeX{} document, numbering each line of code.
+% \begin{macro}{\mglverbatim}
+% The beginning of the |mglverbatim| environment.
+%    \begin{macrocode}
+
 \def\mglverbatim{%
+%    \end{macrocode}
+% Initialize the counter for lines of code.
+%    \begin{macrocode}
   \setcounter{mgl@verb@line@no}{0}%
+%    \end{macrocode}
+% We use the list environment to set the numeration of the lines of code that will be written to the \LaTeX{} document as items of the list. We also set the separation between lines of code, the indentation of the line, and some other length parameters.
+%    \begin{macrocode}
   \list{\itshape\footnotesize\arabic{mgl@verb@line@no}.}{}%
   \setlength{\labelsep}{1em}%
   \itemsep\z@skip%
   \leftskip\z@skip\rightskip\z@skip%
-  \verbatim@font%
   \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
+%    \end{macrocode}
+% We do the same changes of categories as in the |mglcode| environment.
+%    \begin{macrocode}
   \let\do\@makeother \dospecials%
   \endlinechar`\^^M \catcode`\^^M\active%
   \obeyspaces%
-  \mglverbatim@ignore@line%
+%    \end{macrocode}
+% use verbatim font.
+%    \begin{macrocode}
+  \verbatim@font%
+%    \end{macrocode}
+% Call the command that will write each line of the contents of the environment.
+%    \begin{macrocode}
+  \expandafter\mglverbatim@ignore@line%
 }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglverbatim@ignore@line}
+% This command ignores the first line of the |verbatim| environment, which is an empty line.
+%    \begin{macrocode}
 \def\mglverbatim@ignore@line#1{%
-  \mglverbatim@write@line%
+  \expandafter\mglverbatim@write@line%
 }
-\newtoks\mgl@word
-\newtoks\mgl@line
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglverbatim@write@line}
+% Reads the contents of the |mglverbatim| character by character, and stores words in the |\mgl@word| buffer and lines in the |\mgl@line| buffer, just like the |mglcode| environment did.
+%    \begin{macrocode}
 \def\mglverbatim@write@line#1{%
+%    \end{macrocode}
+% Unless overwritten later, the next action (|\next@action|) is recursively call |\mglverbatim@write@line|.
+%    \begin{macrocode}
   \let\next@action\mglverbatim@write@line%
+%    \end{macrocode}
+% If the character read is an end-line character,
+%    \begin{macrocode}
   \expandafter\if#1\^^M%
+%    \end{macrocode}
+% increase the line of code counter, write the line contained in |\mgl@line| as an item of the |list| environment, and clean |\mgl@word| and |\mgl@line|;
+%    \begin{macrocode}
     \stepcounter{mgl@verb@line@no}%
     \item\mbox{\the\mgl@line}%
-    \mgl@line{}%
     \mgl@word{}%
+    \mgl@line{}%
+%    \end{macrocode}
+% if the character is a space, clean |\mgl@wors|, but add the space to |\mgl@line|;
+%    \begin{macrocode}
   \else\expandafter\if#1\space%
     \mgl@word{}%
     \mgl@line\expandafter{\the\mgl@line#1}%
+%    \end{macrocode}
+% otherwise, the character is aphanumeric, so add it to the |\mgl@word| and |\mgl@line| buffers, and check if |\mgl@word| is |\end{mglverbatim}|, in which case overwrite |\next@action| to be that command.
+%    \begin{macrocode}
   \else%
     \mgl@word\expandafter{\the\mgl@word#1}%
     \mgl@line\expandafter{\the\mgl@line#1}%
   \fi\fi%
   \next@action%
 }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\end@mglverbatim}
+% \begin{macro}{\test@end@mglverbatim}
+% We already know the purpose of these macros.
+%    \begin{macrocode}
 \begingroup%
   \escapechar=-1\relax%
   \xdef\end@mglverbatim{\string\\end\string\{mglverbatim\string\}}%
     \def\next@action{\end{mglverbatim}}%
   \fi%
 }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%    \begin{macrocode}
+%    \end{macrocode}
+% \begin{macro}{\endmglverbaim}
+% The end of the |mglverbatim| environment. It just closes the |list| environment.
+%    \begin{macrocode}
 \def\endmglverbatim{\endlist}
+%    \end{macrocode}
+% \end{macro}
+% \end{environment}
+% \begin{environment}{mglblock}
+% This environment writes its contents to a script, whose name is passed as mandatory argument, ad then it also writes its contents to the \LaTeX{} document, numbering each line.
+% \begin{macro}{\mglblock}
+% The beginning of the |mglblock environment|.
+%    \begin{macrocode}
+
+\def\mglblock#1{%
+%    \end{macrocode}
+% Check if the script already exists, in which case we issue a warning, but proceed anyway.
+%    \begin{macrocode}
+  \test@mgl@script@written{#1}%
+%    \end{macrocode}
+% Add the name of the script to the list of scripts written.
+%    \begin{macrocode}
+  \xdef\mgl@script@written{\mgl@script@written#1,}%
+%    \end{macrocode}
+% We make the same changes of categories as in the |mglcode| environment.
+%    \begin{macrocode}
+  \let\do\@makeother \dospecials%
+  \endlinechar`\^^M \catcode`\^^M\active%
+  \obeyspaces%
+%    \end{macrocode}
+% Open the output stream for the current script.
+%    \begin{macrocode}
+  \def\this@script{#1}%
+  \if@mgltex@on@%
+    \immediate\openout\mgl@out@stream="\mgl@dir\this@script.mgl"%
+    \mglsignature@write\mgl@out@stream%
+  \fi%
+%    \end{macrocode}
+% Call the command that will write each line of the contents of the environment.
+%    \begin{macrocode}
+  \expandafter\mglblock@write@line%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglblock@write@line}
+% This macro reads characater by character the code inside |mglblock|, and uses the |\mgl@word| and |\mgl@line| buffers to store words and lines of codes, just like we did with the |mglcode| environment.
+%    \begin{macrocode}
+\def\mglblock@write@line#1{%
+%    \end{macrocode}
+% The next action (|\next@action|) is set to recursively call |\mglblock@write@line|, unless it is overwritten later.
+%    \begin{macrocode}
+  \let\next@action\mglblock@write@line%
+%    \end{macrocode}
+% If the read character is an end-line character, write the contents of |\mgl@line| to the script, and the clean |\mgl@word| and |\mgl@line|;
+%    \begin{macrocode}
+  \expandafter\if#1\^^M%
+    \mgl@write\mgl@out@stream{\the\mgl@line}%
+    \mgl@word{}%
+    \mgl@line{}%
+%    \end{macrocode}
+% if the read character if a space, clean |\mgl@word|, but add the space to |\mgl@line|;
+%    \begin{macrocode}
+  \else\expandafter\if#1\space%
+    \mgl@word{}%
+    \mgl@line\expandafter{\the\mgl@line#1}%
+%    \end{macrocode}
+% otherwise, the character is alphnumeric, and should be added to |\mgl@word| and |\mgl@line|, and we test if |\mgl@word| is |\end{mglblock}|, in which case, we overwrite |\next@action| to that command.
+%    \begin{macrocode}
+  \else%
+    \mgl@word\expandafter{\the\mgl@word#1}%
+    \mgl@line\expandafter{\the\mgl@line#1}%
+    \test@end@mglblock{\the\mgl@word}%
+  \fi\fi%
+%    \end{macrocode}
+% Execute |\next@action|.
+%    \begin{macrocode}
+  \next@action%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\end@mglblock}
+% \begin{macro}{\test@end@mglblock}
+% We already know the purpose of these macros.
+%    \begin{macrocode}
+\begingroup%
+  \escapechar=-1\relax%
+  \xdef\end@mglblock{\string\\end\string\{mglblock\string\}}%
+\endgroup%
+\def\test@end@mglblock#1{%
+  \edef\this@word{#1}%
+  \ifx\this@word\end@mglblock%
+    \def\next@action{\end{mglblock}}%
+  \fi%
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\mgl@in@stream}
+% We create an input stream to read from MGL scripts.
+%    \begin{macrocode}
+\newread\mgl@in@stream
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\endmglblock}
+% The end of the |mglblock| environment.
+%    \begin{macrocode}
+\def\endmglblock{%
+%    \end{macrocode}
+% Close the output stream.
+%    \begin{macrocode}
+  \immediate\closeout\mgl@out@stream%
+%    \end{macrocode}
+% Open the input stream.
+%    \begin{macrocode}
+  \immediate\openin\mgl@in@stream="\mgl@dir\this@script.mgl"%
+%    \end{macrocode}
+% Here, we use the |list| environment to set the numeration of the lines of code that will be written to the \LaTeX{} document as items of the list. We also set the separation between lines of code, the indentation of the line, and some other lenght parameters.
+%    \begin{macrocode}
+  \begingroup%
+  \list{\itshape\footnotesize\arabic{mgl@verb@line@no}.}{}%
+  \setlength{\labelsep}{1em}%
+  \itemsep\z@skip%
+  \leftskip\z@skip\rightskip\z@skip%
+  \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
+%    \end{macrocode}
+% Use the verbatim font, and obey spaces, including spaces at the beggining of the line.
+%    \begin{macrocode}
+  \verbatim@font%
+  \@vobeyspaces%
+%    \end{macrocode}
+% Call the command that will write the lines of code to the \LaTeX{} document.
+%    \begin{macrocode}
+  \mglblock@read@line%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglblock@read@line}
+% This command reads lines of code from the input stream and writes them as items of the |list| environment.
+%    \begin{macrocode}
+\def\mglblock@read@line{%
+%    \end{macrocode}
+% Increase the line counter.
+%    \begin{macrocode}
+  \stepcounter{mgl@verb@line@no}%
+%    \end{macrocode}
+% Read a line from the input stream.
+%    \begin{macrocode}
+  \read\mgl@in@stream to \this@line%
+%    \end{macrocode}
+% If the end of file has been reached, define |\next@action| to close the input stream, and en the |list| environment;
+%    \begin{macrocode}
+  \ifeof\mgl@in@stream%
+    \def\next@action{%
+      \immediate\closein\mgl@in@stream%
+      \endlist%
+      \endgroup%
+    }%
+%    \end{macrocode}
+% otherwise, |\next@action| is write the read line as an item of the |list| environment, and recursively call |\mglblock@read@line|.
+%    \begin{macrocode}
+  \else%
+    \def\next@action{%
+      \item\mbox{\this@line}%
+      \mglblock@read@line%
+    }%
+  \fi%
+%    \end{macrocode}
+% Execute |\next@action|.
+%    \begin{macrocode}
+  \next@action%
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{environment}
+% \subsection{Working with external scripts}
+% \begin{macro}{\mglgraphics}
+% This command allows to generate and include graphics from a external (not embedded) script.
+%    \begin{macrocode}
 
 \newcommand\mglgraphics[2][]{%
+%    \end{macrocode}
+%   Initialize |\graph@keys|, which will contain the \meta{key}=\meta{value} options for the |\includegraphics|command.
+%    \begin{macrocode}
   \def\graph@keys{}%
+%    \end{macrocode}
+% Process the \meta{key}=\meta{value} options passed by the user.
+%    \begin{macrocode}
   \setkeys{mgl@keys}{#1}%
-  \immediate\write18{mglconv "\mgl@dir#2.mgl" -o "\mgl@dir#2\mgl@image@ext"}
+%    \end{macrocode}
+% Execute the program |mglconv| (included in MathGL) to compile the corresponding script.
+%    \begin{macrocode}
+  \mgl@write{18}{mglconv "\mgl@dir#2.mgl" -s "\mgl@dir\mglcommonscript.mgl" -o "\mgl@dir#2\mgl@image@ext"}
+%    \end{macrocode}
+% Include the generated image with the |\mgl@include@image| command.
+%    \begin{macrocode}
   \mgl@include@image{\mgl@dir#2}%
 }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglinclude}
+% This command copies verbatim the contents of an external script, and numerates each line of code.
+%    \begin{macrocode}
 
 \def\mglinclude#1{%
+%    \end{macrocode}
+% Initialize the line counter.
+%    \begin{macrocode}
   \setcounter{mgl@verb@line@no}{0}%
+%    \end{macrocode}
+% Open the script in the input stream.
+%    \begin{macrocode}
   \immediate\openin\mgl@in@stream="\mgl@dir#1.mgl"%
+%    \end{macrocode}
+% Here, we use the |list| environment to numerate each line of code as an item. We also set some length parameters.
+%    \begin{macrocode}
   \begingroup%
   \list{\itshape\footnotesize\arabic{mgl@verb@line@no}.}{}%
   \setlength{\labelsep}{1em}%
   \itemsep\z@skip%
   \leftskip\z@skip\rightskip\z@skip%
-  \verbatim@font%
   \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
+%    \end{macrocode}
+% We do the same changes of category as in the |mglcode| environment, and set the font to verbatim font.
+%    \begin{macrocode}
   \let\do\@makeother \dospecials%
   \endlinechar`\^^M \catcode`\^^M\active%
   \@vobeyspaces%
+  \verbatim@font%
+%    \end{macrocode}
+% We (re)use the |\mglblock@read@line| command to numerate and write each line of code.
+%    \begin{macrocode}
   \mglblock@read@line%
 }
+%    \end{macrocode}
+% \end{macro}
+% \subsection{Additional commands}
+% \begin{macro}{\mgldir}
+% A command to specify a directory to write the scripts and create the images.
+% First, we create a macro that will store the specified directory for later use.
+%    \begin{macrocode}
+
+\def\mgl@dir{}
+%    \end{macrocode}
+% The command |\mgldir| is the only way to modify |\mgl@dir|. This is done so the user won't be able to modify the default directory, dangerously altering the internal behavior of the package.
+%    \begin{macrocode}
+\def\mgldir#1{%
+  \def\mgl@dir{#1}%
+}
+%    \end{macrocode}
+% Declare |\mgldir| so that it can only be used in the preamble. This is because the main script \meta{document}.mgl is opened at the moment of the |\begin{document}| instruction.
+%    \begin{macrocode}
+\@onlypreamble\mgldir
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mgl@quality}
+% We define a macro to store the quality.
+%    \begin{macrocode}
+\def\mgl@quality{2}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglquality}
+% This is used to define the quality for MGL graphics.
+%    \begin{macrocode}
+\def\mglquality#1{%
+%    \end{macrocode}
+% Write the quality command to a setup script.
+%    \begin{macrocode}
+  \def\mgl@quality{#1}%
+  \if@mgltex@on@%
+    \immediate\openout\mgl@out@stream="\mgl@dir\mglcommonscript.mgl"%
+    \mgl@write\mgl@out@stream{quality #1}%
+    \immediate\closeout\mgl@out@stream%
+%    \end{macrocode}
+% Print an info message about the corresponding quality, or a warning if the quality doesn't exist.
+%    \begin{macrocode}
+    \ifcase#1
+      \PackageInfo{mgltex}{Quality 0: No face drawing (fastest)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 1: No color interpolation (fast)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 2: High quality (normal)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 3: High quality with 3d primitives (not implemented yet)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 4: No face drawing, direct bitmap drawing (low memory usage)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 5: No color interpolation, direct bitmap drawing (low memory usage)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 6: High quality, direct bitmap drawing (low memory usage)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 7: High quality with 3d primitives, direct bitmap drawing (not implemented yet)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 8: Draw dots instead of primitives (extremely fast)}%
+    \else%
+      \PackageWarning{mgltex}{Quality #1 not available. Using default (2)}%
+    \fi%
+  \else%
+    \PackageWarning{mgltex}{mglTeX is off, quality changes won't have effect}%
+  \fi%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mgltexon}
+% \changes{v.2.0}{2014/11/15}{Add the command \texttt{\textbackslash mgltexon}}
+% Has the same effect as the package option |on|, but its effect is local, meaning that works only from the point this command is called on.
+%    \begin{macrocode}
+
+\def\mgltexon{
+  \@mgltex@on@true
+  \def\mgl@write##1##2{%
+    \immediate\write##1{##2}%
+  }
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mgltexoff}
+% \changes{v.2.0}{2014/11/15}{Add the command \texttt{\textbackslash mgltexoff}}
+% Has the same effect as the package option |off|, but its effect is local.
+%    \begin{macrocode}
+\def\mgltexoff{%
+  \@mgltex@on@false
+  \def\mgl@write##1##2{}%
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglcomments}
+% \changes{v2.0}{2014/11/22}{Add the command \texttt{\textbackslash mglcomments}}
+% Has the same effect as the package option |comments|, but its effect is local, meaning that works only from the point this command is called on.
+%    \begin{macrocode}
+
+\def\mglcomments{
+  \@mgl@comments@true
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglnocomments}
+% \changes{v2.0}{2014/11/22}{Add the command \texttt{\textbackslash mglnocomments}}
+% Has the same effect as the package option |off|, but its effect is local.
+%    \begin{macrocode}
+\def\mglnocomments{%
+  \@mgl@comments@false
+}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\mglTeX}
+% Just pretty-prints the name of the package.
+%    \begin{macrocode}
 
 \def\mglTeX{mgl\TeX}
 %    \end{macrocode}
+% \end{macro}
+
+
 % \Finale
\ No newline at end of file
diff --git a/mgltex/mgltex.ins b/mgltex/mgltex.ins
new file mode 100644 (file)
index 0000000..f780ff3
--- /dev/null
@@ -0,0 +1,61 @@
+%%
+%% Copyright (C) 2014 by Diego Sejas <diego.mathematician@gmail.com>
+%% 
+%% This program is free software: you can redistribute it and/or modify it
+%% under the terms of the GNU General Public License as published by the
+%% Free Software Foundation, either version 3 of the License, or (at your
+%% option) any later version.
+%% 
+%% This program is distributed in the hope that it will be useful, but
+%% WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+%% Public License for more details.
+%% 
+%% You should have received a copy of the GNU General Public License along
+%% with this program.  If not, see <http://www.gnu.org/licenses/>.
+%%
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/latex/mgltex}
+
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2014 by Diego Sejas <diego.mathematician@gmail.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+\endpreamble
+
+\generate{\file{mgltex.sty}{\from{mgltex.dtx}{package}}}
+
+\obeyspaces
+\Msg{**********************************************************}
+\Msg{*                                                        *}
+\Msg{* To finish the installation you have to move the        *}
+\Msg{* following file into a directory searched by TeX:       *}
+\Msg{*                                                        *}
+\Msg{*          mgltex.sty                                    *}
+\Msg{*                                                        *}
+\Msg{* To produce the documentation run the file mgltex.dtx   *}
+\Msg{* through LaTeX.                                         *}
+\Msg{*                                                        *}
+\Msg{* Happy TeXing!                                          *}
+\Msg{*                                                        *}
+\Msg{**********************************************************}
+
+\endbatchfile
\ No newline at end of file
diff --git a/mgltex/mgltex.installer b/mgltex/mgltex.installer
deleted file mode 100644 (file)
index f780ff3..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-%%
-%% Copyright (C) 2014 by Diego Sejas <diego.mathematician@gmail.com>
-%% 
-%% This program is free software: you can redistribute it and/or modify it
-%% under the terms of the GNU General Public License as published by the
-%% Free Software Foundation, either version 3 of the License, or (at your
-%% option) any later version.
-%% 
-%% This program is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-%% Public License for more details.
-%% 
-%% You should have received a copy of the GNU General Public License along
-%% with this program.  If not, see <http://www.gnu.org/licenses/>.
-%%
-
-\input docstrip.tex
-\keepsilent
-
-\usedir{tex/latex/mgltex}
-
-\preamble
-
-This is a generated file.
-
-Copyright (C) 2014 by Diego Sejas <diego.mathematician@gmail.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation, either version 3 of the License, or (at your
-option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-\endpreamble
-
-\generate{\file{mgltex.sty}{\from{mgltex.dtx}{package}}}
-
-\obeyspaces
-\Msg{**********************************************************}
-\Msg{*                                                        *}
-\Msg{* To finish the installation you have to move the        *}
-\Msg{* following file into a directory searched by TeX:       *}
-\Msg{*                                                        *}
-\Msg{*          mgltex.sty                                    *}
-\Msg{*                                                        *}
-\Msg{* To produce the documentation run the file mgltex.dtx   *}
-\Msg{* through LaTeX.                                         *}
-\Msg{*                                                        *}
-\Msg{* Happy TeXing!                                          *}
-\Msg{*                                                        *}
-\Msg{**********************************************************}
-
-\endbatchfile
\ No newline at end of file
index 61542e961b87f3f5dc290d96979e0413542cd7ce..fb4fedfe9a45fcc560e47c830ec8c60b2585331f 100644 (file)
Binary files a/mgltex/mgltex.pdf and b/mgltex/mgltex.pdf differ
index 33fea4b0e55d057b2e776b7ebd36c9d7e451abda..a4eb204aa67fd4dd7681a904dc6197f06a65cc38 100644 (file)
 %% You should have received a copy of the GNU General Public License along
 %% with this program.  If not, see <http://www.gnu.org/licenses/>.
 %% 
-\def\mgl@name{mgltex}
-\def\mgl@date{2014/09/16}
-\def\mgl@version{1.0}
-\def\mgl@description{Embed MGL code into LaTeX documents}
-
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{\mgl@name}[\mgl@date\space v.\mgl@version\space\mgl@description]
+\ProvidesPackage{mgltex}[/2014/11/22 v2.0 Embed MGL scripts in LaTeX documents]
+
 
 \RequirePackage{keyval}
 \RequirePackage{graphicx}
 
+
 \DeclareOption{draft}{%
   \PassOptionsToPackage{\CurrentOption}{graphicx}%
 }
 \DeclareOption{final}{%
   \PassOptionsToPackage{\CurrentOption}{graphicx}%
 }
+\newif\if@mgltex@on@
+\DeclareOption{on}{%
+  \@mgltex@on@true%
+  \def\mgl@write#1#2{%
+    \immediate\write#1{#2}%
+  }
+}
+\DeclareOption{off}{%
+  \@mgltex@on@false%
+  \def\mgl@write#1#2{}%
+}
+\newif\if@mgl@comments@
+\DeclareOption{comments}{%
+  \@mgl@comments@true%
+}
+\DeclareOption{nocomments}{%
+  \@mgl@comments@false%
+}
 
-\DeclareGraphicsExtensions{.png,.eps,.jpg,.jpeg,.bps,.pdf,.epsz,.eps.gz,.bpsz,.bps.gz,.gif}
+\DeclareGraphicsExtensions{%
+  .png,.eps,.jpg,.jpeg,.bps,.pdf,.epsz,.eps.gz,.bpsz,.bps.gz,.gif%
+}
 
 \DeclareOption{jpg}{\def\mgl@image@ext{.jpg}}
 \DeclareOption{jpeg}{\def\mgl@image@ext{.jpeg}}
@@ -54,8 +71,9 @@
 \DeclareOption{gif}{\def\mgl@image@ext{.gif}}
 
 \DeclareOption{tex}{\def\mgl@image@ext{.tex}}
+\DeclareOption*{\@unknownoptionerror}
 
-\ExecuteOptions{final,eps}
+\ExecuteOptions{final,on,nocomments,eps}
 \ProcessOptions*
 
 \define@key{mgl@keys}{bb}{\g@addto@macro{\graph@keys}{bb=#1,}}
 \define@key{mgl@keys}{command}{\g@addto@macro{\graph@keys}{command=#1,}}
 \define@key{mgl@keys}{imgext}{\def\mgl@image@ext{.#1}}
 
+
 \define@key{mglplot@keys}{bb}{\g@addto@macro{\graph@keys}{bb=#1,}}
 \define@key{mglplot@keys}{bbllx}{\g@addto@macro{\graph@keys}{bbllx=#1,}}
 \define@key{mglplot@keys}{bblly}{\g@addto@macro{\graph@keys}{bblly=#1,}}
 \define@key{mglplot@keys}{ext}{\g@addto@macro{\graph@keys}{ext=#1,}}
 \define@key{mglplot@keys}{read}{\g@addto@macro{\graph@keys}{read=#1,}}
 \define@key{mglplot@keys}{command}{\g@addto@macro{\graph@keys}{command=#1,}}
-\define@key{mglplot@keys}{outext}{\def\mglplot@output@ext{.#1}}
-\define@key{mglplot@keys}{settings}{\def\mglplot@settings{#1}}
+\define@key{mglplot@keys}{imgext}{\def\mglplot@image@ext{.#1}}
+\define@key{mglplot@keys}{setup}{\def\mglplot@setup{#1}}
 
-\def\mgl@dir{}
-\def\mgldir#1{%
-  \def\mgl@dir{#1}%
-}
-\@onlypreamble\mgldir
-
-\newwrite\mgl@script
-\AtBeginDocument{%
-  \immediate\openout\mgl@script="\mgl@dir\jobname.mgl"%
-}
-\AtEndDocument{%
-  \immediate\write\mgl@script{}%
-  \immediate\write\mgl@script{stop}%
-  \mgl@func%
-  \immediate\closeout\mgl@script%
-  \immediate\write18{mglconv -n "\mgl@dir\jobname.mgl"}%
-}
 
-\def\mglplotsettings@defined{}
-\newcommand\mglplotsettings[1][generic]{%
-  \test@mglplotsettings@defined{#1}%
-  \expandafter\def\csname mgl@setup@#1\endcsname{\immediate\write\mgl@script{}}%
-  \g@addto@macro{\mglplotsettings@defined}{#1,}%
-  \let\do\@makeother \dospecials%
-  \endlinechar`\^^M \catcode`\^^M\active%
-  \catcode`\ =10%
-  \expandafter\mglplotsettings@write@line%
-}
-\def\test@mglplotsettings@defined#1{%
-  \def\this@setup{#1}%
-  \@for\mglplotsettings@name:=\mglplotsettings@defined\do{%
-    \ifx\this@mglplotsettings\mglplotsettings@name%
-      \PackageWarning{\mgl@name}{Redefining "#1" setup for \noexpand\mglplot}%
-    \fi%
-  }%
-}
-\begingroup%
-  \catcode`\^^M\active%
-  \gdef\mglplotsettings@write@line#1^^M{%
-    \def\next@action{%
-      \expandafter\g@addto@macro\csname mgl@setup@\this@setup\endcsname{\immediate\write\mgl@script{#1}}%
-      \mglplotsettings@write@line%
+\def\TeX@ext{.tex}
+\def\mgl@include@image#1{%
+  \ifx\mgl@image@ext\TeX@ext%
+    \IfFileExists{#1.tex}{%
+      \include{#1}%
+    }{%
+      \mgl@img@not@found{#1}%
+    }%
+  \else%
+  \def\next@action{\mgl@img@not@found{#1}}%
+    \@for\img@ext:=\Gin@extensions\do{%
+      \IfFileExists{#1\img@ext}{%
+        \def\next@action{%
+          \expandafter\includegraphics\expandafter[\graph@keys]{#1}%
+        }%
+      }{}%
     }%
-    \test@end@mglplotsettings{#1}%
     \next@action%
-  }%
-\endgroup
-\begingroup%
-  \escapechar=-1 \relax%
-  \xdef\end@mglplotsettings{\string\\end\string\{mglplotsettings\string\}}%
-\endgroup
-\def\test@end@mglplotsettings#1{%
-  \edef\this@line{#1}%
-  \ifx\this@line\end@mglplotsettings%
-    \def\next@action{\end{mglplotsettings}}%
   \fi%
 }
-\def\endmglplotsettings{}
+\def\mgl@img@not@found#1{%
+  \PackageWarning{mgltex}{MGL image "#1" not found}%
+  \framebox[10em]{%
+    \centering%
+    \bfseries\Huge%
+    \begin{tabular}{c}MGL\\image\\not\\found\end{tabular}%
+  }%
+}
 
-\def\TeX@ext{.tex}
 \newcounter{mgl@image@no}
 
-\def\mglplot{%
-  \@ifnextchar[{\@mglplot}{\@mglplot[]}%
-}
-\def\@mglplot[#1]{%
-  \def\mglplot@settings{generic}%
-  \def\graph@keys{}%
-  \setkeys{mglplot@keys}{#1}%
-  \stepcounter{mgl@image@no}%
-  \ifx\csname mgl@setup@\mglplot@settings\endcsname\@undefined%
-    \PackageError{\mgl@name}{Setup "\mglplot@settings" undefined}{}%
-  \else%
-    \csname mgl@setup@\mglplot@settings\endcsname%
+\newwrite\mgl@script
+\AtBeginDocument{%
+  \if@mgltex@on@%
+    \immediate\openout\mgl@script="\mgl@dir\jobname.mgl"%
+    \mglsignature@write\mgl@script%
   \fi%
-  \@@mglplot%
 }
-\long\def\@@mglplot#1{%
-  \immediate\write\mgl@script{\detokenize{#1}}%
-  \immediate\write\mgl@script{write '\mgl@dir\jobname-mgl-\arabic{mgl@image@no}\mgl@image@ext'}%
-  \immediate\write\mgl@script{reset}%
-  \mgl@include@image{\mgl@dir\jobname-mgl-\arabic{mgl@image@no}}%
+\AtEndDocument{%
+  \mgl@write\mgl@script{}%
+  \mgl@write\mgl@script{stop}%
+  \mgl@func%
+  \immediate\closeout\mgl@script%
+  \mgl@write{18}{mglconv -n "\mgl@dir\jobname.mgl"}%
 }
 
+
 \newcommand\mgl[1][]{%
   \def\graph@keys{}%
   \setkeys{mgl@keys}{#1}%
   \let\do\@makeother \dospecials%
   \endlinechar`\^^M \catcode`\^^M\active%
   \catcode`\ =10%
-  \mgl@write@line%
+  \mgl@write\mgl@script{quality \mgl@quality}%
+  \expandafter\mgl@write@line%
 }
 \begingroup%
   \escapechar=-1 \relax%
   \xdef\end@mgl{\string\\end\string\{mgl\string\}}%
 \endgroup
+
 \begingroup%
+
   \catcode`\^^M\active%
   \gdef\mgl@write@line#1^^M{%
     \def\next@action{%
-      \immediate\write\mgl@script{#1}%
+      \mgl@write\mgl@script{#1}%
       \mgl@write@line%
     }%
     \test@end@mgl{#1}%
     \next@action%
   }%
 \endgroup
+
 \def\test@end@mgl#1{%
   \edef\this@line{#1}%
   \ifx\this@line\end@mgl%
 }
 \def\endmgl{%
   \stepcounter{mgl@image@no}%
-  \immediate\write\mgl@script{write '\mgl@dir\jobname-mgl-\arabic{mgl@image@no}\mgl@image@ext'}%
-  \immediate\write\mgl@script{reset}%
-  \mgl@include@image{\mgl@dir\jobname-mgl-\arabic{mgl@image@no}}%
-}
-\def\mgl@include@image#1{%
-  \ifx\mgl@image@ext\TeX@ext%
-    \IfFileExists{#1.tex}{%
-      \include{#1}%
-    }{%
-      \mgl@img@not@found{#1}%
-    }%
-  \else%
-  \def\next@action{\mgl@img@not@found{#1}}%
-    \@for\img@ext:=\Gin@extensions\do{%
-      \IfFileExists{#1\img@ext}{%
-        \def\next@action{%
-          \expandafter\includegraphics\expandafter[\graph@keys]{#1}%
-        }%
-      }{}%
-    }%
-    \next@action%
-  \fi%
-}
-\def\mgl@img@not@found#1{%
-  \PackageWarning{\mgl@name}{MGL image "#1" not found}%
-  \framebox[10em]{%
-    \centering%
-    \bfseries\Huge%
-    \vbox{MGL\\image\\not\\found}%
+  \mgl@write\mgl@script{%
+    write '\mgl@dir\jobname-mgl-\arabic{mgl@image@no}\mgl@image@ext'%
   }%
+  \mgl@write\mgl@script{reset}%
+  \mgl@write\mgl@script{}%
+  \mgl@include@image{\mgl@dir\jobname-mgl-\arabic{mgl@image@no}}%
 }
 
 \bgroup%
   \test@mgl@script@written{#2}%
   \xdef\mgl@script@written{\mgl@script@written#2,}%
   \def\this@script{#2}%
-  \immediate\openout\mgl@out@stream=\mgl@dir\this@script.mgl%
+  \if@mgltex@on@%
+    \immediate\openout\mgl@out@stream=\mgl@dir\this@script.mgl%
+    \mglsignature@write\mgl@out@stream%
+  \fi%
   \let\do\@makeother \dospecials%
   \endlinechar`\^^M \catcode`\^^M\active%
   \obeyspaces%
-  \mglcode@write@line%
+  \expandafter\mglcode@write@line%
 }
 \def\test@mgl@script@written#1{%
   \edef\this@script{#1}%
   \@for\mgl@script@name:=\mgl@script@written\do{%
     \ifx\this@script\mgl@script@name%
-      \PackageWarning{\mgl@name}{Overwriting MGL script "\this@script.mgl"}%
+      \PackageWarning{mgltex}{Overwriting MGL script "\this@script.mgl"}%
     \fi%
   }%
 }
+\newtoks\mgl@word
+\newtoks\mgl@line
 \def\mglcode@write@line#1{%
   \let\next@action\mglcode@write@line%
   \expandafter\if#1\^^M%
-    \immediate\write\mgl@out@stream{\the\mgl@line}%
-    \mgl@line{}%
+    \mgl@write\mgl@out@stream{\the\mgl@line}%
     \mgl@word{}%
+    \mgl@line{}%
   \else\expandafter\if#1\space%
     \mgl@word{}%
     \mgl@line\expandafter{\the\mgl@line#1}%
 }
 \def\endmglcode{%
   \immediate\closeout\mgl@out@stream%
-  \immediate\write18{mglconv "\mgl@dir\this@script.mgl" -o "\mgl@dir\this@script\mgl@image@ext"}%
+  \mgl@write{18}{%
+    mglconv "\mgl@dir\this@script.mgl" -s "\mgl@dir\mglcommonscript.mgl" -o "\mgl@dir\this@script\mgl@image@ext"%
+  }%
   \mgl@include@image{\mgl@dir\this@script}%
 }
 
 
 \def\mglfunc@defined{}
 \def\mgl@func{}
+
 \newcommand\mglfunc[2][0]{%
   \test@mglfunc@defined{#2}%
   \g@addto@macro{\mglfunc@defined}{#2,}%
   \let\do\@makeother \dospecials%
   \endlinechar`\^^M \catcode`\^^M\active%
   \catcode`\ =10%
-  \g@addto@macro{\mgl@func}{\immediate\write\mgl@script{}}%
-  \g@addto@macro{\mgl@func}{\immediate\write\mgl@script{func '#2' #1}}%
-  \expandafter\mglfunc@ignore@line%
+  \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{}}%
+  \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{func '#2' #1}}%
+  \expandafter\mglfunc@write@line%
 }
 \def\test@mglfunc@defined#1{%
   \def\this@func{#1}%
 }
 \begingroup%
   \catcode`\^^M\active%
-  \gdef\mglfunc@ignore@line#1^^M{%
-    \expandafter\mglfunc@write@line%
-  }
   \gdef\mglfunc@write@line#1^^M{%
     \def\next@action{%
-      \g@addto@macro{\mgl@func}{\immediate\write\mgl@script{#1}}%
-      \mglfunc@write@line%
+      \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{#1}}%
+      \expandafter\mglfunc@write@line%
     }%
     \test@end@mglfunc{#1}%
     \next@action%
   \fi%
 }
 \def\endmglfunc{%
-  \g@addto@macro{\mgl@func}{\immediate\write\mgl@script{return}}%
+  \g@addto@macro{\mgl@func}{\mgl@write\mgl@script{return}}%
 }
 
+
+\def\mglcommonscript{mgl_common_script}
+\bgroup%
+  \escapechar=-1\relax%
+  \xdef\end@mglcommon{\string\\end\string\{mglcommon\string\}}%
+\egroup%
+\newenvironment{mglcommon}{%
+  \def\test@end@mglcode##1{%
+    \edef\this@word{##1}%
+    \ifx\this@word\end@mglcommon%
+      \def\next@action{\end{mglcommon}}%
+    \fi%
+  }%
+  \mglcode{\mglcommonscript}%
+}{%
+  \mgl@write\mgl@out@stream{quality \mgl@quality}%
+  \immediate\closeout\mgl@out@stream%
+}
+\@onlypreamble\mglcommon
+\bgroup
+  \catcode`#=12
+  \gdef\mglcomm{#}
+\egroup
+\def\mgltexsignature{%
+  \mglcomm^^J%
+  \mglcomm\space This file was autogenerated from the document \jobname.tex on date \today^^J%
+  \mglcomm%
+}
+\newcommand\mglsignature{%
+  \def\mgltexsignature{}%
+  \let\do\@makeother \dospecials%
+  \endlinechar`\^^M \catcode`\^^M\active%
+  \@vobeyspaces%
+  \expandafter\mglsignature@write@line%
+}
+\begingroup%
+  \escapechar=-1 \relax%
+  \xdef\end@mglsignature{\string\\end\string\{mglsignature\string\}}%
+\endgroup
+\begingroup%
+  \catcode`\^^M\active%
+  \gdef\mglsignature@write@line#1^^M{%
+    \def\next@action{%
+      \g@addto@macro{\mgltexsignature}{\mglcomm\space#1^^J}
+      \mglsignature@write@line%
+    }%
+    \test@end@mglsignature{#1}%
+    \next@action%
+  }%
+\endgroup
+\def\test@end@mglsignature#1{%
+  \edef\this@line{#1}%
+  \ifx\this@line\end@mglsignature%
+    \def\next@action{\end{mglsignature}}%
+  \fi%
+}
+\def\endmglsignature{%
+  \g@addto@macro{\mgltexsignature}{\mglcomm}
+}
+\def\mglsignature@write#1{\mgl@write#1{\mgltexsignature}}
+
+\def\mglcomment{%
+  \let\do\@makeother\dospecials%
+  \obeylines%
+  \@vobeyspaces%
+  \verbatim@font%
+  \small%
+  \mgl@comment%
+}
+\begingroup%
+  \catcode`|=0\catcode`[= 1\catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\\=12%
+  |gdef|mgl@comment#1\end{mglcomment}[%
+    |if@mgl@comments@%
+      |begin[center]%
+        <------------------ MGL comment ------------------>%
+        #1%
+        <------------------ MGL comment ------------------>%
+      |end[center]%
+    |fi%
+    |end[mglcomment]]%
+|endgroup%
+\def\endmglcomment{}
+
+
+\def\mglsetup@defined{}
+\newcommand\mglsetup[1][generic]{%
+  \test@mglsetup@defined{#1}%
+  \g@addto@macro{\mglsetup@defined}{#1,}%
+  \expandafter\def\csname mgl@setup@#1\endcsname{\mgl@write\mgl@script{}}%
+  \expandafter\def\csname mgl@setup@#1\endcsname{\mgl@write\mgl@script{quality \mgl@quality}}%
+  \let\do\@makeother \dospecials%
+  \endlinechar`\^^M \catcode`\^^M\active%
+  \catcode`\ =10%
+  \expandafter\mglsetup@write@line%
+}
+\def\test@mglsetup@defined#1{%
+  \def\this@setup{#1}%
+  \@for\mglsetup@name:=\mglsetup@defined\do{%
+    \ifx\this@mglsetup\mglsetup@name%
+      \PackageWarning{\mgl@name}{Redefining "#1" setup for \noexpand\mglplot}%
+    \fi%
+  }%
+}
+\begingroup%
+  \catcode`\^^M\active%
+  \gdef\mglsetup@write@line#1^^M{%
+    \def\next@action{%
+      \expandafter\g@addto@macro\csname mgl@setup@\this@setup\endcsname{%
+        \mgl@write\mgl@script{#1}%
+      }%
+      \expandafter\mglsetup@write@line%
+    }%
+    \test@end@mglsetup{#1}%
+    \next@action%
+  }%
+\endgroup
+\begingroup%
+  \escapechar=-1 \relax%
+  \xdef\end@mglsetup{\string\\end\string\{mglsetup\string\}}%
+\endgroup
+\def\test@end@mglsetup#1{%
+  \edef\this@line{#1}%
+  \ifx\this@line\end@mglsetup%
+    \def\next@action{\end{mglsetup}}%
+  \fi%
+}
+\def\endmglsetup{}
+
+
+\def\mglplot{%
+  \@ifnextchar[{\@mglplot}{\@mglplot[]}%
+}
+\def\@mglplot[#1]{%
+  \def\mglplot@setup{generic}%
+  \def\graph@keys{}%
+  \setkeys{mglplot@keys}{#1}%
+  \stepcounter{mgl@image@no}%
+  \ifx\csname mgl@setup@\mglplot@setup\endcsname\@undefined%
+    \PackageError{\mgl@name}{Setup "\mglplot@setup" undefined}{}%
+  \else%
+    \csname mgl@setup@\mglplot@setup\endcsname%
+  \fi%
+  \@@mglplot%
+}
+\long\def\@@mglplot#1{%
+  \mgl@write\mgl@script{\detokenize{#1}}%
+  \mgl@write\mgl@script{%
+    write '\mgl@dir\jobname-mgl-\arabic{mgl@image@no}\mgl@image@ext'%
+  }%
+  \mgl@write\mgl@script{reset}%
+  \mgl@include@image{\mgl@dir\jobname-mgl-\arabic{mgl@image@no}}%
+}
+
+\newcounter{mgl@verb@line@no}
+
+\def\mglverbatim{%
+  \setcounter{mgl@verb@line@no}{0}%
+  \list{\itshape\footnotesize\arabic{mgl@verb@line@no}.}{}%
+  \setlength{\labelsep}{1em}%
+  \itemsep\z@skip%
+  \leftskip\z@skip\rightskip\z@skip%
+  \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
+  \let\do\@makeother \dospecials%
+  \endlinechar`\^^M \catcode`\^^M\active%
+  \obeyspaces%
+  \verbatim@font%
+  \expandafter\mglverbatim@ignore@line%
+}
+\def\mglverbatim@ignore@line#1{%
+  \expandafter\mglverbatim@write@line%
+}
+\def\mglverbatim@write@line#1{%
+  \let\next@action\mglverbatim@write@line%
+  \expandafter\if#1\^^M%
+    \stepcounter{mgl@verb@line@no}%
+    \item\mbox{\the\mgl@line}%
+    \mgl@word{}%
+    \mgl@line{}%
+  \else\expandafter\if#1\space%
+    \mgl@word{}%
+    \mgl@line\expandafter{\the\mgl@line#1}%
+  \else%
+    \mgl@word\expandafter{\the\mgl@word#1}%
+    \mgl@line\expandafter{\the\mgl@line#1}%
+    \test@end@mglverbatim{\the\mgl@word}%
+  \fi\fi%
+  \next@action%
+}
+\begingroup%
+  \escapechar=-1\relax%
+  \xdef\end@mglverbatim{\string\\end\string\{mglverbatim\string\}}%
+\endgroup%
+\def\test@end@mglverbatim#1{%
+  \edef\this@word{#1}%
+  \ifx\this@word\end@mglverbatim%
+    \def\next@action{\end{mglverbatim}}%
+  \fi%
+}
+\def\endmglverbatim{\endlist}
+
 \def\mglblock#1{%
   \test@mgl@script@written{#1}%
   \xdef\mgl@script@written{\mgl@script@written#1,}%
-  \def\this@script{#1}%
   \let\do\@makeother \dospecials%
   \endlinechar`\^^M \catcode`\^^M\active%
   \obeyspaces%
-  \immediate\openout\mgl@out@stream="\mgl@dir\this@script.mgl"%
-  \mglblock@ignore@line%
-}
-\def\mglblock@ignore@line#1{%
-  \mglblock@write@line%
+  \def\this@script{#1}%
+  \if@mgltex@on@%
+    \immediate\openout\mgl@out@stream="\mgl@dir\this@script.mgl"%
+    \mglsignature@write\mgl@out@stream%
+  \fi%
+  \expandafter\mglblock@write@line%
 }
 \def\mglblock@write@line#1{%
   \let\next@action\mglblock@write@line%
   \expandafter\if#1\^^M%
-    \immediate\write\mgl@out@stream{\the\mgl@line}%
-    \mgl@line{}%
+    \mgl@write\mgl@out@stream{\the\mgl@line}%
     \mgl@word{}%
+    \mgl@line{}%
   \else\expandafter\if#1\space%
     \mgl@word{}%
     \mgl@line\expandafter{\the\mgl@line#1}%
   \setlength{\labelsep}{1em}%
   \itemsep\z@skip%
   \leftskip\z@skip\rightskip\z@skip%
-  \verbatim@font%
   \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
+  \verbatim@font%
   \@vobeyspaces%
   \mglblock@read@line%
 }
   \next@action%
 }
 
-\newcounter{mgl@verb@line@no}
-\def\mglverbatim{%
-  \setcounter{mgl@verb@line@no}{0}%
-  \list{\itshape\footnotesize\arabic{mgl@verb@line@no}.}{}%
-  \setlength{\labelsep}{1em}%
-  \itemsep\z@skip%
-  \leftskip\z@skip\rightskip\z@skip%
-  \verbatim@font%
-  \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
-  \let\do\@makeother \dospecials%
-  \endlinechar`\^^M \catcode`\^^M\active%
-  \obeyspaces%
-  \mglverbatim@ignore@line%
-}
-\def\mglverbatim@ignore@line#1{%
-  \mglverbatim@write@line%
-}
-\newtoks\mgl@word
-\newtoks\mgl@line
-\def\mglverbatim@write@line#1{%
-  \let\next@action\mglverbatim@write@line%
-  \expandafter\if#1\^^M%
-    \stepcounter{mgl@verb@line@no}%
-    \item\mbox{\the\mgl@line}%
-    \mgl@line{}%
-    \mgl@word{}%
-  \else\expandafter\if#1\space%
-    \mgl@word{}%
-    \mgl@line\expandafter{\the\mgl@line#1}%
-  \else%
-    \mgl@word\expandafter{\the\mgl@word#1}%
-    \mgl@line\expandafter{\the\mgl@line#1}%
-    \test@end@mglverbatim{\the\mgl@word}%
-  \fi\fi%
-  \next@action%
-}
-\begingroup%
-  \escapechar=-1\relax%
-  \xdef\end@mglverbatim{\string\\end\string\{mglverbatim\string\}}%
-\endgroup%
-\def\test@end@mglverbatim#1{%
-  \edef\this@word{#1}%
-  \ifx\this@word\end@mglverbatim%
-    \def\next@action{\end{mglverbatim}}%
-  \fi%
-}
-\def\endmglverbatim{\endlist}
-
 \newcommand\mglgraphics[2][]{%
   \def\graph@keys{}%
   \setkeys{mgl@keys}{#1}%
-  \immediate\write18{mglconv "\mgl@dir#2.mgl" -o "\mgl@dir#2\mgl@image@ext"}
+  \mgl@write{18}{mglconv "\mgl@dir#2.mgl" -s "\mgl@dir\mglcommonscript.mgl" -o "\mgl@dir#2\mgl@image@ext"}
   \mgl@include@image{\mgl@dir#2}%
 }
 
   \setlength{\labelsep}{1em}%
   \itemsep\z@skip%
   \leftskip\z@skip\rightskip\z@skip%
-  \verbatim@font%
   \parindent\z@\parfillskip\@flushglue\parskip\z@skip%
   \let\do\@makeother \dospecials%
   \endlinechar`\^^M \catcode`\^^M\active%
   \@vobeyspaces%
+  \verbatim@font%
   \mglblock@read@line%
 }
 
+\def\mgl@dir{}
+\def\mgldir#1{%
+  \def\mgl@dir{#1}%
+}
+\@onlypreamble\mgldir
+\def\mgl@quality{2}
+\def\mglquality#1{%
+  \def\mgl@quality{#1}%
+  \if@mgltex@on@%
+    \immediate\openout\mgl@out@stream="\mgl@dir\mglcommonscript.mgl"%
+    \mgl@write\mgl@out@stream{quality #1}%
+    \immediate\closeout\mgl@out@stream%
+    \ifcase#1
+      \PackageInfo{mgltex}{Quality 0: No face drawing (fastest)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 1: No color interpolation (fast)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 2: High quality (normal)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 3: High quality with 3d primitives (not implemented yet)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 4: No face drawing, direct bitmap drawing (low memory usage)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 5: No color interpolation, direct bitmap drawing (low memory usage)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 6: High quality, direct bitmap drawing (low memory usage)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 7: High quality with 3d primitives, direct bitmap drawing (not implemented yet)}%
+    \or%
+      \PackageInfo{mgltex}{Quality 8: Draw dots instead of primitives (extremely fast)}%
+    \else%
+      \PackageWarning{mgltex}{Quality #1 not available. Using default (2)}%
+    \fi%
+  \else%
+    \PackageWarning{mgltex}{mglTeX is off, quality changes won't have effect}%
+  \fi%
+}
+
+\def\mgltexon{
+  \@mgltex@on@true
+  \def\mgl@write##1##2{%
+    \immediate\write##1{##2}%
+  }
+}
+\def\mgltexoff{%
+  \@mgltex@on@false
+  \def\mgl@write##1##2{}%
+}
+
+\def\mglcomments{
+  \@mgl@comments@true
+}
+\def\mglnocomments{%
+  \@mgl@comments@false
+}
+
 \def\mglTeX{mgl\TeX}
+
 \endinput
 %%
 %% End of file `mgltex.sty'.
index 7fcda3ba1d60c39f799c09f772e217db5760f6a5..5fe94f8e39a0eefc87619eb7b5f3e5ae55cd7e08 100644 (file)
@@ -1,22 +1,25 @@
-\documentclass[12pt]{article}
+\documentclass{article}
 
-\usepackage[png]{mgltex}
+\usepackage[png,comments]{mgltex}
 
 \title{\mglTeX{} package example}
 \author{Diego Sejas Viscarra, Alexey Balakin}
 \date{\today}
 \mgldir{scripts/}
 
+\begin{mglcommon}
+  define gravity 9.81
+\end{mglcommon}
+
 \begin{document}
   
 \maketitle
 
+\noindent The \LaTeX{} package \textsf{\mglTeX} (was made by Diego Sejas Viscarra) allows one to make figures directly from MGL scripts located in \LaTeX{} file. 
 
-LaTeX package \texttt{mgltex} (was made by Diego Sejas Viscarra) allow one to make figures directly from MGL script located in LaTeX file.
-
-For using this package you need to specify \texttt{--shell-escape} option for \emph{latex/pdflatex} or manually run \emph{mglconv} tool with produced MGL scripts for generation of images. Don't forgot to run \emph{latex/pdflatex} second time to insert generated images into the output document.
+For using this package you need to specify \texttt{--shell-escape} option for \emph{latex/pdflatex} or manually run \emph{mglconv} tool on produced MGL scripts for generation of images. Don't forget to run \emph{latex/pdflatex} a second time to insert the generated images into the output document.
 
-The package may have following options: \texttt{draft}, \texttt{final} -- the same as in the \emph{graphicx} package; \texttt{jpg}, \texttt{jpeg}, \texttt{png} -- for export to JPEG/PNG images; \texttt{eps}, \texttt{epsz} -- for export to uncompressed/compressed EPS format as primitives; \texttt{bps}, \texttt{bpsz} -- for export to uncompressed/compressed EPS format as bitmap (don't work with \emph{pdflatex}), \texttt{pdf} -- for export to 3D PDF.
+The package may have following options: \texttt{draft}, \texttt{final} --- the same as in the \emph{graphicx} package; \texttt{on}, \texttt{off} --- to activate/deactivate the creation of scripts and graphics; \texttt{comments}, \texttt{nocomments} --- to make visible/invisible commentaries contained inside \texttt{mglcomment} environments; \texttt{jpg}, \texttt{jpeg}, \texttt{png} --- to export graphics as JPEG/PNG images; \texttt{eps}, \texttt{epsz} --- to export to uncompressed/compressed EPS format as primitives; \texttt{bps}, \texttt{bpsz} --- to export to uncompressed/compressed EPS format as bitmap (doesn't work with \emph{pdflatex}); \texttt{pdf} --- to export to 3D PDF; \texttt{tex} --- to export to \LaTeX{}/\emph{tikz} document.
 
 The package defines the following environments:
 \begin{description}
@@ -36,22 +39,90 @@ The package defines the following environments:
        Exactly the same as \texttt{mglblock}, but it doesn't write to a file. This environment doesn't have arguments.
 \item[mglfunc]
        Is used to define MGL functions. It takes one mandatory argument, which is the name of the function, plus one additional argument, which specifies the number of arguments of the function. The environment needs to contain only the body of the function, since the first and last lines are appended automatically, and the resulting code is written at the end of the general script, which is also written automatically. The warning is produced if 2 or more function with the same name is defined.
-\item[mglplotsettings]
+\item[mglsignature]
+Used to defined a commentary that will be added to every script. It is useful to include signature text or license text. Observe this is a verbatim-like environment, so no \LaTeX{} command will be executed inside it, but will be copied as is.
+
+As an alternative to this method of declaring signatures, the user can manually redefine the signature macro \texttt{\textbackslash{}mgltexsignature}, according to the following rules:
+  \begin{itemize}
+    \item The positions of the comment signs for the MGL language have to be manually specified in the signature using the \texttt{\textbackslash{}mglcomm} macro.
+    \item The new-line character is declared as ``\verb|^^J|''.
+    \item A percent sign (\texttt{\%}) has to be added at the end of every physical line of \texttt{\textbackslash{}mgltexsignature}, otherwise an inelegant space at the beginning of every line will appear.
+  \item Any \LaTeX{} command can be used in this case.
+\end{itemize}
+  For example, the default signature:
+  \begin{quote}\small
+    \mglcomm\\
+    \mglcomm\ This script was generated from $<$document$>$.mgl on date $<$today$>$\\
+    \mglcomm
+  \end{quote}
+  can be achieved with
+  \begin{verbatim}
+    \def\mgltexsignature{%
+      \mglcomm^^J%
+      \mglcomm\ This script was generated from \jobname.mgl on date \today^^J%
+      \mglcomm%
+    }
+  \end{verbatim}
+\item[mglcomment]
+  Used to contain multiline commentaries. This commentaries will be visible/invisible in the output document, depending on the use of the package options \texttt{comments} and \texttt{nocomments} (see above), or the \texttt{\mglcomments} and \texttt{\mglnocomments} commands (see bellow).
+  
+  When, bisible, the comment will appear like this:
+  \begin{center}
+    \makeatletter
+    \verbatim@font
+    \makeatother
+    <------------------ MGL comment ------------------>\\
+    $<$Commentary$>$\\
+    <------------------ MGL comment ------------------>\\
+  \end{center}
+\item[mglsetup]
        If many scripts with the same code are to be written, the repetitive code can be written inside this environment only once, then this code will be used automatically every time the \texttt{\textbackslash{}mglplot} command is used (see below). It takes one optional argument, which is a name to be associated to the corresponding contents of the environment; this name can be passed to the \texttt{\textbackslash{}mglplot} command to use the corresponding block of code automatically (see below).
 \end{description}
 
 The package also defines the following commands:
 \begin{description}
 \item[\textbackslash{}mglplot]
-       It takes one mandatory argument, which is MGL instructions separated by the symbol ':' this argument can be more than one line long. It takes the same optional arguments as the \texttt{mgl} environment, plus an additional argument \emph{settings}, which indicates the name associated to a block of code inside a \texttt{mglplotsettings} environment. The code inside the mandatory argument will be appended to the block of code specified, and the resulting code will be written to the general script.
+       It takes one mandatory argument, which is MGL instructions separated by the symbol ':' this argument can be more than one line long. It takes the same optional arguments as the \texttt{mgl} environment, plus an additional argument \emph{settings}, which indicates the name associated to a block of code inside a \texttt{mglsetup} environment. The code inside the mandatory argument will be appended to the block of code specified, and the resulting code will be written to the general script.
 \item[\textbackslash{}mglgraphics]
        This command takes the same optional arguments as the \texttt{mgl} environment, and one mandatory argument, which is the name of a MGL script. This command will compile the corresponding script and include the resulting image. It is useful when you have a script outside the LaTeX document, and you want to include the image, but you don't want to type the script again.
 \item[\textbackslash{}mglinclude]
        This is like \texttt{\textbackslash{}mglgraphics} but, instead of creating/including the corresponding image, it writes the contents of the MGL script to the LaTeX document, and numerates the lines.
 \item[\textbackslash{}mgldir]
        This command can be used in the preamble of the document to specify a directory where LaTeX will save the MGL scripts and generate the corresponding images. This directory is also where \texttt{\textbackslash{}mglgraphics} and \texttt{\textbackslash{}mglinclude} will look for scripts.
+\item[\textbackslash{}mglquality]
+  Can be used to adjust the quality of the MGL graphics produced. The following table shows the available qualities:
+  \begin{center}
+    \begin{tabular}{cl}
+      \hline
+      Quality & Description\\
+      \hline
+      \hline
+      $0$ & No face drawing (fastest)\\
+      \hline
+      $1$ & No color interpolation (fast)\\
+      \hline
+      $2$ & High quality (normal)\\
+      \hline
+      $3$ & High quality with 3d primitives (not implemented yet)\\
+      \hline
+      $4$ & No face drawing, direct bitmap drawing (low memory usage)\\
+      \hline
+      $5$ & No color interpolation, direct bitmap drawing (low memory usage)\\
+      \hline
+      $6$ & High quality, direct bitmap drawing (low memory usage)\\
+      \hline
+      $7$ & High quality with 3d primitives, direct bitmap drawing (not implemented yet)\\
+      \hline
+      $8$ & Draw dots instead of primitives (extremely fast)\\
+      \hline
+    \end{tabular}
+  \end{center}
+\item[\textbackslash{}mgltexon, \textbackslash{}mgltexoff]
+  To activate/deactivate the creation of MGL scripts and images. Notice these commands have local behavior in the sense that their effect is from the point they are called on.
+\item[\textbackslash{}mglcomment, \textbackslash{}mglnocomment]
+  To make visible/invisible the contents of the \texttt{mglcomment} environments. These commands have local effect too.
 \item[\textbackslash{}mglTeX]
-       It just pretty prints the name of the package ''\mglTeX''.
+       It just pretty prints the name of the package ``\mglTeX''.
 \end{description}
 
 
@@ -271,17 +342,17 @@ Finally, you can just show MGL script itself
 
 An example of usage of \texttt{\textbackslash{}mglplot} command would be:
 \begin{verbatim}
-\begin{mglplotsettings}
+\begin{mglsetup}
   box '@{W9}' : axis
-\end{mglplotsettings}
-\begin{mglplotsettings}[2d]
+\end{mglsetup}
+\begin{mglsetup}[2d]
   box : axis
   grid 'xy' ';k'
-\end{mglplotsettings}
-\begin{mglplotsettings}[3d]
+\end{mglsetup}
+\begin{mglsetup}[3d]
   rotate 50 60
   box : axis : grid 'xyz' ';k'
-\end{mglplotsettings}
+\end{mglsetup}
 \begin{figure}[!ht]
   \centering
   \mglplot[scale=0.5]{new a 200 'sin(pi*x)':plot a '2B'}
@@ -300,31 +371,31 @@ An example of usage of \texttt{\textbackslash{}mglplot} command would be:
 \end{figure}
 \end{verbatim}
 
-\begin{mglplotsettings}
+\begin{mglsetup}
   box '@{W9}' : axis
-\end{mglplotsettings}
-\begin{mglplotsettings}[2d]
+\end{mglsetup}
+\begin{mglsetup}[2d]
   box : axis
   grid 'xy' ';k'
-\end{mglplotsettings}
-\begin{mglplotsettings}[3d]
+\end{mglsetup}
+\begin{mglsetup}[3d]
   rotate 50 60
   box : axis : grid 'xyz' ';k'
-\end{mglplotsettings}
+\end{mglsetup}
 \begin{figure}[!ht]
   \centering
   \mglplot[scale=0.5]{new a 200 'sin(pi*x)':plot a '2B'}
 \end{figure}
 \begin{figure}[!ht]
   \centering
-  \mglplot[scale=0.5,settings=2d]{
+  \mglplot[scale=0.5,setup=2d]{
     fplot 'sin(pi*x)' '2B' :
     fplot 'cos(pi*x^2)' '2R'
   }
 \end{figure}
 \begin{figure}[!ht]
   \centering
-  \mglplot[width=0.5 \textwidth, settings=3d]
+  \mglplot[width=0.5 \textwidth, setup=3d]
   {fsurf 'sin(pi*x)+cos(pi*y)'}
 \end{figure}
 
@@ -334,7 +405,61 @@ As an additional feature, when an image is not found or cannot be included, inst
   \mglgraphics{xyz}
 \end{figure}
 
-The last sample is displaying the content of the MGL file using \texttt{\textbackslash{}mglinclude} command:
+Let's display the content of the MGL file using \texttt{\textbackslash{}mglinclude} command:
 \mglinclude{Vectorial}
 
+The following commentary will be visible, since \mglTeX{} has been called with the \texttt{comments} option.
+\begin{verbatim}
+  \begin{mglcomment}
+    This is a visible commentary
+    that can have multiple lines
+  \end{mglcomment}
+\end{verbatim}
+The result is:
+\begin{mglcomment}
+  This is a visible commentary
+  that can have multiple lines
+\end{mglcomment}
+
+The following commentary won't be visible, since it is wrapped by \texttt{\textbackslash{}mglnocomments} and \texttt{\textbackslash{}mglcomments}.
+\begin{verbatim}
+  \mglnocomments
+  \begin{mglcomment}
+    This is an invisible commentary
+    that can have multiple lines
+  \end{mglcomment}
+  \mglcomments
+\end{verbatim}
+\mglnocomments
+\begin{mglcomment}
+  This is an invisible commentary
+  that can have multiple lines
+\end{mglcomment}
+\mglcomments
+
+The last example is the use of the \texttt{\textbackslash{}mgltexon} and \texttt{\textbackslash{}mgltexoff} commands. For example, the following image won't be generated:
+\begin{verbatim}
+  \mgltexoff
+  \begin{figure}[!ht]
+    \centering
+    \begin{mgl}
+      box : axis
+      fplot 'sin(pi*x)' '2B'
+    \end{mgl}
+  \end{figure}
+  \mgltexon
+\end{verbatim}
+The result is:
+\mgltexoff
+\begin{figure}[!ht]
+  \centering
+  \begin{mgl}
+    box : axis
+    fplot 'sin(pi*x)' '2B'
+  \end{mgl}
+\end{figure}
+\mgltexon
+
+
+
 \end{document}
\ No newline at end of file
index f523beda42fe46ec57d161a5377546b23a464ad8..d1185f07cca2dc5910e80eab3e8bce302cafa5d6 100644 (file)
@@ -45,22 +45,16 @@ void MGL_EXPORT mgl_strcls(char *str)
        delete []tmp;
 }
 //-----------------------------------------------------------------------------
-int MGL_EXPORT_PURE mgl_strpos(const char *str,char *fnd)
+long MGL_EXPORT_PURE mgl_strpos(const char *str,char *fnd)
 {
        const char *p=strstr(str,fnd);
-       int res;
-       if(p)   res = p-str;
-       else    res = -1;
-       return res;
+       return p?p-str:-1L;
 }
 //-----------------------------------------------------------------------------
-int MGL_EXPORT_PURE mgl_chrpos(const char *str,char ch)
+long MGL_EXPORT_PURE mgl_chrpos(const char *str,char ch)
 {
        const char *p=str?strchr(str,ch):0;
-       int res;
-       if(p)   res = p-str;
-       else    res = -1;
-       return res;
+       return p?p-str:-1L;
 }
 //-----------------------------------------------------------------------------
 MGL_EXPORT char *mgl_fgetstr(FILE *fp)
@@ -112,7 +106,7 @@ void MGL_EXPORT mgl_test(const char *str, ...)
        char buf[256];
        va_list lst;
        va_start(lst,str);
-       vsnprintf(buf,256,str,lst);
+       vsnprintf(buf,256,str,lst);     buf[255]=0;
        va_end(lst);
        printf("TEST: %s\n",buf);
        fflush(stdout);
@@ -123,7 +117,7 @@ void MGL_EXPORT mgl_info(const char *str, ...)
        char buf[256];
        va_list lst;
        va_start(lst,str);
-       vsnprintf(buf,256,str,lst);
+       vsnprintf(buf,256,str,lst);     buf[255]=0;
        va_end(lst);
        printf("%s",buf);
        FILE *fp = fopen("info.txt","at");
index f9db21a66423bd56598ff5092bdb5843ac6534d0..30bc0892fad322990f3e1d1c34972ca54c193b6d 100644 (file)
@@ -856,9 +856,9 @@ void mglCanvas::Labelw(char dir, const wchar_t *text, mreal pos, const char *opt
                        mglPnt &pp = Pnt[kk];
                        if(pp.u<0 || (pp.u==0 && pp.v<0))
                        {       pp.u=-pp.u;     pp.v=-pp.v;     pp.w=-pp.w;     }
+                       ff[0] = GetLabelPos(t, kk, *aa);        strcat(font,ff);
+                       text_plot(kk,text,font,-1.4,0.35+shift);
                }
-               ff[0] = GetLabelPos(t, kk, *aa);        strcat(font,ff);
-               text_plot(kk,text,font,-1.4,0.35+shift);
        }
        LoadState();
 }
index 06ce6a40e1e07cdac28c6a30461f07a6fa5cc478..d54571d89512b0f57dbaca2fd971eb95f5a7507f 100644 (file)
@@ -24,7 +24,7 @@
 char *mgl_strdup(const char *s)\r
 {\r
        char *r = (char *)malloc((strlen(s)+1)*sizeof(char));\r
-       memcpy(r,s,(strlen(s)+1)*sizeof(char));\r
+       if(r)   memcpy(r,s,(strlen(s)+1)*sizeof(char));\r
        return r;\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -170,7 +170,7 @@ void mglBase::StartGroup(const char *name, int id)
 {\r
        LightScale(&B);\r
        char buf[128];\r
-       snprintf(buf,128,"%s_%d",name,id);\r
+       snprintf(buf,128,"%s_%d",name,id);      buf[127]=0;\r
        StartAutoGroup(buf);\r
 }\r
 //-----------------------------------------------------------------------------\r
@@ -990,7 +990,7 @@ mreal mglBase::AddTexture(mglColor c)
 //-----------------------------------------------------------------------------\r
 mreal mglBase::NextColor(long &id)\r
 {\r
-       long i=abs(id)/256, n=Txt[i].n, p=abs(id)&0xff;\r
+       long i=labs(id)/256, n=Txt[i].n, p=labs(id)&0xff;\r
        if(id>=0)       {       p=(p+1)%n;      id = 256*i+p;   }\r
        CDef = i + (n>0 ? (p+0.5)/n : 0);       CurrPal++;\r
        sprintf(last_style+11,"{&%g}",CDef);\r
@@ -1001,7 +1001,7 @@ mreal mglBase::NextColor(long &id)
 //-----------------------------------------------------------------------------\r
 mreal mglBase::NextColor(long id, long sh)\r
 {\r
-       long i=abs(id)/256, n=Txt[i].n, p=abs(id)&0xff;\r
+       long i=labs(id)/256, n=Txt[i].n, p=labs(id)&0xff;\r
        if(id>=0)       p=(p+sh)%n;\r
        mreal cc = i + (n>0 ? (p+0.5)/n : 0);\r
        sprintf(last_style+11,"{&%g}",cc);\r
index 7f46bb9da932591c8858258e48f871980c1d2607..98702b9923e5d352ddf0b417d6979e2749139bac 100644 (file)
@@ -258,7 +258,7 @@ void MGL_EXPORT mgl_test_txt(const char *str, ...)
                char buf[256];\r
                va_list lst;\r
                va_start(lst,str);\r
-               vsnprintf(buf,256,str,lst);\r
+               vsnprintf(buf,256,str,lst);     buf[255]=0;\r
                va_end(lst);\r
                printf("TEST: %s\n",buf);\r
                fflush(stdout);\r
index fd6e388bb8d796beed4c50cc3b6c4576cc4bfa52..9d4099ff559e5a2d5afe1544c0dc8c6cecaef595 100644 (file)
@@ -121,8 +121,7 @@ void mglCanvas::ClearFrame()
                Pnt.clear();    Prm.clear();    Ptx.clear();    Glf.clear();    ClearPrmInd();\r
                Txt.clear();    Txt.reserve(3);\r
                mglTexture t1(MGL_DEF_PAL,-1), t2(MGL_DEF_SCH,1);\r
-               MGL_PUSH(Txt,t1,mutexTxt);\r
-               MGL_PUSH(Txt,t2,mutexTxt);\r
+               Txt.push_back(t1);      Txt.push_back(t2);      // No extra lock is required\r
        }\r
 #if MGL_HAVE_PTHREAD\r
        pthread_mutex_unlock(&mutexAct);\r
@@ -800,6 +799,7 @@ std::wstring MGL_EXPORT mgl_ftoa(double v, const char *fmt)
        int fdig = int(log10(v));       fdig = fdig>0?(fdig<dig?dig-fdig:0):dig;\r
        ff[2] = fdig+'0';       ee[2] = dig+'0';\r
        snprintf(se,64,ee,v);   snprintf(sf,64,ff,v);\r
+       se[63] = sf[63] = 0;\r
        long le=strlen(se), lf=strlen(sf), i;\r
 \r
        // clear fix format\r
@@ -839,7 +839,7 @@ std::wstring MGL_EXPORT mgl_ftoa(double v, const char *fmt)
        if(mglchr(fmt,'-') && !(plus||tex))             // replace '-' by "\minus"\r
                for(i=0;i<lf;i++)       res += sf[i];\r
        else\r
-               for(i=0;i<lf;i++)       res += sf[i]!='-'?sf[i]:L'−';\r
+               for(i=0;i<lf;i++)       res += sf[i]!='-'?wchar_t(sf[i]):L'−';\r
        if(tex) // TeX notation: 'e' -> "\cdot 10^{...}"\r
        {\r
                if(res[0]=='1' && (res[1]=='e' || res[1]=='E'))\r
index 4bde0eeb7c6b9578fe065d93a055f8f7dacb5bba..3457c7d82a54755676015202082808ee8de548d3 100644 (file)
@@ -97,28 +97,19 @@ MGL_NO_EXPORT void *mgl_csmth_x(void *par)
        long nx=t->p[0], kind=t->p[2];\r
        dual *b=t->a;\r
        const dual *a=t->b;\r
-       if(kind==SMOOTH_LINE_3)\r
+       if(kind>0)\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
                for(long i=t->id;i<t->n;i+=mglNumThr)\r
                {\r
                        register long j = i%nx;\r
-                       if(j>0 && j<nx-1)       b[i] = (a[i-1] + a[i] + a[i+1])/mreal(3);\r
-                       else    b[i] = a[i];\r
-               }\r
-       else if(kind==SMOOTH_LINE_5)\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-               for(long i=t->id;i<t->n;i+=mglNumThr)\r
-               {\r
-                       register long j = i%nx;\r
-                       if(j>1 && j<nx-2)       b[i] = (a[i-2] + a[i-1] + a[i] + a[i+1] + a[i+2])/mreal(5);\r
-                       else if(j==1 || j==nx-2)        b[i] = (a[i-1] + a[i] + a[i+1])/mreal(3);\r
-                       else    b[i] = a[i];\r
+                       if(j-kind<0)    j = i+kind-j;\r
+                       else if(j+kind>nx-1)    j = i+nx-1-j-kind;\r
+                       else    j=i;\r
+                       for(long k=-kind;k<=kind;k++)   b[i] += a[j+k]/mreal(2*kind+1);\r
                }\r
-       else if(kind==SMOOTH_QUAD_5)\r
+       else\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
@@ -137,28 +128,19 @@ MGL_NO_EXPORT void *mgl_csmth_y(void *par)
        long nx=t->p[0],ny=t->p[1], kind=t->p[2];\r
        dual *b=t->a;\r
        const dual *a=t->b;\r
-       if(kind==SMOOTH_LINE_3)\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-               for(long i=t->id;i<t->n;i+=mglNumThr)\r
-               {\r
-                       register long j = (i/nx)%ny;\r
-                       if(j>0 && j<ny-1)       b[i] = (a[i-nx] + a[i] + a[i+nx])/mreal(3);\r
-                       else    b[i] = a[i];\r
-               }\r
-       else if(kind==SMOOTH_LINE_5)\r
+       if(kind>0)\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
                for(long i=t->id;i<t->n;i+=mglNumThr)\r
                {\r
                        register long j = (i/nx)%ny;\r
-                       if(j>1 && j<ny-2)       b[i] = (a[i-2*nx] + a[i-nx] + a[i] + a[i+nx] + a[i+2*nx])/mreal(5);\r
-                       else if(j==1 || j==ny-2)        b[i] = (a[i-nx] + a[i] + a[i+nx])/mreal(3);\r
-                       else    b[i] = a[i];\r
+                       if(j-kind<0)    j = i+(kind-j)*nx;\r
+                       else if(j+kind>ny-1)    j = i+(ny-1-j-kind)*nx;\r
+                       else    j=i;\r
+                       for(long k=-kind;k<=kind;k++)   b[i] += a[j+k*nx]/mreal(2*kind+1);\r
                }\r
-       else if(kind==SMOOTH_QUAD_5)\r
+       else\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
@@ -177,28 +159,19 @@ MGL_NO_EXPORT void *mgl_csmth_z(void *par)
        register long nn=t->p[0]*t->p[1], nz=t->n/nn, kind=t->p[2];\r
        dual *b=t->a;\r
        const dual *a=t->b;\r
-       if(kind==SMOOTH_LINE_3)\r
+       if(kind>0)\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
                for(long i=t->id;i<t->n;i+=mglNumThr)\r
                {\r
                        register long j = i/nn;\r
-                       if(j>0 && j<nz-1)       b[i] = (a[i-nn] + a[i] + a[i+nn])/mreal(3);\r
-                       else    b[i] = a[i];\r
+                       if(j-kind<0)    j = i+(kind-j)*nn;\r
+                       else if(j+kind>nz-1)    j = i+(nz-1-j-kind)*nn;\r
+                       else    j=i;\r
+                       for(long k=-kind;k<=kind;k++)   b[i] += a[j+k*nn]/mreal(2*kind+1);\r
                }\r
-       else if(kind==SMOOTH_LINE_5)\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-               for(long i=t->id;i<t->n;i+=mglNumThr)\r
-               {\r
-                       register long j = i/nn;\r
-                       if(j>1 && j<nz-2)       b[i] = (a[i-2*nn] + a[i-nn] + a[i] + a[i+nn] + a[i+2*nn])/mreal(5);\r
-                       else if(j==1 || j==nz-2)        b[i] = (a[i-nn] + a[i] + a[i+nn])/mreal(3);\r
-                       else    b[i] = a[i];\r
-               }\r
-       else if(kind==SMOOTH_QUAD_5)\r
+       else\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
@@ -213,11 +186,27 @@ MGL_NO_EXPORT void *mgl_csmth_z(void *par)
 }\r
 void MGL_EXPORT mgl_datac_smooth(HADT d, const char *dirs, mreal )\r
 {\r
-       long Type = SMOOTH_QUAD_5;\r
+       long Type = -1;\r
        if(!dirs || *dirs==0)   dirs = "xyz";\r
-       if(strchr(dirs,'0') || strchr(dirs,'1'))        return;\r
-       if(strchr(dirs,'3'))    Type = SMOOTH_LINE_3;\r
-       if(strchr(dirs,'5'))    Type = SMOOTH_LINE_5;\r
+       if(strchr(dirs,'0'))    return;\r
+       if(strchr(dirs,'d'))\r
+       {\r
+               if(strchr(dirs,'1'))    Type = 1;\r
+               if(strchr(dirs,'2'))    Type = 2;\r
+               if(strchr(dirs,'3'))    Type = 3;\r
+               if(strchr(dirs,'4'))    Type = 4;\r
+               if(strchr(dirs,'5'))    Type = 5;\r
+               if(strchr(dirs,'6'))    Type = 6;\r
+               if(strchr(dirs,'7'))    Type = 7;\r
+               if(strchr(dirs,'8'))    Type = 8;\r
+               if(strchr(dirs,'9'))    Type = 9;\r
+       }\r
+       else\r
+       {\r
+               if(strchr(dirs,'1'))    return;\r
+               if(strchr(dirs,'3'))    Type = 1;\r
+               if(strchr(dirs,'5'))    Type = 2;\r
+       }\r
        long nx=d->nx,ny=d->ny,nz=d->nz;\r
 //     if(Type == SMOOTH_NONE) return;\r
        long p[3]={nx,ny,Type};\r
@@ -1081,6 +1070,7 @@ void MGL_EXPORT mgl_difr_axial(dual *a,int n,int step,dual q,int Border,dual *tm
 //-----------------------------------------------------------------------------\r
 MGL_NO_EXPORT void *mgl_difr(void *par)\r
 {\r
+#if !defined(_MSC_VER) // MSVC produce internal compiler error on this code\r
        mglThreadC *t=(mglThreadC *)par;\r
        long n=t->p[0], st=t->p[1], bord=t->p[3], nn=t->n;\r
        dual *b=t->a, q = *(t->b);\r
@@ -1103,6 +1093,7 @@ MGL_NO_EXPORT void *mgl_difr(void *par)
                                mgl_difr_grid(b + ((i%st)+n*(i/st)), n,st, q, bord,tmp,3);\r
                delete []tmp;\r
        }\r
+#endif\r
        return 0;\r
 }\r
 void MGL_EXPORT mgl_datac_diffr(HADT d, const char *how, mreal q)\r
index befe4c6cdc6e3bb7c759e67e3b11a43fb1b24829..fa7f3363edc740af4ff1cdcdf2c2f276eaaca2a1 100644 (file)
@@ -55,52 +55,87 @@ void mglFromStr(HADT d,char *buf,long NX,long NY,long NZ)   // TODO: add multithre
 {\r
        if(NX<1 || NY <1 || NZ<1)       return;\r
        mgl_datac_create(d, NX,NY,NZ);\r
-       long nb = strlen(buf);\r
-       register long i=0, j=0;\r
        const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
-       while(j<nb)\r
+       std::vector<char *> lines;\r
+       std::vector<std::vector<dual> > numbs;\r
+       lines.push_back(buf);\r
+       for(char *s=buf; *s; s++)       if(isn(*s))\r
+       {       lines.push_back(s+1);   *s = 0; s++;    }\r
+       numbs.resize(lines.size());\r
+       long nl = long(lines.size());\r
+//#pragma omp parallel for\r
+       for(long k=0;k<nl;k++)\r
        {\r
-               while(j<nb && buf[j]<=' ')      j++;\r
-               while(buf[j]=='#')              // skip comment\r
+               char *b = lines[k];\r
+               long nb = strlen(b);\r
+               register long i=0, j=0;\r
+\r
+               while(j<nb)\r
                {\r
-                       if(i>0 || buf[j+1]!='#')        // this is columns id\r
-                               while(j<nb && !isn(buf[j]))     j++;\r
+                       while(j<nb && b[j]<=' ')        j++;\r
+                       if(j>=nb)       break;\r
+                       while(b[j]=='#')                // skip comment\r
+                       {\r
+                               if(i>0 || b[j+1]!='#')  // this is columns id\r
+                                       while(j<nb && !isn(b[j]))       j++;\r
+                               else    // NOTE I suppose that only single line contain column ids\r
+                               {\r
+                                       while(j<nb && !isn(b[j]))\r
+                                       {\r
+                                               if(b[j]>='a' && b[j]<='z')      d->id.push_back(b[j]);\r
+                                               j++;\r
+                                       }\r
+                               }\r
+                               while(j<nb && b[j]<=' ')        j++;\r
+                       }\r
+                       char *s=b+j;\r
+                       register long sk=0;\r
+                       while(j<nb && b[j]>' ' && ((b[j]!=',' && b[j]!=' ') || sk!=0) && b[j]!=';')\r
+                       {\r
+                               if(strchr("[{(",b[j]))  sk++;\r
+                               if(strchr("]})",b[j]))  sk--;\r
+                               j++;\r
+                       }\r
+                       b[j]=0;\r
+                       double re=0,im=0;       size_t ll=strlen(s);\r
+                       while(s[ll]<=' ')       ll--;\r
+                       if(*s=='(')             sscanf(s,"(%lg,%lg)",&re,&im);\r
+                       else if(*s=='i')        {       re=0;   im=atof(s+1);   }\r
+                       else if(*s=='[')        sscanf(s,"[%lg,%lg]",&re,&im);\r
+                       else if(*s=='{')        sscanf(s,"{%lg,%lg}",&re,&im);\r
+                       else if(s[ll]=='i')\r
+                       {\r
+                               double a,b;     s[ll] = 0;\r
+                               int s1=sscanf(s,"%lg+%lg",&re,&im);\r
+                               int s2=sscanf(s,"%lg-%lg",&a,&b);\r
+                               if(s1<2)\r
+                               {\r
+                                 if(s2==2)     {       re=a;   im=-b;  }\r
+                                 else  {       im=atof(s);     re=0;   }\r
+                               }\r
+                       }\r
                        else\r
                        {\r
-                               while(j<nb && !isn(buf[j]))\r
+                               double a,b;\r
+                               int s1=sscanf(s,"%lg+i%lg",&re,&im);\r
+                               int s2=sscanf(s,"%lg-i%lg",&a,&b);\r
+                               if(s1<2)\r
                                {\r
-                                       if(buf[j]>='a' && buf[j]<='z')\r
-                                               d->id.push_back(buf[j]);\r
-                                       j++;\r
+                                 if(s2==2)     {       re=a;   im=-b;  }\r
+                                 else  {       re=atof(s);     im=0;   }\r
                                }\r
                        }\r
-                       while(j<nb && buf[j]<=' ')      j++;\r
-               }\r
-               char *s=buf+j;\r
-               while(j<nb && buf[j]>=' ' && buf[j]!=';')       j++;\r
-               buf[j]=0;\r
-               double re=0,im=0;       size_t ll=strlen(s);\r
-               while(s[ll]<=' ')       ll--;\r
-               if(*s=='(')             sscanf(s,"(%lg,%lg)",&re,&im);\r
-               else if(*s=='[')        sscanf(s,"[%lg,%lg]",&re,&im);\r
-               else if(*s=='{')        sscanf(s,"{%lg,%lg}",&re,&im);\r
-               else if(s[ll]=='i')\r
-               {\r
-                       double a,b;     s[ll] = 0;\r
-                       int s1=sscanf(s,"%lg+%lg",&re,&im);\r
-                       int s2=sscanf(s,"%lg-%lg",&a,&b);\r
-                       if(s2==2 && s1<2)       {       re=a;   im=-b;  }\r
-\r
+                       numbs[k].push_back(dual(re,im));\r
                }\r
-               else\r
-               {\r
-                       double a,b;\r
-                       int s1=sscanf(s,"%lg+i%lg",&re,&im);\r
-                       int s2=sscanf(s,"%lg-i%lg",&a,&b);\r
-                       if(s2==2 && s1<2)       {       re=a;   im=-b;  }\r
-               }\r
-               d->a[i] = dual(re,im);\r
-               i++;    if(i>=NX*NY*NZ) break;\r
+       }\r
+       register long i=0, n=NX*NY*NZ;\r
+       for(long k=0;k<nl && i<n;k++)\r
+       {\r
+               std::vector<dual> &vals = numbs[k];\r
+               long c = vals.size();\r
+               if(c>n-i)       c = n-i;\r
+               memcpy(d->a+i,&(vals[0]),c*sizeof(dual));\r
+               i += c;\r
        }\r
        setlocale(LC_NUMERIC, loc.c_str());\r
 }\r
@@ -243,7 +278,7 @@ void MGL_EXPORT mgl_datac_save_(uintptr_t *d, const char *fname,int *ns,int l)
 //-----------------------------------------------------------------------------\r
 int MGL_EXPORT mgl_datac_read(HADT d, const char *fname)\r
 {\r
-       long l=1,m=1,k=1;\r
+       long l=1,m=1,k=1,sk=0;\r
        long nb,i;\r
        gzFile fp = gzopen(fname,"r");\r
        if(!fp)\r
@@ -257,13 +292,15 @@ int MGL_EXPORT mgl_datac_read(HADT d, const char *fname)
        bool first=false;       // space is not allowed delimiter for file with complex numbers\r
        register char ch;\r
        for(i=nb-1;i>=0;i--)    if(buf[i]>' ')  break;\r
-       buf[i+1]=0;     nb = i;         // remove tailing spaces\r
+       buf[i+1]=0;     nb = i+1;               // remove tailing spaces\r
        for(i=0;i<nb-1 && !isn(buf[i]);i++)     // determine nx\r
        {\r
                while(buf[i]=='#')      {       while(!isn(buf[i]) && i<nb)     i++;    }\r
                ch = buf[i];\r
                if(ch>' ' && !first)    first=true;\r
-               if(first && (ch=='\t' || ch==';') && buf[i+1]!='\t') k++;       // ',' is not valid delimiter for complex arrays\r
+               if(strchr("[{(",ch))    sk++;\r
+               if(strchr("]})",ch))    sk--;\r
+               if(first && buf[i+1]>' ' && (ch=='\t' || ch==';' || ((ch==' '||ch==',') && sk==0) ))    k++;\r
        }\r
        first = false;\r
        for(i=0;i<nb-1;i++)                                     // determine ny\r
@@ -590,14 +627,18 @@ void MGL_EXPORT mgl_datac_modify_(uintptr_t *d, const char *eq,int *dim,int l)
 void MGL_EXPORT mgl_datac_modify_vw(HADT d, const char *eq,HCDT vdat,HCDT wdat)\r
 {\r
        std::wstring s = d->s;  d->s = L"u";\r
-       mglDataV x(d->nx,d->ny,d->nz);  x.Fill(0,1,'x');        x.s=L"x";\r
-       mglDataV y(d->nx,d->ny,d->nz);  y.Fill(0,1,'y');        y.s=L"y";\r
-       mglDataV z(d->nx,d->ny,d->nz);  z.Fill(0,1,'z');        z.s=L"z";\r
+       mglDataV x(d->nx,d->ny,d->nz, 0,1,'x'); x.s=L"x";\r
+       mglDataV y(d->nx,d->ny,d->nz, 0,1,'y'); y.s=L"y";\r
+       mglDataV z(d->nx,d->ny,d->nz, 0,1,'z'); z.s=L"z";\r
+       mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x');   i.s=L"i";\r
+       mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y');   j.s=L"j";\r
+       mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z');   k.s=L"k";\r
        mglDataV r(d->nx,d->ny,d->nz);  r.s=L"#$mgl";\r
        mglData v(vdat), w(wdat);       v.s = L"v";     w.s = L"w";\r
        std::vector<mglDataA*> list;\r
        list.push_back(&x);     list.push_back(&y);     list.push_back(&z);     list.push_back(d);\r
        list.push_back(&v);     list.push_back(&w);     list.push_back(&r);\r
+       list.push_back(&i);     list.push_back(&j);     list.push_back(&k);\r
        d->Set(mglFormulaCalcC(eq,list));       d->s = s;\r
 }\r
 void MGL_EXPORT mgl_datac_modify_vw_(uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w,int l)\r
@@ -651,7 +692,7 @@ int MGL_EXPORT mgl_datac_read_range(HADT dat, const char *templ, double from, do
        char *fname = new char[n];\r
 \r
        //read first file\r
-       do{     snprintf(fname,n,templ,t);      t+= step;       } while(!mgl_datac_read(&d,fname) && t<=to);\r
+       do{     snprintf(fname,n,templ,t);      fname[n-1]=0;   t+= step;       } while(!mgl_datac_read(&d,fname) && t<=to);\r
 \r
        if(t>to)        {       delete []fname; return false;   }\r
        kx = d.nx;      ky = d.ny;      kz = d.nz;\r
@@ -661,7 +702,7 @@ int MGL_EXPORT mgl_datac_read_range(HADT dat, const char *templ, double from, do
        // read other files\r
        for(;t<=to;t+=step)\r
        {\r
-               snprintf(fname,n,templ,t);\r
+               snprintf(fname,n,templ,t);      fname[n-1]=0;\r
                if(mgl_datac_read(&d,fname))\r
                        if(!mgl_add_file(kx,ky,kz,b,&d,as_slice))\r
                        {       delete []fname; free(b);        return false;   }\r
index e86454fc4fa722055088fed9b6175858e233424c..987c5d22787c00befcd79d4823b6837f1337c0e9 100644 (file)
@@ -568,8 +568,8 @@ void MGL_EXPORT mgl_contf_gen(HMGL gr, mreal v1, mreal v2, HCDT a, HCDT x, HCDT
                        // draw it\r
                        bool b1d2 = a->v(i+1,j,ak)>v2 && a->v(i,j-1,ak)>v2;\r
                        bool b2d1 = a->v(i,j,ak)>v2 && a->v(i+1,j-1,ak)>v2;\r
-                       mreal vv = mgl_data_linear(a,i+0.5,j-0.5,ak);\r
-                       vv = (vv-v1)*(vv-v2);\r
+//                     mreal vv = mgl_data_linear(a,i+0.5,j-0.5,ak);\r
+//                     vv = (vv-v1)*(vv-v2);\r
                        if(num<3)       continue;\r
                        if(num==4)      gr->quad_plot(p[0],p[1],p[3],p[2]);\r
                        else if(num==3) gr->trig_plot(p[0],p[1],p[2]);\r
index 14930d8d4b663efef33ee2f89367e6eaa6246de1..0ab785912b2b3e11d13a4063d02aafb7a5c79a45 100644 (file)
@@ -159,28 +159,19 @@ MGL_NO_EXPORT void *mgl_smth_x(void *par)
        long nx=t->p[0], kind=t->p[2];\r
        mreal *b=t->a, delta=t->c[0];\r
        const mreal *a=t->b;\r
-       if(kind==SMOOTH_LINE_3)\r
+       if(kind>0)\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
                for(long i=t->id;i<t->n;i+=mglNumThr)\r
                {\r
                        register long j = i%nx;\r
-                       if(j>0 && j<nx-1)       b[i] = (a[i-1] + a[i] + a[i+1])/3.;\r
-                       else    b[i] = a[i];\r
-               }\r
-       else if(kind==SMOOTH_LINE_5)\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-               for(long i=t->id;i<t->n;i+=mglNumThr)\r
-               {\r
-                       register long j = i%nx;\r
-                       if(j>1 && j<nx-2)       b[i] = (a[i-2] + a[i-1] + a[i] + a[i+1] + a[i+2])/5.;\r
-                       else if(j==1 || j==nx-2)        b[i] = (a[i-1] + a[i] + a[i+1])/3.;\r
-                       else    b[i] = a[i];\r
+                       if(j-kind<0)    j = i+kind-j;\r
+                       else if(j+kind>nx-1)    j = i+nx-1-j-kind;\r
+                       else    j=i;\r
+                       for(long k=-kind;k<=kind;k++)   b[i] += a[j+k]/(2*kind+1);\r
                }\r
-       else if(kind==SMOOTH_QUAD_5)\r
+       else\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
@@ -196,8 +187,11 @@ MGL_NO_EXPORT void *mgl_smth_x(void *par)
 #pragma omp parallel for\r
 #endif\r
                for(long i=t->id;i<t->n;i+=mglNumThr)\r
-                       b[i] = mgl_max(a[i]-delta,mgl_min(a[i]+delta,b[i]));\r
-       return 0;\r
+               {\r
+                       double ab = fabs(a[i]-b[i]);\r
+                       if(ab>delta)    b[i] = a[i]+(delta/ab)*(b[i]-a[i]);\r
+               }\r
+               return 0;\r
 }\r
 MGL_NO_EXPORT void *mgl_smth_y(void *par)\r
 {\r
@@ -205,28 +199,19 @@ MGL_NO_EXPORT void *mgl_smth_y(void *par)
        long nx=t->p[0],ny=t->p[1], kind=t->p[2];\r
        mreal *b=t->a, delta=t->c[0];\r
        const mreal *a=t->b;\r
-       if(kind==SMOOTH_LINE_3)\r
+       if(kind>0)\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
                for(long i=t->id;i<t->n;i+=mglNumThr)\r
                {\r
                        register long j = (i/nx)%ny;\r
-                       if(j>0 && j<ny-1)       b[i] = (a[i-nx] + a[i] + a[i+nx])/3.;\r
-                       else    b[i] = a[i];\r
-               }\r
-       else if(kind==SMOOTH_LINE_5)\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-               for(long i=t->id;i<t->n;i+=mglNumThr)\r
-               {\r
-                       register long j = (i/nx)%ny;\r
-                       if(j>1 && j<ny-2)       b[i] = (a[i-2*nx] + a[i-nx] + a[i] + a[i+nx] + a[i+2*nx])/5.;\r
-                       else if(j==1 || j==ny-2)        b[i] = (a[i-nx] + a[i] + a[i+nx])/3.;\r
-                       else    b[i] = a[i];\r
+                       if(j-kind<0)    j = i+(kind-j)*nx;\r
+                       else if(j+kind>ny-1)    j = i+(ny-1-j-kind)*nx;\r
+                       else    j=i;\r
+                       for(long k=-kind;k<=kind;k++)   b[i] += a[j+k*nx]/(2*kind+1);\r
                }\r
-       else if(kind==SMOOTH_QUAD_5)\r
+       else\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
@@ -242,8 +227,11 @@ MGL_NO_EXPORT void *mgl_smth_y(void *par)
 #pragma omp parallel for\r
 #endif\r
                for(long i=t->id;i<t->n;i+=mglNumThr)\r
-                       b[i] = mgl_max(a[i]-delta,mgl_min(a[i]+delta,b[i]));\r
-       return 0;\r
+               {\r
+                       double ab = fabs(a[i]-b[i]);\r
+                       if(ab>delta)    b[i] = a[i]+(delta/ab)*(b[i]-a[i]);\r
+               }\r
+               return 0;\r
 }\r
 MGL_NO_EXPORT void *mgl_smth_z(void *par)\r
 {\r
@@ -251,28 +239,19 @@ MGL_NO_EXPORT void *mgl_smth_z(void *par)
        register long nn=t->p[0]*t->p[1], nz=t->n/nn, kind=t->p[2];\r
        mreal *b=t->a, delta=t->c[0];\r
        const mreal *a=t->b;\r
-       if(kind==SMOOTH_LINE_3)\r
+       if(kind>1)\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
                for(long i=t->id;i<t->n;i+=mglNumThr)\r
                {\r
                        register long j = i/nn;\r
-                       if(j>0 && j<nz-1)       b[i] = (a[i-nn] + a[i] + a[i+nn])/3.;\r
-                       else    b[i] = a[i];\r
+                       if(j-kind<0)    j = i+(kind-j)*nn;\r
+                       else if(j+kind>nz-1)    j = i+(nz-1-j-kind)*nn;\r
+                       else    j=i;\r
+                       for(long k=-kind;k<=kind;k++)   b[i] += a[j+k*nn]/(2*kind+1);\r
                }\r
-       else if(kind==SMOOTH_LINE_5)\r
-#if !MGL_HAVE_PTHREAD\r
-#pragma omp parallel for\r
-#endif\r
-               for(long i=t->id;i<t->n;i+=mglNumThr)\r
-               {\r
-                       register long j = i/nn;\r
-                       if(j>1 && j<nz-2)       b[i] = (a[i-2*nn] + a[i-nn] + a[i] + a[i+nn] + a[i+2*nn])/5.;\r
-                       else if(j==1 || j==nz-2)        b[i] = (a[i-nn] + a[i] + a[i+nn])/3.;\r
-                       else    b[i] = a[i];\r
-               }\r
-       else if(kind==SMOOTH_QUAD_5)\r
+       else\r
 #if !MGL_HAVE_PTHREAD\r
 #pragma omp parallel for\r
 #endif\r
@@ -288,16 +267,35 @@ MGL_NO_EXPORT void *mgl_smth_z(void *par)
 #pragma omp parallel for\r
 #endif\r
                for(long i=t->id;i<t->n;i+=mglNumThr)\r
-                       b[i] = mgl_max(a[i]-delta,mgl_min(a[i]+delta,b[i]));\r
+               {\r
+                       double ab = fabs(a[i]-b[i]);\r
+                       if(ab>delta)    b[i] = a[i]+(delta/ab)*(b[i]-a[i]);\r
+               }\r
        return 0;\r
 }\r
 void MGL_EXPORT mgl_data_smooth(HMDT d, const char *dirs, mreal delta)\r
 {\r
-       long Type = SMOOTH_QUAD_5;\r
+       long Type = -1;\r
        if(!dirs || *dirs==0)   dirs = "xyz";\r
-       if(strchr(dirs,'0') || strchr(dirs,'1'))        return;\r
-       if(strchr(dirs,'3'))    Type = SMOOTH_LINE_3;\r
-       if(strchr(dirs,'5'))    Type = SMOOTH_LINE_5;\r
+       if(strchr(dirs,'0'))    return;\r
+       if(strchr(dirs,'d'))\r
+       {\r
+               if(strchr(dirs,'1'))    Type = 1;\r
+               if(strchr(dirs,'2'))    Type = 2;\r
+               if(strchr(dirs,'3'))    Type = 3;\r
+               if(strchr(dirs,'4'))    Type = 4;\r
+               if(strchr(dirs,'5'))    Type = 5;\r
+               if(strchr(dirs,'6'))    Type = 6;\r
+               if(strchr(dirs,'7'))    Type = 7;\r
+               if(strchr(dirs,'8'))    Type = 8;\r
+               if(strchr(dirs,'9'))    Type = 9;\r
+       }\r
+       else\r
+       {\r
+               if(strchr(dirs,'1'))    return;\r
+               if(strchr(dirs,'3'))    Type = 1;\r
+               if(strchr(dirs,'5'))    Type = 2;\r
+       }\r
        long nx=d->nx,ny=d->ny,nz=d->nz;\r
 //     if(Type == SMOOTH_NONE) return;\r
        long p[3]={nx,ny,Type};\r
@@ -1359,19 +1357,24 @@ MGL_EXPORT const char *mgl_data_info(HCDT d)    // NOTE: Not thread safe function!
 {\r
        static char buf[512];\r
        char s[128];    buf[0]=0;\r
-       snprintf(s,128,"nx = %ld\tny = %ld\tnz = %ld\n",d->GetNx(),d->GetNy(),d->GetNz());      strcat(buf,s);\r
+       snprintf(s,128,"nx = %ld\tny = %ld\tnz = %ld\n",d->GetNx(),d->GetNy(),d->GetNz());\r
+       s[127]=0;       strcat(buf,s);\r
 \r
        long i=0,j=0,k=0;\r
        mreal A=0,Wa=0,X=0,Y=0,Z=0,Wx=0,Wy=0,Wz=0, b;\r
        b = mgl_data_max_int(d,&i,&j,&k);\r
-       snprintf(s,128,"Maximum is %g\t at x = %ld\ty = %ld\tz = %ld\n", b,i,j,k);      strcat(buf,s);\r
+       snprintf(s,128,"Maximum is %g\t at x = %ld\ty = %ld\tz = %ld\n", b,i,j,k);\r
+       s[127]=0;       strcat(buf,s);\r
        b = mgl_data_min_int(d,&i,&j,&k);\r
-       snprintf(s,128,"Minimum is %g\t at x = %ld\ty = %ld\tz = %ld\n", b,i,j,k);      strcat(buf,s);\r
+       snprintf(s,128,"Minimum is %g\t at x = %ld\ty = %ld\tz = %ld\n", b,i,j,k);\r
+       s[127]=0;       strcat(buf,s);\r
 \r
        mgl_data_momentum_val(d,'a',&A,&Wa,0,0);        mgl_data_momentum_val(d,'x',&X,&Wx,0,0);\r
        mgl_data_momentum_val(d,'y',&Y,&Wy,0,0);        mgl_data_momentum_val(d,'z',&Z,&Wz,0,0);\r
-       snprintf(s,128,"Averages are:\n<a> = %g\t<x> = %g\t<y> = %g\t<z> = %g\n", A,X,Y,Z);     strcat(buf,s);\r
-       snprintf(s,128,"Widths are:\nWa = %g\tWx = %g\tWy = %g\tWz = %g\n", Wa,Wx,Wy,Wz);       strcat(buf,s);\r
+       snprintf(s,128,"Averages are:\n<a> = %g\t<x> = %g\t<y> = %g\t<z> = %g\n", A,X,Y,Z);\r
+       s[127]=0;       strcat(buf,s);\r
+       snprintf(s,128,"Widths are:\nWa = %g\tWx = %g\tWy = %g\tWz = %g\n", Wa,Wx,Wy,Wz);\r
+       s[127]=0;       strcat(buf,s);\r
        return buf;\r
 }\r
 int MGL_EXPORT mgl_data_info_(uintptr_t *d, char *out, int len)\r
@@ -2028,7 +2031,7 @@ void MGL_EXPORT mgl_data_refill_xy(HMDT dat, HCDT xdat, HCDT ydat, HCDT vdat, mr
                        xx1=mgl_max(xx1,0);     xx2=mgl_min(xx2,nx-1);\r
                        yy1=mgl_max(yy1,0);     yy2=mgl_min(yy2,ny-1);\r
                        if(xx1>xx2 || yy1>yy2)  continue;\r
-                       \r
+\r
                        mreal d1x = vx1-vx0, d1y = vy1-vy0;\r
                        mreal d2x = vx2-vx0, d2y = vy2-vy0;\r
                        mreal d3x = vx3+vx0-vx1-vx2, d3y = vy3+vy0-vy1-vy2;\r
index 193b55d5cea284feafc05de8cf470a78d1040bf4..4a394281d82ca623381ae61d427434cb6436d592 100644 (file)
@@ -741,7 +741,7 @@ HMDT MGL_EXPORT mgl_data_hist(HCDT dat, long n, mreal v1, mreal v2, long nsub)
        mglData *b=new mglData(n);\r
        mreal v[2]={v1,v2};\r
        long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz();\r
-       long ns=abs(nsub)+1, p[5]={n,ns,nx,ny,nz};\r
+       long ns=labs(nsub)+1, p[5]={n,ns,nx,ny,nz};\r
        if(nsub==0)     mglStartThread(mgl_hist_1,mgl_hist_p, nx*ny*nz, b->a,(const mreal *)dat,0,p,v);\r
        else    mglStartThread(mgl_hist_2,mgl_hist_p, nx*ny*nz*ns*ns*ns, b->a,(const mreal *)dat,0,p,v);\r
        return b;\r
@@ -754,7 +754,7 @@ HMDT MGL_EXPORT mgl_data_hist_w(HCDT dat, HCDT weight, long n, mreal v1, mreal v
        mreal v[2]={v1,v2};\r
 \r
        long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz();\r
-       long ns=abs(nsub)+1, p[5]={n,ns,nx,ny,nz};\r
+       long ns=labs(nsub)+1, p[5]={n,ns,nx,ny,nz};\r
        if(nsub==0)     mglStartThread(mgl_hist_1,mgl_hist_p, nx*ny*nz, b->a,(const mreal *)dat,(const mreal *)weight,p,v);\r
        else    mglStartThread(mgl_hist_2,mgl_hist_p, nx*ny*nz*ns*ns*ns, b->a,(const mreal *)dat,(const mreal *)weight,p,v);\r
        return b;\r
index faf12e77bce0ef89814f50cf227e4a27f8d2691d..1afc6302c8befcbe5c804ccf67d5ebd9a10ccc65 100644 (file)
@@ -64,11 +64,15 @@ void MGL_EXPORT mgl_data_fill_eq(HMGL gr, HMDT d, const char *eq, HCDT vdat, HCD
        mglDataV x(d->nx,d->ny,d->nz, gr->Min.x,gr->Max.x,'x'); x.s=L"x";
        mglDataV y(d->nx,d->ny,d->nz, gr->Min.y,gr->Max.y,'y'); y.s=L"y";
        mglDataV z(d->nx,d->ny,d->nz, gr->Min.z,gr->Max.z,'z'); z.s=L"z";
+       mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x');   i.s=L"i";
+       mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y');   j.s=L"j";
+       mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z');   k.s=L"k";
        mglDataV r(d->nx,d->ny,d->nz);  r.s=L"#$mgl";
        mglData v(vdat), w(wdat);       v.s = L"v";     w.s = L"w";
        std::vector<mglDataA*> list;
        list.push_back(&x);     list.push_back(&y);     list.push_back(&z);     list.push_back(&r);
        list.push_back(d);      list.push_back(&v);     list.push_back(&w);
+       list.push_back(&i);     list.push_back(&j);     list.push_back(&k);
        d->Set(mglFormulaCalc(eq,list));        d->s = s;
        gr->LoadState();
 }
@@ -86,11 +90,15 @@ void MGL_EXPORT mgl_datac_fill_eq(HMGL gr, HADT d, const char *eq, HCDT vdat, HC
        mglDataV x(d->nx,d->ny,d->nz, gr->Min.x,gr->Max.x,'x'); x.s=L"x";
        mglDataV y(d->nx,d->ny,d->nz, gr->Min.y,gr->Max.y,'y'); y.s=L"y";
        mglDataV z(d->nx,d->ny,d->nz, gr->Min.z,gr->Max.z,'z'); z.s=L"z";
+       mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x');   i.s=L"i";
+       mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y');   j.s=L"j";
+       mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z');   k.s=L"k";
        mglDataV r(d->nx,d->ny,d->nz);  r.s=L"#$mgl";
        mglData v(vdat), w(wdat);       v.s = L"v";     w.s = L"w";
        std::vector<mglDataA*> list;
        list.push_back(&x);     list.push_back(&y);     list.push_back(&z);     list.push_back(&r);
        list.push_back(d);      list.push_back(&v);     list.push_back(&w);
+       list.push_back(&i);     list.push_back(&j);     list.push_back(&k);
        d->Set(mglFormulaCalcC(eq,list));       d->s = s;
        gr->LoadState();
 }
index 9cc098f83289fb8e11b0503f9dbb49d9cca167c2..f1a44396f0957c5b662db9c62f6266cac85a2976 100644 (file)
@@ -57,36 +57,57 @@ uintptr_t MGL_EXPORT mgl_create_data_file_(const char *fname,int l)
 void MGL_EXPORT mgl_delete_data_(uintptr_t *d)\r
 {      if(_DT_)        delete _DT_;    }\r
 //-----------------------------------------------------------------------------\r
-void mglFromStr(HMDT d,char *buf,long NX,long NY,long NZ)      // TODO: add multithreading read\r
+void mglFromStr(HMDT d,char *buf,long NX,long NY,long NZ)\r
 {\r
        if(NX<1 || NY <1 || NZ<1)       return;\r
        mgl_data_create(d, NX,NY,NZ);\r
-       long nb = strlen(buf);\r
-       register long i=0, j=0;\r
        const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");\r
-       while(j<nb)\r
+       std::vector<char *> lines;\r
+       std::vector<std::vector<mreal> > numbs;\r
+       lines.push_back(buf);\r
+       for(char *s=buf; *s; s++)       if(isn(*s))\r
+       {       lines.push_back(s+1);   *s = 0; s++;    }\r
+       numbs.resize(lines.size());\r
+       long nl = long(lines.size());\r
+#pragma omp parallel for\r
+       for(long k=0;k<nl;k++)\r
        {\r
-               while(j<nb && buf[j]<=' ')      j++;\r
-               while(buf[j]=='#')              // skip comment\r
+               char *b = lines[k];\r
+               long nb = strlen(b);\r
+               register long i=0, j=0;\r
+               while(j<nb)\r
                {\r
-                       if(i>0 || buf[j+1]!='#')        // this is columns id\r
-                               while(j<nb && !isn(buf[j]))     j++;\r
-                       else\r
+                       while(j<nb && b[j]<=' ')        j++;\r
+                       if(j>=nb)       break;\r
+                       while(b[j]=='#')                // skip comment\r
                        {\r
-                               while(j<nb && !isn(buf[j]))\r
+                               if(i>0 || b[j+1]!='#')  // this is columns id\r
+                                       while(j<nb && !isn(b[j]))       j++;\r
+                               else    // NOTE I suppose that only single line contain column ids\r
                                {\r
-                                       if(buf[j]>='a' && buf[j]<='z')\r
-                                               d->id.push_back(buf[j]);\r
-                                       j++;\r
+                                       while(j<nb && !isn(b[j]))\r
+                                       {\r
+                                               if(b[j]>='a' && b[j]<='z')\r
+                                                       d->id.push_back(b[j]);\r
+                                               j++;\r
+                                       }\r
                                }\r
+                               while(j<nb && b[j]<=' ')        j++;\r
                        }\r
-                       while(j<nb && buf[j]<=' ')      j++;\r
+                       char *s=b+j;\r
+                       while(j<nb && b[j]>' ' && b[j]!=',' && b[j]!=';')       j++;\r
+                       b[j]=0;\r
+                       numbs[k].push_back(strstr(s,"NAN")?NAN:atof(s));\r
                }\r
-               char *s=buf+j;\r
-               while(j<nb && buf[j]>' ' && buf[j]!=',' && buf[j]!=';') j++;\r
-               buf[j]=0;\r
-               d->a[i] = strstr(s,"NAN")?NAN:atof(s);\r
-               i++;    if(i>=NX*NY*NZ) break;\r
+       }\r
+       register long i=0, n=NX*NY*NZ;\r
+       for(long k=0;k<nl && i<n;k++)\r
+       {\r
+               std::vector<mreal> &vals = numbs[k];\r
+               long c = vals.size();\r
+               if(c>n-i)       c = n-i;\r
+               memcpy(d->a+i,&(vals[0]),c*sizeof(mreal));\r
+               i += c;\r
        }\r
        setlocale(LC_NUMERIC, loc.c_str());\r
 }\r
@@ -329,7 +350,7 @@ int MGL_EXPORT mgl_data_read(HMDT d, const char *fname)
        bool first=false;\r
        register char ch;\r
        for(i=nb-1;i>=0;i--)    if(buf[i]>' ')  break;\r
-       buf[i+1]=0;     nb = i;         // remove tailing spaces\r
+       buf[i+1]=0;     nb = i+1;               // remove tailing spaces\r
        for(i=0;i<nb-1 && !isn(buf[i]);i++)     // determine nx\r
        {\r
                while(buf[i]=='#')      {       while(!isn(buf[i]) && i<nb)     i++;    }\r
@@ -873,11 +894,15 @@ void MGL_EXPORT mgl_data_modify_vw(HMDT d, const char *eq,HCDT vdat,HCDT wdat)
        mglDataV x(d->nx,d->ny,d->nz, 0,1,'x'); x.s=L"x";\r
        mglDataV y(d->nx,d->ny,d->nz, 0,1,'y'); y.s=L"y";\r
        mglDataV z(d->nx,d->ny,d->nz, 0,1,'z'); z.s=L"z";\r
+       mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x');   i.s=L"i";\r
+       mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y');   j.s=L"j";\r
+       mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z');   k.s=L"k";\r
        mglDataV r(d->nx,d->ny,d->nz);  r.s=L"#$mgl";\r
        mglData v(vdat), w(wdat);       v.s = L"v";     w.s = L"w";\r
        std::vector<mglDataA*> list;\r
        list.push_back(&x);     list.push_back(&y);     list.push_back(&z);     list.push_back(d);\r
        list.push_back(&v);     list.push_back(&w);     list.push_back(&r);\r
+       list.push_back(&i);     list.push_back(&j);     list.push_back(&k);\r
        d->Set(mglFormulaCalc(eq,list));        d->s = s;\r
 }\r
 void MGL_EXPORT mgl_data_modify_vw_(uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w,int l)\r
@@ -1075,7 +1100,7 @@ int MGL_EXPORT mgl_data_read_range(HMDT dat, const char *templ, double from, dou
        char *fname = new char[n];\r
 \r
        //read first file\r
-       do{     snprintf(fname,n,templ,t);      t+= step;       } while(!mgl_data_read(&d,fname) && t<=to);\r
+       do{     snprintf(fname,n,templ,t);      fname[n-1]=0;   t+= step;       } while(!mgl_data_read(&d,fname) && t<=to);\r
 \r
        if(t>to)        {       delete []fname; return false;   }\r
        kx = d.nx;      ky = d.ny;      kz = d.nz;\r
@@ -1085,7 +1110,7 @@ int MGL_EXPORT mgl_data_read_range(HMDT dat, const char *templ, double from, dou
        // read other files\r
        for(;t<=to;t+=step)\r
        {\r
-               snprintf(fname,n,templ,t);\r
+               snprintf(fname,n,templ,t);      fname[n-1]=0;\r
                if(mgl_data_read(&d,fname))\r
                        if(!mgl_add_file(kx,ky,kz,b,&d,as_slice))\r
                        {       delete []fname; free(b);        return false;   }\r
index 0af84ae1f1162a6845477a713512cd8df6732166..2773487d787e074156327a4fb08e6430459b49ad 100644 (file)
@@ -27,8 +27,8 @@
 //-----------------------------------------------------------------------------\r
 size_t MGL_LOCAL_PURE mgl_col_dif(unsigned char *c1,unsigned char *c2,bool sum)\r
 {\r
-       size_t res,d1=abs(long(c1[0])-long(c2[0])),\r
-               d2=abs(long(c1[1])-long(c2[1])),d3=abs(long(c1[2])-long(c2[2]));\r
+       size_t res,d1=labs(long(c1[0])-long(c2[0])),\r
+               d2=labs(long(c1[1])-long(c2[1])),d3=labs(long(c1[2])-long(c2[2]));\r
        if(sum) res = d1+d2+d3;\r
        else    res = mgl_max(d1,mgl_max(d2,d3));\r
        return res;\r
@@ -232,6 +232,7 @@ void MGL_EXPORT mgl_data_export(HCDT dd, const char *fname, const char *scheme,m
        if(!strcmp(fname+len-4,".bmp"))         mgl_bmp_save(fname, nx,ny,p);\r
        if(!strcmp(fname+len-4,".png"))         mgl_png_save(fname, nx,ny,p);\r
        if(!strcmp(fname+len-4,".eps") || !strcmp(fname+len-4,".bps"))  mgl_bps_save(fname, nx,ny,p);\r
+       delete []p;     delete []d;\r
 }\r
 //-----------------------------------------------------------------------------\r
 void MGL_EXPORT mgl_data_export_(uintptr_t *d, const char *fname, const char *scheme,mreal *v1,mreal *v2,int *ns,int l,int n)\r
index 5b4489f21354b48b86c7f94cfb5af90834a05f27..0455716799f41b95ecda8103d727d048e5452f65 100644 (file)
@@ -19,6 +19,7 @@
  ***************************************************************************/
 #include <time.h>
 #include <ctype.h>
+#include "mgl2/base.h"
 #include "mgl2/parser.h"
 #if MGL_HAVE_GSL
 #include <gsl/gsl_sf.h>
@@ -324,7 +325,7 @@ mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const std
                else if(!str.compare(L":"))             res.a[0] = -1;
                else
                {
-                       HCDT v=FindVar(head, L"#$mgl");
+                       v=FindVar(head, L"#$mgl");
                        if(v)   res.Create(v->GetNx(),v->GetNy(),v->GetNz());
                        if(!str.compare(L"rnd"))        for(long i=0;i<res.GetNN();i++) res.a[i] = mgl_rnd();
                        else if(!str.compare(L"nan"))   res = NAN;
@@ -332,6 +333,22 @@ mglData MGL_NO_EXPORT mglFormulaCalc(std::wstring str, mglParser *arg, const std
                        else if(!str.compare(L"pi"))    res = M_PI;
                        else if(!str.compare(L"on"))    res = 1;
                        else if(!str.compare(L"off"))   res = 0;
+/*                     else if(!str.compare(L"t"))     res.Fill(0,1,'x');
+                       else if(!str.compare(L"x") && arg && arg->curGr)
+                       {
+                               if(res.GetNN()==1)      res.Create(100);
+                               res.Fill(arg->curGr->Min.x, arg->curGr->Max.x,'x');
+                       }
+                       else if(!str.compare(L"y") && arg && arg->curGr)
+                       {
+                               if(res.GetNN()==1)      res.Create(100);
+                               res.Fill(arg->curGr->Min.x, arg->curGr->Max.x,res.ny>1?'y':'x');
+                       }
+                       else if(!str.compare(L"z") && arg && arg->curGr)
+                       {
+                               if(res.GetNN()==1)      res.Create(100);
+                               res.Fill(arg->curGr->Min.x, arg->curGr->Max.x,res.nz>1?'z':'x');
+                       }*/
                        else res = wcstod(str.c_str(),0);       // this is number
                }
                return res;
@@ -811,7 +828,7 @@ mglDataC MGL_NO_EXPORT mglFormulaCalcC(std::wstring str, mglParser *arg, const s
                else if(!str.compare(L":"))             res.a[0] = -1;
                else
                {
-                       HCDT v=FindVar(head, L"#$mgl");
+                       v=FindVar(head, L"#$mgl");
                        if(v)   res.Create(v->GetNx(),v->GetNy(),v->GetNz());
                        if(!str.compare(L"rnd"))        for(long i=0;i<res.GetNN();i++) res.a[i] = mgl_rnd();
                        else if(!str.compare(L"nan"))   res = mreal(NAN);
@@ -819,6 +836,13 @@ mglDataC MGL_NO_EXPORT mglFormulaCalcC(std::wstring str, mglParser *arg, const s
                        else if(!str.compare(L"pi"))    res = mreal(M_PI);
                        else if(!str.compare(L"on"))    res = mreal(1.);
                        else if(!str.compare(L"off"))   res = mreal(0.);
+/*                     else if(!str.compare(L"t"))     res.Fill(0,1,'x');
+                       else if(!str.compare(L"x") && arg && arg->curGr)
+                               res.Fill(arg->curGr->Min.x, arg->curGr->Max.x,'x');
+                       else if(!str.compare(L"y") && arg && arg->curGr)
+                               res.Fill(arg->curGr->Min.x, arg->curGr->Max.x,res.ny>1?'y':'x');
+                       else if(!str.compare(L"z") && arg && arg->curGr)
+                               res.Fill(arg->curGr->Min.x, arg->curGr->Max.x,res.nz>1?'z':'x');*/
                        else if(str[0]=='i')    // this is imaginary number
                                res = dual(0,(str.length()>1 && str[1]>' ')?wcstod(str.c_str(),0):1);
                        else res = mreal(wcstod(str.c_str(),0));        // this is real number
index ed776dcace82cda962b515a0b037ae0683acc77c..e91e1ac4050bbd8b2c576a48cb2fda8ea9f074c8 100644 (file)
@@ -1149,11 +1149,25 @@ int MGL_NO_EXPORT mgls_read(mglGraph *gr, long , mglArg *a, const char *k, const
        int res=0;
        bool rr=true;
        mglData *d = dynamic_cast<mglData *>(a[0].d);
+       mglData *f = dynamic_cast<mglData *>(a[1].d);
        if(!d)  return 1;
-       if(!strcmp(k,"ds"))     rr=d->Read(a[1].s.c_str());
-       else if(!strcmp(k,"dsn"))       rr=d->Read(a[1].s.c_str(), iint(a[2].v));
-       else if(!strcmp(k,"dsnn"))      rr=d->Read(a[1].s.c_str(), iint(a[2].v),iint(a[3].v));
-       else if(!strcmp(k,"dsnnn"))     rr=d->Read(a[1].s.c_str(), iint(a[2].v),iint(a[3].v),iint(a[4].v));
+       mglDataC c;
+       if(!strcmp(k,"ds"))
+       {       rr=c.Read(a[1].s.c_str());      *d = c.Real();  }
+       else if(!strcmp(k,"dsn"))
+       {       rr=c.Read(a[1].s.c_str(), iint(a[2].v));        *d = c.Real();  }
+       else if(!strcmp(k,"dsnn"))
+       {       rr=c.Read(a[1].s.c_str(), iint(a[2].v),iint(a[3].v));   *d = c.Real();  }
+       else if(!strcmp(k,"dsnnn"))
+       {       rr=c.Read(a[1].s.c_str(), iint(a[2].v),iint(a[3].v),iint(a[4].v));      *d = c.Real();  }
+       if(!strcmp(k,"dds") && f)
+       {       rr=c.Read(a[2].s.c_str());      *d = c.Real();  *f = c.Imag();  }
+       if(!strcmp(k,"ddsn") && f)
+       {       rr=c.Read(a[2].s.c_str(), iint(a[3].v));        *d = c.Real();  *f = c.Imag();  }
+       if(!strcmp(k,"ddsnn") && f)
+       {       rr=c.Read(a[2].s.c_str(), iint(a[3].v),iint(a[4].v));   *d = c.Real();  *f = c.Imag();  }
+       if(!strcmp(k,"ddsnnn") && f)
+       {       rr=c.Read(a[2].s.c_str(), iint(a[3].v),iint(a[4].v),iint(a[5].v));      *d = c.Real();  *f = c.Imag();  }
        if(!rr) gr->SetWarn(mglWarnFile,"Read");
        return res;
 }
@@ -2073,7 +2087,7 @@ int MGL_NO_EXPORT mgls_info(mglGraph *gr, long , mglArg *a, const char *k, const
        if(!strcmp(k,"d"))      gr->SetWarn(-1,a[0].d->PrintInfo());
        else if(!strcmp(k,"s")) gr->SetWarn(-1,a[0].s.c_str());
        else if(!strcmp(k,"n"))
-       {       char buf[128];  snprintf(buf,128,"value = %g",a[0].v);  gr->SetWarn(-1,buf);    }
+       {       char buf[128];  snprintf(buf,128,"value = %g",a[0].v);  buf[127]=0;     gr->SetWarn(-1,buf);    }
        else res = 1;   return res;
 }
 //-----------------------------------------------------------------------------
@@ -2455,7 +2469,7 @@ int MGL_NO_EXPORT mgls_fgets(mglGraph *gr, long , mglArg *a, const char *k, cons
                memset(buf,0,1024);
                if(!fgets(buf,1024,fp))
                {
-                       char b[32];     snprintf(b,32,"%d",n);
+                       char b[32];     snprintf(b,32,"%d",n);  b[31]=0;
                        gr->SetWarn(mglWarnOpen,(a[2].s+" - line "+b).c_str());
                        fclose(fp);     return res;
                }
@@ -2475,7 +2489,7 @@ int MGL_NO_EXPORT mgls_fgets(mglGraph *gr, long , mglArg *a, const char *k, cons
                memset(buf,0,1024);
                if(!fgets(buf,1024,fp))
                {
-                       char b[32];     snprintf(b,32,"%d",n);
+                       char b[32];     snprintf(b,32,"%d",n);  b[31]=0;
                        gr->SetWarn(mglWarnOpen,(a[3].s+" - line "+b).c_str());
                        fclose(fp);     return res;
                }
@@ -3075,7 +3089,7 @@ mglCommand mgls_base_cmd[] = {
        {"ranges","Set axis ranges","ranges x1 x2 y1 y2 [z1 z2]", mgls_ranges ,14},
        {"rasterize","Rasterize and save to background","rasterize", mgls_rasterize ,12},
        {"ray","Solve Hamiltonian ODE (find GO ray or trajectory)","ray Res 'ham' x0 y0 z0 px0 py0 pz0 [dz=0.1 tmax=10]", mgls_ray ,4},
-       {"read","Read data from file","read Dat 'file' [nx ny nz]", mgls_read ,4},
+       {"read","Read data from file","read Dat 'file' [nx ny nz] | ReDat ImDat 'file' [nx ny nz]", mgls_read ,4},
        {"readall","Read and join data from several files","readall Dat 'templ' [slice]", mgls_readall ,4},
        {"readhdf","Read data from HDF5 file","readhdf Dat 'file' 'id'", mgls_readhdf ,4},
        {"readmat","Read data from file with sizes specified in first row","readmat Dat 'file' [dim]", mgls_readmat ,4},
index 65529b42573a2e55dd644f4fd52533fcc10da065..eac9c49e4f83cedbfc3b35d9ddd20a46a1afdd71 100644 (file)
@@ -203,7 +203,7 @@ void MGL_NO_EXPORT mgl_printf(void *fp, bool gz, const char *str, ...)      // NOTE T
        static char buf[1024];
        va_list lst;
        va_start(lst,str);
-       vsnprintf(buf,1023,str,lst);
+       vsnprintf(buf,1023,str,lst);    buf[1023]=0;
        va_end(lst);
        if(gz)  gzprintf((gzFile)fp, "%s", buf);
        else    fprintf((FILE *)fp, "%s", buf);
@@ -214,7 +214,7 @@ std::string MGL_NO_EXPORT mgl_sprintf(const char *str, ...)
        char *buf=new char[1024];
        va_list lst;
        va_start(lst,str);
-       vsnprintf(buf,1023,str,lst);
+       vsnprintf(buf,1023,str,lst);    buf[1023]=0;
        va_end(lst);
        std::string res = buf;  delete []buf;
        return res;
@@ -223,7 +223,6 @@ std::string MGL_NO_EXPORT mgl_sprintf(const char *str, ...)
 int MGL_NO_EXPORT mgl_bps_save(const char *fname, int w, int h, unsigned char **p)
 {
        time_t now;     time(&now);
-       register long i,j;
        bool gz = fname[strlen(fname)-1]=='z';
 
        void *fp;
@@ -242,7 +241,7 @@ int MGL_NO_EXPORT mgl_bps_save(const char *fname, int w, int h, unsigned char **
                        if(pos) {       buf[pos]=buf[pos+1]='b';        buf[pos+2]=0;   }
                        FILE *fb = fopen(buf,"w");
                        fprintf(fb, "%%%%BoundingBox: 0 0 %d %d\n", w, h);
-                       fclose(fb);
+                       fclose(fb);     delete []buf;
                }
        }
        mgl_printf(fp, gz, "%%!PS-Adobe-3.0 EPSF-3.0\n%%%%BoundingBox: 0 0 %d %d\n",w,h);
@@ -577,7 +576,7 @@ void MGL_EXPORT mgl_write_frame(HMGL gr, const char *fname,const char *descr)
 {
        char buf[64];
        if(!fname || !fname[0])
-       {       snprintf(buf,64,"%s%04d.jpg",_Gr_->PlotId.c_str(),_Gr_->GetNumFrame()); fname = buf;    }
+       {       snprintf(buf,64,"%s%04d.jpg",_Gr_->PlotId.c_str(),_Gr_->GetNumFrame()); buf[63]=0;      fname = buf;    }
        int len=strlen(fname);
        if(!strcmp(fname+len-4,".jpg"))         mgl_write_jpg(gr,fname,descr);
        if(!strcmp(fname+len-5,".jpeg"))        mgl_write_jpg(gr,fname,descr);
@@ -618,14 +617,14 @@ void MGL_EXPORT mgl_write_frame_(uintptr_t *gr, const char *fname,const char *de
 void MGL_EXPORT mgl_show_image(HMGL gr, const char *viewer, int keep)
 {
        char fname[128], *cmd = new char [128];
-       snprintf(fname,128,"%s.png", tmpnam(NULL));
+       snprintf(fname,128,"%s.png", tmpnam(NULL));     fname[127]=0;
        mgl_write_png_solid(gr,fname,"MathGL ShowImage file");
        if(!viewer || !viewer[0])
                viewer = MGL_DEF_VIEWER;
 #ifdef WIN32
                if(keep)
                {
-                       snprintf(cmd,128,"%s %s &", viewer,fname);
+                       snprintf(cmd,128,"%s %s &", viewer,fname);      cmd[127]=0;
                        if(system(cmd)==-1)     printf("Error to call external viewer\n");
                        Sleep(2000);
                        snprintf(cmd,128,"del %s", fname);
@@ -634,13 +633,14 @@ void MGL_EXPORT mgl_show_image(HMGL gr, const char *viewer, int keep)
 #else
                if(keep)
                {
-                       snprintf(cmd,128,"%s %s &", viewer,fname);
+                       snprintf(cmd,128,"%s %s &", viewer,fname);      cmd[127]=0;
                        if(system(cmd)==-1)     printf("Error to call external viewer\n");
                        sleep(2);
                        snprintf(cmd,128,"rm %s", fname);
                }
                else    snprintf(cmd,128,"%s %s; rm %s", viewer,fname,fname);
 #endif
+               cmd[127] = 0;
                if(system(cmd)==-1)     printf("Error to call external viewer\n");
                delete []cmd;
 }
index 172d8a860448a4f20e7b5dc800be2ed818e774f0..01a9b94ca54478cd75fd2bb25c261a91ed153dbe 100644 (file)
@@ -43,11 +43,11 @@ MGL_NO_EXPORT const char *mgl_get_dash(unsigned short d, mreal w,char dlm)
                if(((d>>j)&1) == p)     f++;
                else
                {
-                       snprintf(b,32," %g%c",f*w,dlm); s += b;
+                       snprintf(b,32," %g%c",f*w,dlm); b[31]=0;        s += b;
                        p = (d>>j)&1;   f = 1;  n++;
                }
        }
-       snprintf(b,32,"%g",f*w);        s += b;
+       snprintf(b,32,"%g",f*w);        b[31]=0;        s += b;
        s += (n%2) ? "" : " 0";
        return s.c_str();
 }
@@ -193,7 +193,7 @@ void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr)
                if(pos) {       buf[pos]=buf[pos+1]='b';        buf[pos+2]=0;   }
                FILE *fb = fopen(buf,"w");
                fprintf(fb, "%%%%BoundingBox: 0 0 %d %d\n", w, h);
-               fclose(fb);
+               fclose(fb);     delete []buf;
        }
        
        const std::string loc = setlocale(LC_NUMERIC, NULL);    setlocale(LC_NUMERIC, "C");
@@ -288,13 +288,14 @@ void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr)
                if(q.type<0)    continue;       // q.n1>=0 always
                cp.c = _Gr_->GetPrmCol(i);
                const mglPnt p1 = gr->GetPnt(q.n1);
-               if(q.type>1)    snprintf(str,256,"%.2g %.2g %.2g rgb ", cp.r[0]/255.,cp.r[1]/255.,cp.r[2]/255.);
+               if(q.type>1)
+               {       snprintf(str,256,"%.2g %.2g %.2g rgb ", cp.r[0]/255.,cp.r[1]/255.,cp.r[2]/255.);        str[255]=0;     }
 
                if(q.type==0)   // mark
                {
                        mreal x0 = p1.x,y0 = p1.y;
                        snprintf(str,256,"%.2g lw %.2g %.2g %.2g rgb ", 50*q.s*q.w>1?50*q.s*q.w:1, cp.r[0]/255.,cp.r[1]/255.,cp.r[2]/255.);
-                       wp=1;   // NOTE: this may renew line style if a mark inside!
+                       str[255]=0;     wp=1;   // NOTE: this may renew line style if a mark inside!
                        if(q.s!=qs_old)
                        {
                                mgl_printf(fp, gz, "/ss {%g} def\n",q.s);
@@ -341,7 +342,7 @@ void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr)
                else if(q.type==1)      // line
                {
                        snprintf(str,256,"%.2g lw %.2g %.2g %.2g rgb ", q.w>1 ? q.w:1., cp.r[0]/255.,cp.r[1]/255.,cp.r[2]/255.);
-                       wp = q.w>1  ? q.w:1;    st = q.n3;
+                       str[255]=0;     wp = q.w>1  ? q.w:1;    st = q.n3;
                        put_line(gr,fp,gz,i,wp,cp.c,st, "np %g %g mt ", "%g %g ll ", false, 1);
                        const char *sd = mgl_get_dash(q.n3,q.w,' ');
                        if(sd && sd[0]) mgl_printf(fp, gz, "%s [%s] %g sd dr\n",str,sd,q.w*q.s);
@@ -610,7 +611,7 @@ void MGL_EXPORT mgl_write_tex(HMGL gr, const char *fname,const char *descr)
                const mglPrim &q = gr->GetPrm(i);
                if(q.type<0)    continue;       // q.n1>=0 always
                cp.c = _Gr_->GetPrmCol(i);
-               snprintf(cname,128,"color={rgb,255:red,%d;green,%d;blue,%d}",cp.r[0],cp.r[1],cp.r[2]);
+               snprintf(cname,128,"color={rgb,255:red,%d;green,%d;blue,%d}",cp.r[0],cp.r[1],cp.r[2]);  cname[127]=0;
 
                const mglPnt p1=gr->GetPnt(q.n1);
                mreal x=p1.x/100,y=p1.y/100,s=q.s/100;
index eee798e7753eac5da9b5ae779693d511093ac9b5..5c9232aa50e6e3ccd4bcefc82fbe3cda3caed2ff 100644 (file)
@@ -92,9 +92,9 @@ void MGL_EXPORT mgl_obj_glyph_old(HMGL gr, const mglPrim &q, const mglPnt &p, FI
                }\r
                else    // glyph_wire(p,f,g, d);\r
                {\r
+                       long il=0;\r
                        for(long ik=0;ik<g.nl;ik++)\r
                        {\r
-                               long il=0;\r
                                x = g.line[2*ik];       y = g.line[2*ik+1];\r
                                if(x==0x3fff && y==0x3fff)      // line breakthrough\r
                                {       il = ik+1;      continue;       }\r
index c5a8c97440e3e1f77e7badb02916fdda899c698f..a0a4bb811764266d20cee722a4653868c07c9565 100644 (file)
@@ -168,7 +168,7 @@ MGL_NO_EXPORT void* mgl_ffty(void *par)
 #pragma omp parallel
 #endif
        {
-               void *w = mgl_fft_alloc_thr(nx);
+               void *w = mgl_fft_alloc_thr(ny);
 #pragma omp for nowait
                for(long i=t->id;i<t->n;i+=mglNumThr)
                        mgl_fft(t->b+2*(i%nx)+2*nx*ny*(i/nx), nx, ny, t->v, w, t->p[3]);
@@ -184,7 +184,7 @@ MGL_NO_EXPORT void* mgl_fftz(void *par)
 #pragma omp parallel
 #endif
        {
-               void *w = mgl_fft_alloc_thr(nx);
+               void *w = mgl_fft_alloc_thr(nz);
 #pragma omp for nowait
                for(long i=t->id;i<t->n;i+=mglNumThr)
                        mgl_fft(t->b+2*i, nx*ny, nz, t->v, w, t->p[3]);
@@ -1071,26 +1071,28 @@ void MGL_EXPORT mgl_data_hankel_(uintptr_t *d, const char *dir,int l)
 void MGL_EXPORT mgl_data_fill_sample(HMDT d, const char *how)
 {
        if(!how || *how==0)     return;
-       bool xx = strchr(how,'x');
-       long n=d->nx;
+       bool kk = strchr(how,'k');
+       long n=d->nx,dn=1;
        mreal *aa=d->a;
+       if(strchr(how,'y'))     {       n=d->ny;        dn=d->nx;       }
+       if(strchr(how,'z'))     {       n=d->nz;        dn=d->nx*d->ny; }
        if(strchr(how,'h'))     // Hankel
        {
 #if MGL_HAVE_GSL
                gsl_dht *dht = gsl_dht_new(n,0,1);
 #pragma omp parallel for
                for(long i=0;i<n;i++)
-                       aa[i] = xx ? gsl_dht_x_sample(dht, i) : gsl_dht_k_sample(dht, i);
+                       aa[i*dn] = kk ? gsl_dht_k_sample(dht, i) : gsl_dht_x_sample(dht, i);
                gsl_dht_free(dht);
 #endif
        }
        else    // Fourier
        {
-               if(xx)  for(long i=0;i<n;i++)   aa[i] = mreal(2*i-n)/n;
-               else    for(long i=0;i<n;i++)   aa[i] = M_PI*(i<n/2 ? i:i-n);
+               if(kk)  for(long i=0;i<n;i++)   aa[i*dn] = M_PI*(i<n/2 ? i:i-n);
+               else    for(long i=0;i<n;i++)   aa[i*dn] = mreal(2*i-n)/n;
        }
 #pragma omp parallel for
-       for(long i=1;i<d->ny*d->nz;i++) memcpy(aa+i*n,aa,n*sizeof(mreal));
+       for(long i=0;i<d->GetNN();i++)  aa[i] = aa[((i%(n*dn))/dn)*dn];
 }
 void MGL_EXPORT mgl_data_fill_sample_(uintptr_t *d, const char *how,int l)
 {      char *s=new char[l+1];  memcpy(s,how,l);        s[l]=0;
@@ -1257,7 +1259,7 @@ MGL_NO_EXPORT double *mgl_d_correl(HCDT d1, HCDT d2, const char *dir)
                {       mgl_fft_data.wtz = wt;  clear = false;  mgl_fft_data.wnz=nz;    }
        }
        if(clear)       mgl_fft_free(wt,0,0);
-       return a;
+       delete []b;     return a;
 }
 //-----------------------------------------------------------------------------
 HADT MGL_EXPORT mgl_datac_correl(HCDT d1, HCDT d2, const char *dir)
index d49f68613a72e764ac4e42b5bf4386c8de846ae5..4a789642b31a58452c34e2bcf21b860a3c0d78a7 100644 (file)
@@ -42,8 +42,8 @@ void MGL_EXPORT mgl_puts_fit(HMGL gr, double x, double y, double z, const char *
        long n = strlen(mglFitRes)+(pre?strlen(pre):0)+1;\r
        char *buf = new char[n];\r
        if(pre) snprintf(buf,n,"%s%s",pre,mglFitRes);\r
-       else    strcpy(buf,mglFitRes);\r
-       mgl_puts(gr,x,y,z,buf,font,size);\r
+       else    strncpy(buf,mglFitRes,n);\r
+       buf[n-1]=0;     mgl_puts(gr,x,y,z,buf,font,size);\r
        delete []buf;\r
 }\r
 void MGL_EXPORT mgl_puts_fit_(uintptr_t* gr, mreal *x, mreal *y, mreal *z, const char *prefix, const char *font, mreal *size, int l, int n)\r
@@ -204,12 +204,12 @@ void mglPrepareFitEq(mglBase *gr,mreal chi, const char *eq, const char *var, mre
 {\r
        char buf[32]="";\r
        mglFitChi = chi;\r
-       snprintf(mglFitRes,1024,"chi=%g",chi);\r
+       snprintf(mglFitRes,1024,"chi=%g",chi);  mglFitRes[1023]=0;\r
        size_t i,k,len=strlen(var);\r
        for(i=0;i<len;i++)\r
        {\r
                snprintf(buf,32,", %c=%g",var[i],par[i]);\r
-               strcat(mglFitRes,buf);\r
+               buf[31]=0;      strcat(mglFitRes,buf);\r
        }\r
        gr->SetWarn(-1,mglFitRes);\r
 \r
@@ -221,7 +221,7 @@ void mglPrepareFitEq(mglBase *gr,mreal chi, const char *eq, const char *var, mre
                if(c && (i==0 || !isalnum(eq[i-1])) && (i==len-1 || !isalnum(eq[i+1])))\r
                {\r
                        snprintf(buf,32,"%g",par[c-var]);\r
-                       strcat(mglFitRes+k, buf);       k+=strlen(buf);\r
+                       buf[31]=0;      strcat(mglFitRes+k, buf);       k+=strlen(buf);\r
                }\r
                else    {       mglFitRes[k] = eq[i];   k++;    }\r
        }\r
index 6ea187149c8238b728e73dbab3fce953b8d6cc65..d1b1318fd3ad059edfc8a6ebccfbce4f3199788e 100644 (file)
@@ -688,7 +688,7 @@ bool mglFont::Load(const char *base, const char *path)
        }\r
        Clear();        // first clear old\r
 \r
-       snprintf(str,256,"%s%c%s.vfm",path,sep,base?base:"");\r
+       snprintf(str,256,"%s%c%s.vfm",path,sep,base?base:"");   str[255]=0;\r
        std::vector<short> norm, bold, ital, both;\r
        if(!(base && *base) || !read_main(str,norm))\r
        {\r
@@ -703,17 +703,17 @@ bool mglFont::Load(const char *base, const char *path)
                //================== bold ===========================================\r
 #pragma omp section\r
                {       char str[256];  snprintf(str,256,"%s%c%s_b.vfm",path,sep,base); // this file may absent\r
-               read_data(str, 1, bold, ex_b);  }\r
+                       str[255]=0;     read_data(str, 1, bold, ex_b);  }\r
 \r
                //================== italic =========================================\r
 #pragma omp section\r
                {       char str[256];  snprintf(str,256,"%s%c%s_i.vfm",path,sep,base);\r
-               read_data(str, 2, ital, ex_i);  }\r
+                       str[255]=0;     read_data(str, 2, ital, ex_i);  }\r
 \r
                //================== bold-italic ====================================\r
 #pragma omp section\r
                {       char str[256];  snprintf(str,256,"%s%c%s_bi.vfm",path,sep,base);\r
-               read_data(str, 3, both, ex_bi); }\r
+                       str[255]=0;     read_data(str, 3, both, ex_bi); }\r
        }\r
 \r
        // now collect data\r
index 04571576f25eb57cb00a374ed0b4fe9e56c43cb6..46eee6dc84df8c2759a567b6ac885a99c73aeae5 100644 (file)
@@ -250,5 +250,6 @@ template <class Treal> void mgl_gspline_init(long n, const mreal *x, const Treal
                c[5*i+3] = (3*h2)*(v[i+1]-v[i]) - (b[i+1]+b[i]+b[i])*h;
                c[5*i+4] = (2*h2*h)*(v[i]-v[i+1]) + (b[i+1]+b[i])*h2;
        }
+       delete []a;     delete []b;
 }
 //-----------------------------------------------------------------------------
index e35b6cacc0268f3a4e58d4c2beca9f7c92d44546..0c327e07e916bf752f5a2a593b6073640057f896 100644 (file)
@@ -17,7 +17,7 @@ HMGL MGL_EXPORT mgl_create_graph_gl()
 uintptr_t MGL_EXPORT mgl_create_graph_gl_()\r
 {      return uintptr_t(new mglCanvasGL);      }\r
 //-----------------------------------------------------------------------------\r
-mglCanvasGL::mglCanvasGL() : mglCanvas(1,1)    {}\r
+mglCanvasGL::mglCanvasGL() : mglCanvas(1,1)    {       Clf();  Zoom(0,0,1,1);  }\r
 //-----------------------------------------------------------------------------\r
 mglCanvasGL::~mglCanvasGL(){}\r
 //-----------------------------------------------------------------------------\r
@@ -189,6 +189,12 @@ void mglCanvasGL::Clf(mglColor Back)
        gl_clf(Back);\r
 }\r
 //-----------------------------------------------------------------------------\r
+void mglCanvasGL::Clf(const char *col)\r
+{\r
+       mglCanvas::Clf(col);\r
+       gl_clf(mglColor(BDef[0]/255.,BDef[1]/255.,BDef[2]/255.));\r
+}\r
+//-----------------------------------------------------------------------------\r
 void mglCanvasGL::gl_clf(mglColor Back)\r
 {\r
        if(Back==NC)    Back = WC;\r
@@ -246,6 +252,7 @@ unsigned char **mglCanvasGL::GetRGBLines(long &width, long &height, unsigned cha
        p = (unsigned char **)malloc(height * sizeof(unsigned char *));\r
        f = (unsigned char *) malloc(width*height * sizeof(unsigned char)*d);\r
        for(long i=0;i<height;i++)      p[i] = f+d*width*(height-1-i);\r
+       glReadBuffer(GL_FRONT);\r
        glPixelStorei(GL_PACK_ALIGNMENT, 1);\r
        glReadPixels(x, y, width, height, alpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, f);\r
        return p;\r
index 9d01f11511a5019a638df028c7519037d5abd55c..0949ef79ba6840ad471159c33b25aa48dc4b9017 100644 (file)
@@ -140,7 +140,7 @@ int mglParser::Exec(mglGraph *gr, const wchar_t *com, long n, mglArg *a, const s
 //-----------------------------------------------------------------------------
 mglParser::mglParser(bool setsize)
 {
-       InUse = 1;
+       InUse = 1;      curGr = 0;
        Skip=Stop=for_br=false;
        memset(for_stack,0,40*sizeof(int));
        memset(if_stack,0,40*sizeof(int));
@@ -470,7 +470,8 @@ int mglParser::ParseDef(std::wstring &str)
                        {
                                res = 0;
                                d = mglFormulaCalc(mgl_trim_ws(s.substr(2)), this, DataList).a[0];
-                               char buf[32];   snprintf(buf,32,"%g",d);        AddParam(nn, buf);
+                               char buf[32];   snprintf(buf,32,"%g",d);
+                               buf[31] = 0;    AddParam(nn, buf);
                        }
                        return res+1;
                }
@@ -532,6 +533,7 @@ int mglParser::ParseDef(std::wstring &str)
 int mglParser::Parse(mglGraph *gr, std::wstring str, long pos)
 {
        if(Stop || gr->NeedStop())      return 0;
+       curGr = gr->Self();
        std::wstring arg[1024];
        str=mgl_trim_ws(str);
        long n,k=0,m=0,mm=0,res;
@@ -612,9 +614,8 @@ int mglParser::Parse(mglGraph *gr, std::wstring str, long pos)
                                if(n && k!=na+2)
                                {
                                        char buf[64];
-                                       snprintf(buf,64,"Bad arguments for %ls: %ld instead of %d\n",
-                                                       a[0].w.c_str(),k-2,na);
-                                       gr->SetWarn(-1,buf);    n = 1;
+                                       snprintf(buf,64,"Bad arguments for %ls: %ld instead of %d\n", a[0].w.c_str(),k-2,na);
+                                       buf[63]=0;      gr->SetWarn(-1,buf);    n = 1;
                                }
                                else if(n)
                                {
@@ -860,6 +861,7 @@ void mglParser::Execute(mglGraph *gr, int n, const wchar_t **text)
                else if(r==4)   snprintf(buf,64,"\nUnbalanced ' in line %ld\n", i+1);
                else if(gr->GetWarn()>0)        snprintf(buf,64," in line %ld\n", i+1);
                else *buf=0;
+               buf[63] = 0;
                if(*buf)        gr->SetWarn(-2,buf);
                if(r>0 && r<5)  res=r;
        }
index c22949b039edcb2474386816b553dc3743eba43c..9e94096d2ee1257501c0eb0a5515d58bc2b22c21 100644 (file)
@@ -621,6 +621,8 @@ void mglCanvas::Finish()
        static mglMatrix bp;\r
        if(Quality==MGL_DRAW_NONE)      return;\r
 #if MGL_HAVE_PTHREAD\r
+       pthread_mutex_lock(&mutexPrm);\r
+       pthread_mutex_lock(&mutexPnt);\r
        pthread_mutex_lock(&mutexClf);\r
 #elif MGL_HAVE_OMP\r
        omp_set_lock(&lockClf);\r
@@ -654,6 +656,8 @@ void mglCanvas::Finish()
        }\r
 #if MGL_HAVE_PTHREAD\r
        pthread_mutex_unlock(&mutexClf);\r
+       pthread_mutex_unlock(&mutexPnt);\r
+       pthread_mutex_unlock(&mutexPrm);\r
 #elif MGL_HAVE_OMP\r
        omp_unset_lock(&lockClf);\r
 #endif\r
@@ -899,7 +903,7 @@ bool MGL_LOCAL_PURE visible(long i, long j, const unsigned char m[8], mreal pw,
 //     register int ii = int(0.5+(i*c+j*s)/pw)%8, jj = int(0.5+(j*c-i*s)/pw)%8;\r
 //     if(ii<0)        ii+=8;  if(jj<0)        jj+=8;\r
        register int ii = int(0.5+(i*c+j*s)/pw)&7, jj = int(0.5+(j*c-i*s)/pw)&7;\r
-       return m[jj] & (1<<ii);\r
+       return m[jj] & (1L<<ii);\r
 }\r
 //-----------------------------------------------------------------------------\r
 /* Bilinear interpolation r(u,v) = r0 + (r1-r0)*u + (r2-r0)*v + (r3+r0-r1-r2)*u*v\r
@@ -1139,7 +1143,7 @@ void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *
                        if(u<0)                 v += u*u;\r
                        else if(u>dd)   v += (u-dd)*(u-dd);\r
                        if(v>pw*pw)             continue;\r
-                       if(!(pd & ( 1<<long(fmod(pp+u/pw/1.5, 16)) ) )) continue;\r
+                       if(!(pd & ( 1L<<long(fmod(pp+u/pw/1.5, 16)) ) ))        continue;\r
                        p = p1+d*(u/dd);        col2int(p,r,oi);\r
                        r[3] = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                        pnt_plot(i,j,p.z+dz,r,oi);\r
@@ -1159,7 +1163,7 @@ void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *
                        if(u<0)                 v += u*u;\r
                        else if(u>dd)   v += (u-dd)*(u-dd);\r
                        if(v>pw*pw)             continue;\r
-                       if(!(pd & (1<<long(fmod(pp+u/pw/1.5, 16)))))            continue;\r
+                       if(!(pd & (1L<<long(fmod(pp+u/pw/1.5, 16)))))           continue;\r
                        p = p1+d*(u/dd);        col2int(p,r,oi);\r
                        r[3] = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
                        pnt_plot(i,j,p.z+dz,r,oi);\r
@@ -1216,7 +1220,7 @@ void mglCanvas::line_pix(long i, long j, const mglPnt &p1, const mglPnt &p2, con
        else if(u>dd)   v += (u-dd)*(u-dd);\r
        register float pw=dr->PenWidth, dpw=3;\r
        if(dr->ObjId==HighId)   {       pw *= 2;        dpw=2;  }\r
-       if(v>pw*pw || !(dr->PDef & ( 1<<long(fmod(dr->pPos+u/pw/1.5, 16)) ) ))  return;\r
+       if(v>pw*pw || !(dr->PDef & ( 1L<<long(fmod(dr->pPos+u/pw/1.5, 16)) ) )) return;\r
        mglPnt p = p1+d*(u/dd);\r
        unsigned char r[4];\r
        col2int(p,r,dr->ObjId);\r
index 592655b16ab862f339cf18b1dd20aed3d8509cfe..0df5b3ec21c235a24928cdc181b2cfd496f76c98 100644 (file)
@@ -214,22 +214,27 @@ void MGL_EXPORT mgl_candle_xyv(HMGL gr, HCDT x, HCDT v1, HCDT v2, HCDT y1, HCDT
        if(y1->GetNx()!=n || y2->GetNx()!=n)\r
        {       gr->SetWarn(mglWarnDim,"Candle");       return; }\r
        static int cgid=1;      gr->StartGroup("Candle",cgid++);\r
-       gr->SaveState(opt);     gr->SetPenPal(pen,&pal);\r
-       gr->NextColor(pal);     gr->Reserve(8*n);\r
+       gr->SaveState(opt);     gr->SetPenPal(pen,&pal);        gr->Reserve(8*n);\r
        bool sh = mglchr(pen,'!');\r
+       bool wire = mglchr(pen,'#');\r
 \r
        mreal dv=nx>n?1:0;\r
        if(mglchr(pen,'<'))     dv = 1;\r
        if(mglchr(pen,'^'))     dv = 0;\r
        if(mglchr(pen,'>'))     dv = -1;\r
        mreal zm = gr->AdjustZMin();\r
+       mreal c1,c2;    c2=c1=gr->NextColor(pal);\r
+       bool col2 = (gr->GetNumPal(pal)==2 && !sh);\r
+       if(col2)        c2 = gr->NextColor(pal);\r
        for(long i=0;i<n;i++)\r
        {\r
                mreal m1=v1->v(i),      m2 = v2->v(i),  xx = x->v(i);\r
-               mreal d = i<nx-1 ? x->v(i+1)-xx : xx-x->v(i-1);\r
+               mreal d = i<nx-1 ? x->v(i+1)-xx : xx-x->v(i-1), c;\r
                mreal x1 = xx + d/2*(dv-gr->BarWidth);\r
                mreal x2 = x1 + gr->BarWidth*d; xx = (x1+x2)/2;\r
-               mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
+               if(sh)  c = gr->NextColor(pal,i);\r
+               else if(wire)   c = (i>0 && m2>v2->v(i-1))?c2:c1;\r
+               else    c = (m1>m2)?c1:c2;\r
                long n1 = gr->AddPnt(mglPoint(xx,y1->v(i),zm),c);\r
                long n2 = gr->AddPnt(mglPoint(xx,m1,zm),c);\r
                gr->line_plot(n1,n2);\r
@@ -243,7 +248,7 @@ void MGL_EXPORT mgl_candle_xyv(HMGL gr, HCDT x, HCDT v1, HCDT v2, HCDT y1, HCDT
                n4 = gr->AddPnt(mglPoint(x2,m2,zm),c);\r
                gr->line_plot(n1,n2);   gr->line_plot(n1,n3);\r
                gr->line_plot(n4,n2);   gr->line_plot(n4,n3);\r
-               if(m1>m2)       gr->quad_plot(n1,n2,n3,n4);\r
+               if(m1>m2 || (col2 && !wire))    gr->quad_plot(n1,n2,n3,n4);\r
        }\r
        if(d1)  delete y1;      if(d2)  delete y2;\r
        gr->EndGroup();\r
@@ -1054,7 +1059,6 @@ void MGL_EXPORT mgl_barh_yx(HMGL gr, HCDT y, HCDT v, const char *pen, const char
        bool wire = mglchr(pen,'#');\r
        bool above = mglchr(pen,'a'), fall = mglchr(pen,'f');\r
        if(above)       fall = false;\r
-       mreal c1,c2;\r
        mreal *dd=new mreal[n], x0,xp,dv=ny>n?1:0;\r
        if(mglchr(pen,'<'))     dv = 1;\r
        if(mglchr(pen,'^'))     dv = 0;\r
@@ -1067,7 +1071,7 @@ void MGL_EXPORT mgl_barh_yx(HMGL gr, HCDT y, HCDT v, const char *pen, const char
        for(long j=0;j<m;j++)\r
        {\r
                if(gr->NeedStop())      break;\r
-               c2=c1=gr->NextColor(pal);\r
+               mreal c1,c2;    c2=c1=gr->NextColor(pal);\r
                if(gr->GetNumPal(pal)==2*m && !sh)      c2 = gr->NextColor(pal);\r
                long mx = j<v->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
                xp = x0 = gr->GetOrgX('y');\r
@@ -1127,7 +1131,7 @@ void MGL_EXPORT mgl_ohlc_x(HMGL gr, HCDT x, HCDT open, HCDT high, HCDT low, HCDT
        {       gr->SetWarn(mglWarnDim,"OHLC"); return; }\r
        gr->SaveState(opt);\r
        static int cgid=1;      gr->StartGroup("OHLC",cgid++);\r
-       mreal dv=nx>n?1:0,dd,vv,x1,x2,cc;\r
+       mreal dv=nx>n?1:0;\r
        if(mglchr(pen,'<'))     dv = 1;\r
        if(mglchr(pen,'^'))     dv = 0;\r
        if(mglchr(pen,'>'))     dv = -1;\r
@@ -1139,24 +1143,27 @@ void MGL_EXPORT mgl_ohlc_x(HMGL gr, HCDT x, HCDT open, HCDT high, HCDT low, HCDT
        for(long j=0;j<m;j++)\r
        {\r
                if(gr->NeedStop())      break;\r
-               cc=gr->NextColor(pal);\r
+               mreal c1,c2;    c2=c1=gr->NextColor(pal);\r
+               if(gr->GetNumPal(pal)==2*m && !sh)      c2 = gr->NextColor(pal);\r
                mx = j<x->GetNy() ? j:0;\r
                for(long i=0;i<n;i++)\r
                {\r
+                       mreal dd,vv,x1,x2;\r
                        vv = x->v(i,mx);        dd = i<nx-1 ? x->v(i+1)-vv : vv-x->v(i-1);\r
                        x1 = vv + dd/2*(dv-gr->BarWidth);       x2 = x1 + gr->BarWidth*dd;\r
                        x2 = (x2-x1)/m;         x1 += j*x2;             x2 += x1;       vv = (x2+x1)/2;\r
-                       mreal c = sh ? gr->NextColor(pal,i):cc;\r
+                       if(sh)  c1=c2=gr->NextColor(pal,i);\r
                        register long n1,n2;\r
 \r
-                       dd = open->v(i,j);\r
-                       n1=gr->AddPnt(mglPoint(x1,dd,zVal),c);\r
-                       n2=gr->AddPnt(mglPoint(vv,dd,zVal),c);\r
-                       gr->line_plot(n1,n2);\r
                        dd = close->v(i,j);\r
+                       mreal c = (i==0 || dd>=close->v(i-1,j)) ? c1:c2;\r
                        n1=gr->AddPnt(mglPoint(vv,dd,zVal),c);\r
                        n2=gr->AddPnt(mglPoint(x2,dd,zVal),c);\r
                        gr->line_plot(n1,n2);\r
+                       dd = open->v(i,j);\r
+                       n1=gr->AddPnt(mglPoint(x1,dd,zVal),c);\r
+                       n2=gr->AddPnt(mglPoint(vv,dd,zVal),c);\r
+                       gr->line_plot(n1,n2);\r
                        n1=gr->AddPnt(mglPoint(vv,low->v(i,j),zVal),c);\r
                        n2=gr->AddPnt(mglPoint(vv,high->v(i,j),zVal),c);\r
                        gr->line_plot(n1,n2);\r
index 0890e990149cfd86c2481d452f557d60793aceef..3734b42ab3e645f95c011d80468b2f01f555fd24 100644 (file)
@@ -74,8 +74,8 @@ void MGL_EXPORT mgl_fsurf(HMGL gr, const char *eqZ, const char *sch, const char
        mreal r = gr->SaveState(opt);\r
        long n = (mgl_isnan(r) || r<=0) ? 100:long(r+0.5);\r
        mglData z(n,n),res;\r
-       mglDataV x(n,n);        x.Fill(gr->Min.x,gr->Max.x,'x');        x.s=L"x";\r
-       mglDataV y(n,n);        y.Fill(gr->Min.y,gr->Max.y,'y');        y.s=L"y";\r
+       mglDataV x(n,n,1, gr->Min.x,gr->Max.x,'x');     x.s=L"x";\r
+       mglDataV y(n,n,1, gr->Min.y,gr->Max.y,'y');     y.s=L"y";\r
        mglDataV t(n,n);        t.s=L"#$mgl";\r
        std::vector<mglDataA*> list;\r
        list.push_back(&x);     list.push_back(&y);     list.push_back(&t);\r
@@ -90,8 +90,8 @@ void MGL_EXPORT mgl_fsurf_xyz(HMGL gr, const char *eqX, const char *eqY, const c
        mreal r = gr->SaveState(opt);\r
        long n = (mgl_isnan(r) || r<=0) ? 100:long(r+0.5);\r
        mglData z(n,n), x(n,n), y(n,n), res;\r
-       mglDataV u(n,n);        u.Fill(0,1,'x');        u.s=L"u";\r
-       mglDataV v(n,n);        v.Fill(0,1,'y');        v.s=L"v";\r
+       mglDataV u(n,n,1, 0,1,'x');     u.s=L"u";\r
+       mglDataV v(n,n,1, 0,1,'y');     v.s=L"v";\r
        mglDataV t(n,n);        t.s=L"#$mgl";\r
        std::vector<mglDataA*> list;\r
        list.push_back(&u);     list.push_back(&v);     list.push_back(&t);\r
index a7b80263035abfbaa7ee70cdc5811f4cee10c007..b31e7da214b27f0cd4884983d88a08755e14facc 100644 (file)
@@ -2311,7 +2311,7 @@ These functions draw boxplot (also known as a box-and-whisker diagram) at points
 @deftypefnx {C function} @code{void} mgl_candle_yv (@code{HMGL} gr, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_candle_xyv (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-These functions draw candlestick chart at points @var{x}[i]. This is a combination of a line-chart and a bar-chart, in that each bar represents the range of price movement over a given time interval. Wire (or white) candle correspond to price growth @var{v1}[i]<@var{v2}[i], opposite case -- solid (or dark) candle. "Shadows" show the minimal @var{y1} and maximal @var{y2} prices. If @var{v2} is absent then it is determined as @var{v2}[i]=@var{v1}[i+1]. See also @ref{plot}, @ref{bars}, @ref{ohlc}, @ref{barwidth}. @sref{Candle sample}
+These functions draw candlestick chart at points @var{x}[i]. This is a combination of a line-chart and a bar-chart, in that each bar represents the range of price movement over a given time interval. Wire (or white) candle correspond to price growth @var{v1}[i]<@var{v2}[i], opposite case -- solid (or dark) candle. You can give different colors for growth and decrease values if number of specified colors is equal to 2. If @var{pen} contain @samp{#} then the wire candle will be used even for 2-color scheme. "Shadows" show the minimal @var{y1} and maximal @var{y2} prices. If @var{v2} is absent then it is determined as @var{v2}[i]=@var{v1}[i+1]. See also @ref{plot}, @ref{bars}, @ref{ohlc}, @ref{barwidth}. @sref{Candle sample}
 @end deftypefn
 
 @anchor{ohlc}
@@ -2323,7 +2323,7 @@ These functions draw candlestick chart at points @var{x}[i]. This is a combinati
 @deftypefnx {C function} @code{void} mgl_ohlc (@code{HMGL} gr, @code{HCDT} o, @code{HCDT} h, @code{HCDT} l, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_ohlc_x (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} o, @code{HCDT} h, @code{HCDT} l, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-These functions draw Open-High-Low-Close diagram. This diagram show vertical line for between maximal(high @var{h}) and minimal(low @var{l}) values, as well as horizontal lines before/after vertical line for initial(open @var{o})/final(close @var{c}) values of some process (usually price). See also @ref{candle}, @ref{plot}, @ref{barwidth}. @sref{OHLC sample}
+These functions draw Open-High-Low-Close diagram. This diagram show vertical line for between maximal(high @var{h}) and minimal(low @var{l}) values, as well as horizontal lines before/after vertical line for initial(open @var{o})/final(close @var{c}) values of some process (usually price). You can give different colors for up and down values (when closing values higher or not as in previous point) if number of specified colors is equal to 2*number of curves. See also @ref{candle}, @ref{plot}, @ref{barwidth}. @sref{OHLC sample}
 @end deftypefn
 
 
@@ -3380,10 +3380,10 @@ Fit data along x-, y- and z-directions for array specified parametrically @var{a
 @end deftypefn
 
 @anchor{fit}
-@deftypefn {MGL command} {} fit res adat sdat 'func' 'var' [ini=0]
-@deftypefnx {MGL command} {} fit res xdat adat sdat 'func' 'var' [ini=0]
-@deftypefnx {MGL command} {} fit res xdat ydat adat sdat 'func' 'var' [ini=0]
-@deftypefnx {MGL command} {} fit res xdat ydat zdat adat sdat 'func' 'var' [ini=0]
+@deftypefn {MGL command} {} fit res adat 'func' 'var' [ini=0]
+@deftypefnx {MGL command} {} fit res xdat adat 'func' 'var' [ini=0]
+@deftypefnx {MGL command} {} fit res xdat ydat adat 'func' 'var' [ini=0]
+@deftypefnx {MGL command} {} fit res xdat ydat zdat adat 'func' 'var' [ini=0]
 @ifclear UDAV
 @deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
 @deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
index bb7c2d5b631e79d4da8587da7ad70e5301e2a651..b2c87f5be269925dff520b4cffe308418ec512ef 100644 (file)
@@ -2218,7 +2218,7 @@ Draw bitmap (logo) along whole axis range, which can be changed by @ref{Command
 @deftypefnx {Функция С} @code{void} mgl_candle_yv (@code{HMGL} gr, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_candle_xyv (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-Функции рисуют candlestick chart в точках @var{x}[i]. Этот график показывает прямоугольником ("свечой") диапазон изменения величины. Прозрачная (белая) свеча соответствует росту величины @var{v1}[i]<@var{v2}[i], чёрная -- уменьшению. "Тени" показывают минимальное @var{y1} и максимальное @var{y2} значения. Если @var{v2} отсутствует, то он определяется как @var{v2}[i]=@var{v1}[i+1]. См. также @ref{plot}, @ref{bars}, @ref{ohlc}, @ref{barwidth}. @sref{Candle sample}
+ФÑ\83нкÑ\86ии Ñ\80иÑ\81Ñ\83Ñ\8eÑ\82 candlestick chart Ð² Ñ\82оÑ\87каÑ\85 @var{x}[i]. Ð­Ñ\82оÑ\82 Ð³Ñ\80аÑ\84ик Ð¿Ð¾ÐºÐ°Ð·Ñ\8bваеÑ\82 Ð¿Ñ\80Ñ\8fмоÑ\83голÑ\8cником ("Ñ\81веÑ\87ой") Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ\8f Ð²ÐµÐ»Ð¸Ñ\87инÑ\8b. Ð\9fÑ\80озÑ\80аÑ\87наÑ\8f (белаÑ\8f) Ñ\81веÑ\87а Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83еÑ\82 Ñ\80оÑ\81Ñ\82Ñ\83 Ð²ÐµÐ»Ð¸Ñ\87инÑ\8b @var{v1}[i]<@var{v2}[i], Ñ\87Ñ\91Ñ\80наÑ\8f -- Ñ\83менÑ\8cÑ\88ениÑ\8e. "Тени" Ð¿Ð¾ÐºÐ°Ð·Ñ\8bваÑ\8eÑ\82 Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»Ñ\8cное @var{y1} Ð¸ Ð¼Ð°ÐºÑ\81ималÑ\8cное @var{y2} Ð·Ð½Ð°Ñ\87ениÑ\8f. Ð\95Ñ\81ли @var{v2} Ð¾Ñ\82Ñ\81Ñ\83Ñ\82Ñ\81Ñ\82вÑ\83еÑ\82, Ñ\82о Ð¾Ð½ Ð¾Ð¿Ñ\80еделÑ\8fеÑ\82Ñ\81Ñ\8f ÐºÐ°Ðº @var{v2}[i]=@var{v1}[i+1]. Ð\9cожно Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ñ\80азнÑ\8bе Ñ\86веÑ\82а Ð´Ð»Ñ\8f Ñ\80аÑ\81Ñ\82Ñ\83Ñ\89иÑ\85 Ð¸ Ð¿Ð°Ð´Ð°Ñ\8eÑ\89иÑ\85 Ð´Ð½ÐµÐ¹ ÐµÑ\81ли Ñ\87иÑ\81ло Ñ\83казаннÑ\8bÑ\85 Ñ\86веÑ\82ов Ñ\80авно Ñ\83двоенномÑ\83 Ñ\87иÑ\81лÑ\83 ÐºÑ\80ивÑ\8bÑ\85 Ð´Ð»Ñ\8f Ð¿Ð¾Ñ\81Ñ\82Ñ\80оениÑ\8f. Ð\95Ñ\81ли @var{pen} Ñ\81одеÑ\80жиÑ\82 @samp{#}, Ñ\82о Ð¿Ñ\80озÑ\80аÑ\87наÑ\8f Ñ\81веÑ\87а Ð±Ñ\83деÑ\82 Ð¸Ñ\81полÑ\8cзована Ð¸ Ð¿Ñ\80и 2-Ñ\86веÑ\82ной Ñ\81Ñ\85еме. Ð¡Ð¼. Ñ\82акже @ref{plot}, @ref{bars}, @ref{ohlc}, @ref{barwidth}. @sref{Candle sample}
 @end deftypefn
 
 @anchor{ohlc}
@@ -2230,7 +2230,7 @@ Draw bitmap (logo) along whole axis range, which can be changed by @ref{Command
 @deftypefnx {Функция С} @code{void} mgl_ohlc (@code{HMGL} gr, @code{HCDT} o, @code{HCDT} h, @code{HCDT} l, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
 @deftypefnx {Функция С} @code{void} mgl_ohlc_x (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} o, @code{HCDT} h, @code{HCDT} l, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
-Функции рисуют Open-High-Low-Close диаграмму. Этот график содержит вертикальные линии между максимальным @var{h} и минимальным @var{l} значениями, и горизонтальные линии перед/после вертикальной линии для начального @var{o} и конечного @var{c} значений процесса (обычно цены). См. также @ref{candle}, @ref{plot}, @ref{barwidth}. @sref{OHLC sample}
+ФÑ\83нкÑ\86ии Ñ\80иÑ\81Ñ\83Ñ\8eÑ\82 Open-High-Low-Close Ð´Ð¸Ð°Ð³Ñ\80аммÑ\83. Ð­Ñ\82оÑ\82 Ð³Ñ\80аÑ\84ик Ñ\81одеÑ\80жиÑ\82 Ð²ÐµÑ\80Ñ\82икалÑ\8cнÑ\8bе Ð»Ð¸Ð½Ð¸Ð¸ Ð¼ÐµÐ¶Ð´Ñ\83 Ð¼Ð°ÐºÑ\81ималÑ\8cнÑ\8bм @var{h} Ð¸ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»Ñ\8cнÑ\8bм @var{l} Ð·Ð½Ð°Ñ\87ениÑ\8fми, Ð¸ Ð³Ð¾Ñ\80изонÑ\82алÑ\8cнÑ\8bе Ð»Ð¸Ð½Ð¸Ð¸ Ð¿ÐµÑ\80ед/поÑ\81ле Ð²ÐµÑ\80Ñ\82икалÑ\8cной Ð»Ð¸Ð½Ð¸Ð¸ Ð´Ð»Ñ\8f Ð½Ð°Ñ\87алÑ\8cного @var{o} Ð¸ ÐºÐ¾Ð½ÐµÑ\87ного @var{c} Ð·Ð½Ð°Ñ\87ений Ð¿Ñ\80оÑ\86еÑ\81Ñ\81а (обÑ\8bÑ\87но Ñ\86енÑ\8b). Ð\9cожно Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ñ\80азнÑ\8bе Ñ\86веÑ\82а Ð´Ð»Ñ\8f Ñ\80аÑ\81Ñ\82Ñ\83Ñ\89иÑ\85 Ð¸ Ð¿Ð°Ð´Ð°Ñ\8eÑ\89иÑ\85 Ð´Ð½ÐµÐ¹ ÐµÑ\81ли Ñ\87иÑ\81ло Ñ\83казаннÑ\8bÑ\85 Ñ\86веÑ\82ов Ñ\80авно Ñ\83двоенномÑ\83 Ñ\87иÑ\81лÑ\83 ÐºÑ\80ивÑ\8bÑ\85 Ð´Ð»Ñ\8f Ð¿Ð¾Ñ\81Ñ\82Ñ\80оениÑ\8f. Ð¡Ð¼. Ñ\82акже @ref{candle}, @ref{plot}, @ref{barwidth}. @sref{OHLC sample}
 @end deftypefn
 
 
@@ -3292,10 +3292,10 @@ Draw bitmap (logo) along whole axis range, which can be changed by @ref{Command
 @end deftypefn
 
 @anchor{fit}
-@deftypefn {Команда MGL} {} fit res adat sdat 'func' 'var' [ini=0]
-@deftypefnx {Команда MGL} {} fit res xdat adat sdat 'func' 'var' [ini=0]
-@deftypefnx {Команда MGL} {} fit res xdat ydat adat sdat 'func' 'var' [ini=0]
-@deftypefnx {Команда MGL} {} fit res xdat ydat zdat adat sdat 'func' 'var' [ini=0]
+@deftypefn {Команда MGL} {} fit res adat 'func' 'var' [ini=0]
+@deftypefnx {Команда MGL} {} fit res xdat adat 'func' 'var' [ini=0]
+@deftypefnx {Команда MGL} {} fit res xdat ydat adat 'func' 'var' [ini=0]
+@deftypefnx {Команда MGL} {} fit res xdat ydat zdat adat 'func' 'var' [ini=0]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
 @deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
index 1e46da6a067ffbbefff6fe979bf25e3b4ac6f79d..5d09f282d8bd4a033c2df2dc88a8072376780de5 100644 (file)
@@ -72,45 +72,45 @@ This file documents the Mathematical Graphic Library (MathGL), a collection of c
 <tr><td style="padding-left: 5px;font-size: 110%"> <a target=_blank href="http://groups.google.com/group/mathgl"><b>MathGL</b></a> </td></tr>
 </table>
 
-@comment  <hr style="width: 100%; height: 1px;">
-@comment  <script type="text/javascript"><!--
-@comment  google_ad_client = "ca-pub-1128070552722622";
-@comment  /* Vertical small */
-@comment  google_ad_slot = "5501954624";
-@comment  google_ad_width = 120;
-@comment  google_ad_height = 240;
-@comment  //-->
-@comment  </script>
-@comment  <script type="text/javascript"
-@comment  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
-@comment  </script>
+<hr style="width: 100%; height: 1px;">
+<script type="text/javascript"><!--
+google_ad_client = "ca-pub-1128070552722622";
+/* Vertical small */
+google_ad_slot = "5501954624";
+google_ad_width = 120;
+google_ad_height = 240;
+//-->
+</script>
+<script type="text/javascript"
+src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+</script>
 </nav>
 @end html
 @end macro
 
 @macro external {}
 @html
-@comment  <br><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
-@comment  <!-- Ref 728x15 -->
-@comment  <ins class="adsbygoogle"
-@comment  style="display:inline-block;width:728px;height:15px"
-@comment  data-ad-client="ca-pub-1128070552722622"
-@comment  data-ad-slot="7008431385"></ins>
-@comment  <script>
-@comment  (adsbygoogle = window.adsbygoogle || []).push({});
-@comment  </script><br>
+<br><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
+<!-- Ref 728x15 -->
+<ins class="adsbygoogle"
+style="display:inline-block;width:728px;height:15px"
+data-ad-client="ca-pub-1128070552722622"
+data-ad-slot="7008431385"></ins>
+<script>
+(adsbygoogle = window.adsbygoogle || []).push({});
+</script><br>
 @comment
-@comment  <script type="text/javascript"><!--
-@comment  google_ad_client = "ca-pub-1128070552722622";
-@comment  /* 728x90, создано 23.12.09 */
-@comment  google_ad_slot = "9958083480";
-@comment  google_ad_width = 728;
-@comment  google_ad_height = 90;
-@comment  //-->
-@comment  </script>
-@comment  <script type="text/javascript"
-@comment  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
-@comment  </script><br/>
+<script type="text/javascript"><!--
+google_ad_client = "ca-pub-1128070552722622";
+/* 728x90, создано 23.12.09 */
+google_ad_slot = "9958083480";
+google_ad_width = 728;
+google_ad_height = 90;
+//-->
+</script>
+<script type="text/javascript"
+src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+</script><br/>
 <footer>
 <!--LiveInternet counter--><script type="text/javascript"><!--
 document.write("<a href='http://www.liveinternet.ru/click' "+
index 37c95d303258d7cbe069a066a3eddacf2914a3f7..24b31084f545a0e6e8271b99a2dd17e4c0e23e68 100644 (file)
@@ -75,45 +75,45 @@ This file documents the Mathematical Graphic Library (MathGL), a collection of c
 <tr><td style="padding-left: 5px;font-size: 110%"> <a target=_blank href="http://groups.google.com/group/mathgl"><b>MathGL</b></a> </td></tr>
 </table>
 
-@comment  <hr style="width: 100%; height: 1px;">
-@comment  <script type="text/javascript"><!--
-@comment  google_ad_client = "ca-pub-1128070552722622";
-@comment  /* Vertical small */
-@comment  google_ad_slot = "5501954624";
-@comment  google_ad_width = 120;
-@comment  google_ad_height = 240;
-@comment  //-->
-@comment  </script>
-@comment  <script type="text/javascript"
-@comment  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
-@comment  </script>
+<hr style="width: 100%; height: 1px;">
+<script type="text/javascript"><!--
+google_ad_client = "ca-pub-1128070552722622";
+/* Vertical small */
+google_ad_slot = "5501954624";
+google_ad_width = 120;
+google_ad_height = 240;
+//-->
+</script>
+<script type="text/javascript"
+src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+</script>
 </nav>
 @end html
 @end macro
 
 @macro external {}
 @html
-@comment  <br><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
-@comment  <!-- Ref 728x15 -->
-@comment  <ins class="adsbygoogle"
-@comment  style="display:inline-block;width:728px;height:15px"
-@comment  data-ad-client="ca-pub-1128070552722622"
-@comment  data-ad-slot="7008431385"></ins>
-@comment  <script>
-@comment  (adsbygoogle = window.adsbygoogle || []).push({});
-@comment  </script><br>
+<br><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
+<!-- Ref 728x15 -->
+<ins class="adsbygoogle"
+style="display:inline-block;width:728px;height:15px"
+data-ad-client="ca-pub-1128070552722622"
+data-ad-slot="7008431385"></ins>
+<script>
+(adsbygoogle = window.adsbygoogle || []).push({});
+</script><br>
 @comment
-@comment  <script type="text/javascript"><!--
-@comment  google_ad_client = "ca-pub-1128070552722622";
-@comment  /* 728x90, создано 23.12.09 */
-@comment  google_ad_slot = "9958083480";
-@comment  google_ad_width = 728;
-@comment  google_ad_height = 90;
-@comment  //-->
-@comment  </script>
-@comment  <script type="text/javascript"
-@comment  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
-@comment  </script><br/>
+<script type="text/javascript"><!--
+google_ad_client = "ca-pub-1128070552722622";
+/* 728x90, создано 23.12.09 */
+google_ad_slot = "9958083480";
+google_ad_width = 728;
+google_ad_height = 90;
+//-->
+</script>
+<script type="text/javascript"
+src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+</script><br/>
 <footer>
 <!--LiveInternet counter--><script type="text/javascript"><!--
 document.write("<a href='http://www.liveinternet.ru/click' "+
index 40fad8106052de514c496adb6963c4cf41d4e36c..c47eabfc259664e790ad5c5e945db5c68519c4d9 100644 (file)
@@ -1200,7 +1200,7 @@ subplot 1 1 0 '':title 'OHLC plot':box
 ohlc o h l c
 @end verbatim
 
-@pfig{candle, Example of OHLC()}
+@pfig{ohlc, Example of OHLC()}
 
 @c ------------------------------------------------------------------
 @external{}
@@ -1805,7 +1805,7 @@ Command @ref{surf3} is one of most suitable (for my opinion) functions to visual
 @verbatim
 call 'prepare3d'
 light on:alpha on
-subplot 2 2 1:title 'Surf3 plot':rotate 50 60:box
+subplot 2 2 0:title 'Surf3 plot':rotate 50 60:box
 surf3 c
 
 subplot 2 2 1:title '"\#" style':rotate 50 60:box
index 57dbe35fad23af6c70670bb017a7812b1ac5080a..6051ed0c4f5b49fc6077fb39d87306da43e2a855 100644 (file)
@@ -1200,7 +1200,7 @@ subplot 1 1 0 '':title 'OHLC plot':box
 ohlc o h l c
 @end verbatim
 
-@pfig{candle, Example of OHLC()}
+@pfig{ohlc, Example of OHLC()}
 
 @c ------------------------------------------------------------------
 @external{}
@@ -1805,7 +1805,7 @@ Command @ref{surf3} is one of most suitable (for my opinion) functions to visual
 @verbatim
 call 'prepare3d'
 light on:alpha on
-subplot 2 2 1:title 'Surf3 plot':rotate 50 60:box
+subplot 2 2 0:title 'Surf3 plot':rotate 50 60:box
 surf3 c
 
 subplot 2 2 1:title '"\#" style':rotate 50 60:box
index b66e7053a48ed26441fcd5882fb44a4d2248655f..eeb9851b40bbd97b94d35a60ccaa1d040ba22b2d 100644 (file)
@@ -1,2 +1,2 @@
 @set VERSION 2.3
-@set MINVER .1
+@set MINVER .2
index 29c5289c1050d65d41600f2db7a376c928ea0cab..370b144887dac23203f9be129369a72aca05f440 100644 (file)
@@ -1,3 +1,7 @@
+2.3.2 Released 2 February 2015
+2.3.1 Released 21 October 2014
+2.3 Released 7 August 2014
+2.2.2.1 Released 19 March 2014
 2.2.2 Released 10 March 2014
 2.2.1 Released 22 January 2014
 2.2 Released 11 November 2013
index 940c54caba599fcf4d2dfb4fa1394e786c69ce97..c06a7fd7580dbf5729e689f60c6b4dfcfaa956ab 100644 (file)
@@ -52,8 +52,8 @@ Generally, MathGL is GPL library. However, you can use LGPL license for MathGL c
 
 @strong{Latest news}
 @itemize
-@item @emph{20 October 2014.}
-New version (v.@value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are @ref{LaTeX package}, command to load external DLL file (@ref{load}), new primitive (@ref{logo}), improvements for projections, manual rotation angle in @ref{axis} and other minor improvements, which denoted @ref{News, here}.
+@item @emph{2 February 2015.}
+New version (v.@value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are parallelizing of reading data files, updating @ref{LaTeX package}, other minor improvements and bugfixes, which denoted @ref{News, here}.
 @item @emph{7 August 2014.}
 New version (v.@value{VERSION}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are many major improvements for both MathGL core and for UDAV, which denoted @ref{News, here}.
 @end itemize
@@ -75,14 +75,26 @@ Javascript interface was developed with support of @url{http://www.datadvance.ne
 
 @itemize
 
-@item @strong{20 October 2014.}
+@item @strong{2 February 2015.}
+New version (v.2.3.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor improvements and bugfixes:
+@itemize @bullet
+@item Update @ref{LaTeX package} (thanks to Diego Sejas Viscarra)
+@item Add reading files with complex numbers by @ref{read} command.
+@item Parallelize reading textual data files.
+@item Add 'i','j','k' variables for data filling (see @ref{fill}).
+@item Add saving images in QMathGL even if corresponding format support is disabled.
+@item Add cmake option MGL_DEF_FONT to change default font name or use built-in one (if MGL_DEF_FONT is empty).
+@item Compatibility changes and bugfixes.
+@end itemize
+
+@item @strong{21 October 2014.}
 New version (v.2.3.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor improvements and bugfixes:
 @itemize @bullet
 @item Add @ref{LaTeX package} @emph{mglTeX} (author Diego Sejas Viscarra) for making figures directly from MGL script located in LaTeX file.
 @item Add MGL command @ref{load} for loading MGL commands from external DLL (or .so) module.
 @item Add @ref{logo} function to draw bitmap (logo), which is stretched along whole axis range.
 @item Add MGL command @ref{reset} which restore default settings and clear image (i.e. call @code{DefaultPlotParam()}).
-@item Add option @code{value} to @ref{axis} function, which allow to set rotation angle for tick labels.
+@c @item Add option @code{value} to @ref{axis} function, which allow to set rotation angle for tick labels.
 @item Change y coordinate at x-z projection.
 @item Improve projection of 'unrotatable' objects (like @ref{legend}, @ref{title}, ...).
 @item Add projection (@ref{ternary}&8) which is the same as usual (@ref{ternary}&4) but don't print text on projections
index 940c54caba599fcf4d2dfb4fa1394e786c69ce97..c06a7fd7580dbf5729e689f60c6b4dfcfaa956ab 100644 (file)
@@ -52,8 +52,8 @@ Generally, MathGL is GPL library. However, you can use LGPL license for MathGL c
 
 @strong{Latest news}
 @itemize
-@item @emph{20 October 2014.}
-New version (v.@value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are @ref{LaTeX package}, command to load external DLL file (@ref{load}), new primitive (@ref{logo}), improvements for projections, manual rotation angle in @ref{axis} and other minor improvements, which denoted @ref{News, here}.
+@item @emph{2 February 2015.}
+New version (v.@value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are parallelizing of reading data files, updating @ref{LaTeX package}, other minor improvements and bugfixes, which denoted @ref{News, here}.
 @item @emph{7 August 2014.}
 New version (v.@value{VERSION}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are many major improvements for both MathGL core and for UDAV, which denoted @ref{News, here}.
 @end itemize
@@ -75,14 +75,26 @@ Javascript interface was developed with support of @url{http://www.datadvance.ne
 
 @itemize
 
-@item @strong{20 October 2014.}
+@item @strong{2 February 2015.}
+New version (v.2.3.2) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor improvements and bugfixes:
+@itemize @bullet
+@item Update @ref{LaTeX package} (thanks to Diego Sejas Viscarra)
+@item Add reading files with complex numbers by @ref{read} command.
+@item Parallelize reading textual data files.
+@item Add 'i','j','k' variables for data filling (see @ref{fill}).
+@item Add saving images in QMathGL even if corresponding format support is disabled.
+@item Add cmake option MGL_DEF_FONT to change default font name or use built-in one (if MGL_DEF_FONT is empty).
+@item Compatibility changes and bugfixes.
+@end itemize
+
+@item @strong{21 October 2014.}
 New version (v.2.3.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are minor improvements and bugfixes:
 @itemize @bullet
 @item Add @ref{LaTeX package} @emph{mglTeX} (author Diego Sejas Viscarra) for making figures directly from MGL script located in LaTeX file.
 @item Add MGL command @ref{load} for loading MGL commands from external DLL (or .so) module.
 @item Add @ref{logo} function to draw bitmap (logo), which is stretched along whole axis range.
 @item Add MGL command @ref{reset} which restore default settings and clear image (i.e. call @code{DefaultPlotParam()}).
-@item Add option @code{value} to @ref{axis} function, which allow to set rotation angle for tick labels.
+@c @item Add option @code{value} to @ref{axis} function, which allow to set rotation angle for tick labels.
 @item Change y coordinate at x-z projection.
 @item Improve projection of 'unrotatable' objects (like @ref{legend}, @ref{title}, ...).
 @item Add projection (@ref{ternary}&8) which is the same as usual (@ref{ternary}&4) but don't print text on projections
index 93e71485a60d48e5eb1a3b9c0f9a2933841dd482..4b38cfe3727d1070c510990074d21ee856b8b329 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -19,7 +19,6 @@
 15. Frames by mouse in UDAV ???
        A. мысли о frame??? для группы графиков -- не "удалять" их, а запихивать в отдельный кадр -- вопрос что с анимацией???
        B. как делать анимацию (кадры) для мышиной версии ... список кадров, кнопки добавить в кадры + вставить из кадра
-16. Docs about mgl_datac_diffr
 17. Extend QO + extra docs
 18. Import OBJ ???
 19. Simplified triangle filling for Quality=1 ?!?
@@ -43,9 +42,16 @@ ZZ. Update *.i for new functions {before release!!!}
        u. Test FlowP + 3d
 
 7. Improve z-order for rapidly oscillating surfaces
-10. Manual rotation angle for axis ticks (as "value" option?!)
-11. Export to XPM (like GIF)
-13. Title and perspective
+8. Manual rotation angle for axis ticks (as "value" option?!)
+9. Export to XPM (like GIF)
+10. Title and perspective
+11. Adjust BarWidth for proper using prevous (i-1) point
+
+12. introduce a set of default arrays like "x", "y", "z" and "t" for MGL ???
+13. Use mgltex.dtx (see e-mail 15 November)
+14. Binary font files for particular platform (+ check ARM). Add utility to translate from current (textual) to binary.
+16. Contour lines above/under surface (e-mail 10.12.14)
+17. Iris plot -- https://en.wikipedia.org/wiki/Iris_flower_data_set
 
 ============= DOCUMENTATION =============
 
@@ -54,10 +60,14 @@ B. Add chapter with real samples
 C. Translate to Russian everything
 D. Docs about JS interface
 
+1. Docs about new Smooth() styles
+
 YY. Sample like http://pyxplot.org.uk/examples/05ap/02hlines/index.html using Stem()
 
 ============= UDAV =============
 
+1. Zoom rectangle after mouse selection
+
 2. Create default plot depending on selected row/column/range in data table ?!?
 
 3. Manual data changing should be written into script
index 12212f93399830f96cf03d06184006844368c2f1..a12fbd79af8298b3276c33b1d992d1b5cd52f1ee 100644 (file)
@@ -131,32 +131,32 @@ CalcDialog::CalcDialog(QWidget *parent) : QWidget(parent)
 CalcDialog::~CalcDialog()      {}
 void CalcDialog::foc() {       text->setFocus(Qt::ActiveWindowFocusReason);    }
 //-----------------------------------------------------------------------------
-void CalcDialog::key1()                {       text->setText("1");     foc();  }
-void CalcDialog::key2()                {       text->setText("2");     foc();  }
-void CalcDialog::key3()                {       text->setText("3");     foc();  }
-void CalcDialog::key4()                {       text->setText("4");     foc();  }
-void CalcDialog::key5()                {       text->setText("5");     foc();  }
-void CalcDialog::key6()                {       text->setText("6");     foc();  }
-void CalcDialog::key7()                {       text->setText("7");     foc();  }
-void CalcDialog::key8()                {       text->setText("8");     foc();  }
-void CalcDialog::key9()                {       text->setText("9");     foc();  }
-void CalcDialog::key0()                {       text->setText("0");     foc();  }
-void CalcDialog::keyE()                {       text->setText("E");     foc();  }
-void CalcDialog::keyPi()       {       text->setText("pi");    foc();  }
-void CalcDialog::keyX2()       {       text->setText("^2");    foc();  }
-void CalcDialog::keyAdd()      {       text->setText("+");     foc();  }
-void CalcDialog::keyMul()      {       text->setText("*");     foc();  }
-void CalcDialog::keySub()      {       text->setText("-");     foc();  }
-void CalcDialog::keyDiv()      {       text->setText("/");     foc();  }
-void CalcDialog::keyBrO()      {       text->setText("(");     foc();  }
-void CalcDialog::keyBrC()      {       text->setText(")");     foc();  }
-void CalcDialog::keyDot()      {       text->setText(".");     foc();  }
+void CalcDialog::key1()                {       text->insert("1");      foc();  }
+void CalcDialog::key2()                {       text->insert("2");      foc();  }
+void CalcDialog::key3()                {       text->insert("3");      foc();  }
+void CalcDialog::key4()                {       text->insert("4");      foc();  }
+void CalcDialog::key5()                {       text->insert("5");      foc();  }
+void CalcDialog::key6()                {       text->insert("6");      foc();  }
+void CalcDialog::key7()                {       text->insert("7");      foc();  }
+void CalcDialog::key8()                {       text->insert("8");      foc();  }
+void CalcDialog::key9()                {       text->insert("9");      foc();  }
+void CalcDialog::key0()                {       text->insert("0");      foc();  }
+void CalcDialog::keyE()                {       text->insert("E");      foc();  }
+void CalcDialog::keyPi()       {       text->insert("pi");     foc();  }
+void CalcDialog::keyX2()       {       text->insert("^2");     foc();  }
+void CalcDialog::keyAdd()      {       text->insert("+");      foc();  }
+void CalcDialog::keyMul()      {       text->insert("*");      foc();  }
+void CalcDialog::keySub()      {       text->insert("-");      foc();  }
+void CalcDialog::keyDiv()      {       text->insert("/");      foc();  }
+void CalcDialog::keyBrO()      {       text->insert("(");      foc();  }
+void CalcDialog::keyBrC()      {       text->insert(")");      foc();  }
+void CalcDialog::keyDot()      {       text->insert(".");      foc();  }
 void CalcDialog::clear()       {       text->clear();  foc();  }
 //-----------------------------------------------------------------------------
 void CalcDialog::keyFnc()
 {
-       text->setText(func->currentText());
-       text->setCursorPosition(func->currentText().length()-1);        foc();
+       text->insert(func->currentText());
+       text->setCursorPosition(text->cursorPosition()-1);      foc();
 }
 //-----------------------------------------------------------------------------
 void CalcDialog::keyPut()      {       emit putNumber(result->text()); }
diff --git a/udav/mgl.xml b/udav/mgl.xml
new file mode 100644 (file)
index 0000000..8aaa20f
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mime-type xmlns="http://www.freedesktop.org/standards/shared-mime-info" type="text/mgl">
+  <comment>MGL script</comment>
+  <icon name="/usr/local/share/pixmaps/udav.png"/>
+  <glob pattern="*.mgl"/>
+</mime-type>
index 443eca5318a2dc064245db8bd4319c1df32055d0..eff4ffc4600756e390b1c92c49cfbd335503ac43 100644 (file)
@@ -54,7 +54,7 @@ DataOpenDialog::DataOpenDialog(QWidget *parent) : QDialog(parent)
 
        a = new QHBoxLayout;    o->addLayout(a);
        l = new QLabel(tr("Data name"));        a->addWidget(l);
-       char buf[32];   snprintf(buf,32,"mgl_%d",numDataOpened);
+       char buf[32];   snprintf(buf,32,"mgl_%d",numDataOpened);        buf[31]=0;
        name = new QLineEdit(buf,this);         a->addWidget(name);
 
        rA = new QRadioButton(tr("Auto detect data sizes"), this);
@@ -114,7 +114,8 @@ void DataOpenDialog::prepareResult()
 {
        code = "";      numDataOpened++;        data = name->text();
        // prepare unique value of name for next time
-       char buf[32];   snprintf(buf,32,"mgl_%d",numDataOpened);        name->setText(buf);
+       char buf[32];   snprintf(buf,32,"mgl_%d",numDataOpened);
+       buf[31]=0;      name->setText(buf);
        mglData *v = parser.AddVar(data.toStdString().c_str());
        int dd=0;
        if(rA->isChecked())     //      auto sizes
index 582d95082ee7e62cf074c51ca4433aa95816358e..3565b805ad61a3d5eaa0b2e2349defb695164282 100755 (executable)
@@ -5,6 +5,7 @@ Terminal=false
 Icon=udav
 Name=UDAV
 Exec=udav
+MimeType=text/mgl;
 Comment=Data handling and plotting tool
 Comment[en_US]=Data handling and plotting tool
 Comment[ru_RU]=Обработка и отображение данных
index f3e04af6574e73d2bec68dc181b8752b0b7df426..3cfa9ec949891930ab67b83b5196417eaec9cd2d 100644 (file)
@@ -100,6 +100,11 @@ int main(int argc, char **argv)
        // try to fix possible multi-threading errors
        // must be placed before ANY window creation
        XInitThreads();
+#endif
+#ifdef WIN32
+       char buf[512];  getcwd(buf,500);        strcat(buf,"\\plugins\\");
+       QCoreApplication::addLibraryPath(buf);
+       QCoreApplication::addLibraryPath("c:\\plugins\\");
 #endif
        mgl_ask_func = mgl_ask_qt;
        QApplication a(argc, argv);
index 6f5382caa6d5bf035086adb4fc4e578866e52411..5e293fdb7d691bd27bea0559de38977cbd390ecf 100644 (file)
@@ -133,7 +133,7 @@ int main(int argc, char *argv[])
                        p.Execute(&gr,str.c_str());\r
                        if(gr.Message()[0])     printf("%s\n",gr.Message());\r
                        gr.EndFrame();\r
-                       snprintf(buf,2048,"%s-%ld",oname,i);\r
+                       snprintf(buf,2048,"%s-%ld",oname,i);    buf[2047]=0;\r
                        if(!gif)        gr.WriteFrame(buf);\r
                }\r
                if(gif) gr.CloseGIF();\r
index 688feb5defefb81497b5fe196e8824a5bf8d8070..f6a18ae3f37f9adfe4659af8d9bb9e14b68f10df 100644 (file)
@@ -197,7 +197,7 @@ int Fl_MathGL::handle(int code)
                        mglPoint p = gr->CalcXYZ(Fl::event_x()-x(), Fl::event_y()-y());
                        if(g)   g->LastMousePos = p;
                        char s[128];
-                       snprintf(s,128,"x=%g, y=%g, z=%g",p.x,p.y,p.z);
+                       snprintf(s,128,"x=%g, y=%g, z=%g",p.x,p.y,p.z); s[127]=0;
                        draw(); fl_color(FL_BLACK);             fl_draw(s,40,70);
                }
        }
@@ -717,10 +717,9 @@ void mglCanvasFL::Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p
                Adjust();
        }
 
-       char *tmp[1];   tmp[0]=new char[1];     tmp[0][0]=0;
-       Wnd->show(argv ? argc:0, argv ? argv:tmp);
-       delete []tmp[0];
-}
+       static char ctmp[1];    ctmp[0]=0;
+       static char *tmp[1];    tmp[0]=ctmp;
+       Wnd->show(argv ? argc:0, argv ? argv:tmp);}
 //-----------------------------------------------------------------------------
 HMGL MGL_EXPORT mgl_create_graph_fltk(int (*draw)(HMGL gr, void *p), const char *title, void *par, void (*load)(void *p))
 {
index a95fa6e82e769e83a2b938b8ee1c1471b451c7aa..8633e959389f8491f26e8244015edc30588fae24 100644 (file)
@@ -150,25 +150,25 @@ void _mgl_key_up(unsigned char ch,int ,int )
        {\r
                char str[128];\r
                snprintf(str,128,"%s_%d.png",_mgl_glwnd->PlotId.c_str(),_mgl_glwnd->curr_fig);\r
-               mgl_write_png(_mgl_glwnd, str, "Math GL");\r
+               str[127]=0;     mgl_write_png(_mgl_glwnd, str, "MathGL");\r
        }\r
        if(ch=='J')\r
        {\r
                char str[128];\r
                snprintf(str,128,"%s_%d.jpg",_mgl_glwnd->PlotId.c_str(),_mgl_glwnd->curr_fig);\r
-               mgl_write_jpg(_mgl_glwnd, str, "Math GL");\r
+               str[127]=0;     mgl_write_jpg(_mgl_glwnd, str, "MathGL");\r
        }\r
        if(ch=='E')\r
        {\r
                char str[128];\r
                snprintf(str,128,"%s_%d.eps",_mgl_glwnd->PlotId.c_str(),_mgl_glwnd->curr_fig);\r
-               mgl_write_eps(_mgl_glwnd, str, "Math GL");\r
+               str[127]=0;     mgl_write_eps(_mgl_glwnd, str, "MathGL");\r
        }\r
        if(ch=='S')\r
        {\r
                char str[128];\r
                snprintf(str,128,"%s_%d.svg",_mgl_glwnd->PlotId.c_str(),_mgl_glwnd->curr_fig);\r
-               mgl_write_svg(_mgl_glwnd, str, "Math GL");\r
+               str[127]=0;     mgl_write_svg(_mgl_glwnd, str, "MathGL");\r
        }\r
        if(ch==' ')     _mgl_glwnd->Clf();\r
        if(ch=='m')     _mgl_glwnd->tt = 1-_mgl_glwnd->tt;\r
index 298edcb6f6f889f821cf45bab67fe15a775d17b5..c2e2f92bdbce84f7ecace7e92e73a5e4bf0ff249 100644 (file)
@@ -339,7 +339,7 @@ void QMathGL::afterPlot()
 //-----------------------------------------------------------------------------
 void QMathGL::drawPrim()
 {
-//     mgl_clf_nfog(gr);
+       if(!gr) return;
        mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);
        mgl_get_frame(gr, g?g->GetCurFig():mgl_get_num_frame(gr)-1);
        mglParse pr;
@@ -397,7 +397,7 @@ void QMathGL::refreshHQ()
                        else            mgl_view(gr,-phi,-tet,0);
                }
        }
-       mglConvertFromGraph(pic, gr, &grBuf);
+       mglConvertFromGraph(pic, gr, &grBuf, &img);
        if(pic.size()!=size())  setSize(pic.width(), pic.height());
        repaint();
 }
@@ -663,28 +663,48 @@ void QMathGL::exportGIF(QString fname)
 {
        if(fname.isEmpty())     fname = mgl_get_plotid(gr);
        if(fname.isEmpty())     QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0);
-       else    mgl_write_gif(gr,setExtension(fname,"png").toStdString().c_str(), appName.toStdString().c_str());
+       else
+#if MGL_HAVE_GIF
+               mgl_write_gif(gr,setExtension(fname,"png").toStdString().c_str(), appName.toStdString().c_str());
+#else
+               img.save(setExtension(fname,"gif"));
+#endif
 }
 //-----------------------------------------------------------------------------
 void QMathGL::exportPNG(QString fname)
 {
        if(fname.isEmpty())     fname = mgl_get_plotid(gr);
        if(fname.isEmpty())     QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0);
-       else    mgl_write_png(gr,setExtension(fname,"png").toStdString().c_str(), appName.toStdString().c_str());
+       else
+#if MGL_HAVE_PNG
+               mgl_write_png(gr,setExtension(fname,"png").toStdString().c_str(), appName.toStdString().c_str());
+#else
+               img.save(setExtension(fname,"png"));
+#endif
 }
 //-----------------------------------------------------------------------------
 void QMathGL::exportPNGs(QString fname)
 {
        if(fname.isEmpty())     fname = mgl_get_plotid(gr);
        if(fname.isEmpty())     QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0);
-       else    mgl_write_png_solid(gr,setExtension(fname,"png").toStdString().c_str(), appName.toStdString().c_str());
+       else
+#if MGL_HAVE_PNG
+               mgl_write_png_solid(gr,setExtension(fname,"png").toStdString().c_str(), appName.toStdString().c_str());
+#else
+               img.save(setExtension(fname,"png"));
+#endif
 }
 //-----------------------------------------------------------------------------
 void QMathGL::exportJPG(QString fname)
 {
        if(fname.isEmpty())     fname = mgl_get_plotid(gr);
        if(fname.isEmpty())     QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0);
-       else    mgl_write_jpg(gr,setExtension(fname,"jpg").toStdString().c_str(), appName.toStdString().c_str());
+       else
+#if MGL_HAVE_JPEG
+               mgl_write_jpg(gr,setExtension(fname,"jpg").toStdString().c_str(), appName.toStdString().c_str());
+#else
+               img.save(setExtension(fname,"jpg"));
+#endif
 }
 //-----------------------------------------------------------------------------
 void QMathGL::exportBPS(QString fname)
@@ -831,7 +851,7 @@ void QMathGL::exportMGLD(QString fname)
        }
 }
 //-----------------------------------------------------------------------------
-void mglConvertFromGraph(QPixmap &pic, mglCanvas *gr, uchar **buf)
+void mglConvertFromGraph(QPixmap &pic, mglCanvas *gr, uchar **buf, QImage *out)
 {
        const uchar *bb = mgl_get_rgb(gr);
        register long i,w=mgl_get_width(gr), h=mgl_get_height(gr);
@@ -845,6 +865,7 @@ void mglConvertFromGraph(QPixmap &pic, mglCanvas *gr, uchar **buf)
                (*buf)[4*i+3] = 255;
        }
        QImage img(*buf, w, h, QImage::Format_RGB32);
+       if(out) *out = img;
        pic = QPixmap::fromImage(img);
 }
 //-----------------------------------------------------------------------------