diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 17917b9d9d7..f8283198124 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -144,7 +144,7 @@ jobs: # make install -j - name: Configure and compile MNE-CPP run: | - ../Qt5_binaries/bin/qmake -r MNECPP_CONFIG+=noTests MNECPP_CONFIG+=noExamples MNECPP_CONFIG+=static + ../Qt5_binaries/bin/qmake -r MNECPP_CONFIG+=noTests MNECPP_CONFIG+=noExamples MNECPP_CONFIG+=static MNECPP_CONFIG+=withAppBundles make -j make install -j - name: Deploy binaries @@ -339,7 +339,7 @@ jobs: make install - name: Configure and compile MNE-CPP run: | - qmake -r MNECPP_CONFIG+=noTests MNECPP_CONFIG+=noExamples MNECPP_CONFIG+=withBrainFlow MNECPP_CONFIG+=withLsl + qmake -r MNECPP_CONFIG+=noTests MNECPP_CONFIG+=noExamples MNECPP_CONFIG+=withBrainFlow MNECPP_CONFIG+=withLsl MNECPP_CONFIG+=withAppBundles make -j4 - name: Deploy binaries (MacOS) run: | diff --git a/.gitignore b/.gitignore index c487d79d49f..445bc464b06 100644 --- a/.gitignore +++ b/.gitignore @@ -65,4 +65,19 @@ Makefile mne-cpp.pro.user* # FFTW -/include/3rdParty/fftw \ No newline at end of file +/include/3rdParty/fftw + +# Documentation +/doc/pdf/*.aux +/doc/pdf/*.bbl +/doc/pdf/*.blg +/doc/pdf/*.fdb_latexmk +/doc/pdf/*.fls +/doc/pdf/*.log +/doc/pdf/*.out +/doc/pdf/*.toc +/doc/pdf/*.gz +/doc/pdf/*.pdf + + + diff --git a/doc/gh-pages/blabla.md b/doc/gh-pages/blabla.md new file mode 100644 index 00000000000..b7158049947 --- /dev/null +++ b/doc/gh-pages/blabla.md @@ -0,0 +1,14 @@ + +--- +title: Home +has_children: true +nav_order: 1 +--- + +# The MNE-CPP Project + +![A framework for electrophysiology](images/partners.png) + + + +MNE-CPP is a cross-platform, open-source framework which offers a variety of software tools to the neuroscientific research community. We provide applications for the acquisition and processing of MEG/EEG data, both in real-time and offline. All applications are built on top of our cross-platform library which is available via an API and can be used to develop new tools. \ No newline at end of file diff --git a/doc/gh-pages/pages/documentation/analyze_coregistration.md b/doc/gh-pages/pages/documentation/analyze_coregistration.md index 1d13c5b797e..e4d7895a7f6 100644 --- a/doc/gh-pages/pages/documentation/analyze_coregistration.md +++ b/doc/gh-pages/pages/documentation/analyze_coregistration.md @@ -11,7 +11,7 @@ This plugin lets you co-register your subject's BEM-files with a digitizer set o The following sections will show you how to use the plugin and introduce good practice. -![](../../images/analyze/mne_an_coreg.png) +![MNE Analyze Coregistration plugin.](../../images/analyze/mne_an_coreg.png) ## Prerequisites diff --git a/doc/gh-pages/pages/download/changelog.md b/doc/gh-pages/pages/download/changelog.md index 5abe1e90345..aedf0a4cc37 100644 --- a/doc/gh-pages/pages/download/changelog.md +++ b/doc/gh-pages/pages/download/changelog.md @@ -44,594 +44,3 @@ Disp * Made updateFilterPlot public in FilterDesignView * Text color in the FilterPlotScene class is now dependant on the FilterDesignView colors, dependent on the Qt stylesheet -Disp3D - * Fix applying the same rotation animation on the parent and children of a Renderable3DEntity. - * Make use of parallel animation starting via QParallelAnimationGroup - * Orbit camera instead of rotating objects in 3D view - -RtProcessing - * Changed enums in FilterKernel to static class members of new FilterParameter class and replaced static functions - -### Continuous Integration - - * Update CI to use Qt 5.15.2, which solves a problem with Qt3D on MacOS - * Remove setting the noOpenGLWidget flag when Qt version is > 5.15.0 to fix signal plotting in macOs - * Add scripts (/tools/testing) and outsource calling of tests from CI so devs can run tests locally more easily. - * Make test_win powershell script callable from anywhere - -### Documentation - - * fixed some layout issues in the changelog - * fixed website page links with wrong path - * Docu fixes in Renderable3DEntity - * Add CI testing documentation to contribution guide - * Update eegosports docu - * Include more about event system and using event system when creating plugin - * Update E-Mail addresses in the contact page - * Reorganize and restructure webpage - - ### Authors - - People who contributed to this release (preceded by number of commits): - -(89) Juan GPC, -(49) Gabriel Motta, -(22) Simon Heinke, -(17) Lorenz Esch, -(10) Alex Rockhill - -## Version 0.1.8 - 2020/11/19 - -### Applications - -MNE Analyze - * Moved View3D controls to settings view - * New event and struct for sending settings - * Fix GUI spacing in averaging plugin - * New Dipole Fit plugin for MNE Analyze - * Loading new files: *trans.fif, *cov-fif - * New data models for dipole fit, mri transform, noise - * Website documentation for new plugin - * loading *ave.fif without raw file parent - -MNE Scan - * Remove no longer needed applications/mne_analyze/libs/anShared/Interfaces/IStandardView.h - * Remove no longer needed applications/mne_analyze/libs/anShared/Management/analyzesettings.cpp - * Rename interfaces to abstract classes, since they are described better as abstract classes - * Improve Babymeg plugin to feature connection GUI elements. Also fix some bugs which led to crashing when - connecting to the acquisition boards. - * Update include path of ui_ files - * Rename data function in measurement classes to measurementData() since QSharedPointer already has a data() function. - * Comment out set_current_comp function in noise plugin since this lead to multiple calls and errors when bit wise shifting the coil type. - * Add error catching when channels are empty in HPIFit's fitHPI function - * Update dummy toolbox pro and source/header files - * Bump up BrainFlow version - * Make clustering in the MNE Scan forward solution plugin the default - -MNE RtServer - * Add file command line argument - -### API librariers - -Disp3D - * Fix fiducial coloring problem in Disp3D - * Change fiducial colors to match the ones of mne-python - * Add remove option to context menu (right click) in the Control3DView. Subsequently, the 3D data is removed from the 3D data model and view - -Disp - * New Dipole Fit View. - -### Continuous Integration - - * Cleanup qmake files for transition to cmake (Qt6 only supports cmake) - * Move deployment to CI - * Outsource deployment commands to scripts - * Update ubuntu runners - * Update dropbox links - * Update mne-cpp-test-data submodule to newest commit - * Create new static deployment scripts - * Use linuxdeployqt for linux static builds as well - * Fix mnecpp library copying on macos. - * Fix mkdir in windows workflow. - * Add testci workflow script which allows convenient CI testing without actually creating a GH PR - * Fix setting PATH variable via the now deprecated add-path in GH Actions scripts - * Remove hub install action in release.yml since HUB CLI is already a part of all runners. - * Release macOS dynamic build based on Qt 5.14.2. This should fix QOpenGlWidget problems. - -### Documentation - - * Update resource and dependency documentation - * Update settings plugin documentation to include 3D controls - * Update deployment documentation - * Renamed website section Install to Download - * Website section Contribute is now a subsection of Develop - * Link download links on our website to always point to dynamic versions - * Update documentation for the real-time source localization pipeline - -### Other - - * Make building without app bundles on macOS the default (can be reverted by using the new flag withAppBundles) - * Fix Wasm problems introduced by PR #713 (View3D controls in control manager plugin) - * Cleanup mne-cpp.pri file - * Move resources folder back to bin folder to reduce complexity in the qmake/cmake files - * Add @executable_path to rpath setup when building for macOS. (can start the executable from the explorer) - -### Authors - -People who contributed to this release (preceded by number of commits): - -(52) Lorenz Esch, -(48) Gabriel Motta, -(1) Andrey Parfenov - -## Version 0.1.7 - 2020/10/26 - -### Applications - -MNE Analyze - * Add new plugin to perform source localization in MNE Analyze. This is just the skeleton of the plugin and is not functional yet. - * Add new plugin to perform 3D visualization. This plugin provides a Disp3D View3D window in a QWidget container The data can be passed to the plugin via MNE Analyze's event subscription system. - * Fixes to Channel Select plugin (preserve state in-between sessions, change default layouts) - * Create control plugin and merge functionality with scaling plugin - * Increased max visible channels in Signal Viewer plugin to 100 - * Added AveragingDataModel which stores averaging data - * Ability to add and switch between averaging data using the Data Manager - * Add loading bar with corresponding message - * Move trigger detection to a new thread in order to not block the application - * Split View menu into new View and Control menus - * Block EventManager run() with semaphore - * UsedProgressView class which displays loading bar and message when loading/saving models to files - * Mutithreaded Averaging + Trigger detect calculations - * Co-Registration plugin - * AnalyzeDataModel, DataManagerControlView are now BidsViewModel, BidsView - * Reworked hierarchy of stored items in model to fit bids. Items now hold their own place in structure - * Added session, and data type folders to view - * Move sessions between subjects, move data between sessions - * Loading .eve files - * Loading -ave.fif files - * Add item for annotation model in bidsviewmodel - * reworked instantiation and handling of annotationmodel (no longer crated in fiffrawviewmodel) - -MNE Scan - * Improved impedance measurement in Eegosports plugin - * Use a toolbar for each view using the same control mechanism actions (channel slection view, hide/show bad channels) - * Rename Filter plugin to Noise plugin - -### API Libraries - -All - * Remove some no longer needed compiler flags in library .pro files - -Disp - * Added ProgressView class which displays loading bar and message - * Make 2D layout scene in ChannelSelectionView fill free GUI space - * Make ScalingView hide scaling sliders of chnnel types which are not present in the actual data - -Disp3D - * Add support for vertex picking - -Fiff - * Add write functionality to FiffCoordTrans - * Add convenience function to FiffInfoBase to return present channel types as QStringList - -Utils - * Remove dll export/import for circular buffer typenames - -### Tests - - * Add read write read test for FiffCoordTrans - * Add MNEProjectToSurface test - -### Continuous Integration - - * Bump CI Qt version to Qt 5.15.1 - -### Documentation - - * Add guide on how to install the MNE Sample Data Set - * Added page on the event system - * Added page on creating data models - -### Other - - * Fix rpath on macos builds - * Fix Qt3D renderer plugin deployment on macos - * Rename noOpenGL flag to noQOpenGLWidget flag - -### Authors - -People who contributed to this release (preceded by number of commits): - -(141) Gabriel Motta, -(119) Ruben Dörfel, -(27) Lorenz Esch, -(2) Johannes Vorwerk, -(1) Andrey Parfenov - -## Version 0.1.6 - 2020/08/21 - -### Applications - -MNE Analyze - * Add cmd line argument support for file loading - * Add channel selection plugin - * Remove channel selection in averaging plugin - * Add scaling plugin - * Add example plugin - -MNE Scan - * Remove no longer needed recording icons and move them to the write to file plugin instead - * Remove no longer needed readme.txt in some of the plugins' resources - -### API Libraries - -Disp - * Move *Apply to View* from channel selection to library layer to be used by both channel selection and scaling - -RtProcessing - * Add performIcp() namespace function to register a point cloud with a surface - * Add fitMatchedPoints() namespace function to register two point clouds of same size using ICP and quaternions - * Add discard3DPointOutliers() namespace function to discard outliers from digitizer set compared to a given 3D surface - -Utils - * Rename IOBUFFER to UTILSLIB namespace - * Remove circularbuffer.cpp file since it was empty - -### Documentation - * Add documentation for MNE Analyze channel selection plugin - * Add documentation for Disp3D library - * Add documentation for connectivity library - * Add documentation for MNE Analyze scaling plugin - * Add documentation for plugin creation in MNE Analyze - * Restructure static and dynamic build guides - * Rename .md page files to better indicate what subject they belong to - * Rename documentation pages for MNE Scan, MNE Analyze and MNE Anonymize - * Rename MNE Lib to library API - * Improve DoxyGen docu by making use of namespaces for MNE-C types - * Improve documentation for MNE Scan eeg amplifiers and fix some typos - * Hide Learn pages for MNE Dipole Fit and MNE Forward Solution for now (until they have been completley refactored) - -### Authors - -People who contributed to this release (preceded by number of commits): - -(47) Gabriel Motta, -(47) Ruben Dörfel, -(16) Lorenz Esch - -## Version 0.1.5 - 2020/07/30 - -### Applications - -MNE Analyze - * Refactored DataManagerView to DataManagerControlView. - * Added a break case to switch statement in datamanager.cpp. - * Added triggerdetectview to Event plugin. - * Added functionality to Event plugin to create event groups by type and sort detected events. - * Tweaked/added get/set functions dealing with event groups. - * Added functionality to Averaging plugin to read events from user-selected event group. - * Added jump to event to right click menu. - * Changed key event to keyReleaseEvent in Event plugin to avoid event being accepted elsewhere. - * FiffRawView now inherits from AbstractView. - * Window size and number of channels preserved while resizing window. - * Fix data plotting when scrolling to the left (raw and filtering). Fixed a problem where the current fiff curser of the beginning data block was substracted by the filter delay even if filtering was disabled. - * Remove filterAllData function and replace usage by reloadAllData, which leads to an performance improvement. - * Rename updateDisplayData to reloadAllData. - * Comment out some qInfo outputs. - * Rename getWindowSizeBlocks to getTotalBlockCount in FiffRawViewModel. - * Disable downsampling when plotting since it introduced aliasing effects. Performance is not affected by this change. - -### API Libraries - -Disp - * Added offline mode functionality to triggerdetectview. - * Added event group selection to offline mode in averagingsettingsview. - -RtProcessing - * Remove data copies when filtering in order to speed up filtering. - -### Documentation - - * Update MNE Analyze docu. - * Update MNE Scan HPI and forward plugin docu. - -### Authors - -People who contributed to this release (preceded by number of commits): - -(34) Gabriel Motta, -(13) Ruben Dörfel, -(11) Lorenz Esch, -(2) Wayne Mead - -## Version 0.1.4 - 2020/07/07 - -### Applications - -MNE Analyze -* Add filter support. The user can now select/design a filter. If activated the filter is applied to the data as the user scrolls through the file. When activated the filtered data is also written to file and applied when computing an average. -* Add dark mode support to WASM version. -* Corrected saving/loading views inbetween sessions. -* Adjusted minimum allowed window size. -* Add support for computing averages/evoked responses. -* Closing main window now calls destructors for views in dockwidgets. -* Add support to delete loaded files from the data manager. -* Speed up data browsing by decreasing the pre loading buffer size to two blocks. -* Fix vertically overlapping signal plotting. -* Move AnalyzeDataModel to anshared/model folder. -* Annotations have been renamed to Events. -* Added Event Group functionality and struct. -* Event Groups can be renamed or have their color changed through right click context menu. -* Events can now be deleted from selecting any of the columns, double click to edit columns. -* Fixed bug where check boxes changing annotation model state were not updating the view. - -MNE Scan -* Update inverse operator if new forward solution was calculated. -* Update brainflow submodule for the brainflowboard plugin. - -Examples -* Add a new example for averaging. -* Change ex_read_epochs to only read epochs without averaging afterwards. - -MNE Anonymize -* Add GUI mode. -* Add WASM version. -* Improve internal memory handling. - -### API Libraries - -Utils -* Move filter methods/classes to the RtProcessing library. -* Move DetectTrigger class to the RtProcessing library. -* Refactor baseline correction input from QPair to QPair. - -RtProcessing -* Refactor header guards of all RtProcessing classes. -* Add function to set updated forward solution in RtInv. -* Rename RtFilter to Filter and FilterData to FilterKernel. -* Improve automatic slicing of data when filtering. -* Separate continous and one time overlap add filtering methods. Make some functions global RTPROCESSINGLIB namespace functions and was therefore removed. -* Remove processing of multiple filters at once. This feature was never really implemented. -* Rename RtAve to RtAveraging. -* Add new averaging functions. -* Implement convenience function in DetectTrigger to transform between detect trigger QMaps and MNE event matrices. -* Move detect trigger functions to global RTPROCESSINGLIB namespace. - -Disp -* Refactor plotting of the filter's frequency response in the FilterPlotScene class. -* Fix saving/loading from FilterDesignView, FilterSettingsView and FiffRawView. -* Changed signal view control widget scaling to allow for window sizes. -* Remove filtering from EvokedSetModel in disp library. Filtering on short data lengths such as most epochs is difficult because of the edge effects. Filtering for epochs/evoked responses should happen before with appropriate filter lengths which is now supported by the RTPROCESSINGLIB::computeFilteredAverage() function. -* Improve the ScalingView with new default scaling values and convenience functions to retrieve the scale value for a given scale map and channel kind/unit. Make use of the new functions throughout MNE-CPP libraries and applications. - -### Documentation - -* Add averaging plugin documentation page. -* Update MNE Anonymize documentation page. - -### Other - -* Remove minimal version flag and corresponding CI build. This mode was needed to be able to build on the older Neuromag systems. Since we switched to the fieldtrip buffer, this mode is no longer needed. - -### Authors - -People who contributed to this release (preceded by number of commits): - -(156) Juan Garcia-Prieto, -(76) Gabriel Motta, -(60) Lorenz Esch, -(6) Ruben Dörfel, -(2) Wayne Mead, -(2) Andrey Parfenov - -## Version 0.1.3 - 2020/06/05 - -### Applications - -MNE Analyze -* Add new AnalyzeDataModel, which allows subject based data organization. -* Improve data loading from QByteArray in AnalyzeData. -* Log Window now has location preserved between sessions. -* Files once again get selected and displayed automatically when first loaded. -* Disconnect everything from old model before loading new one. This solves performance issues when loading multiple files. -* Signal Viewer and Annotation settings scale depending on available size. -* Add different GUI modes (scientific and clinical) to appearance menu. -* Add dark and light mode to appearance menu. -* Include skeleton of new Filtering plugin in MNE Analyze. Please note that the actual filtering is still WIP and will follow in a future version. - -MNE Scan -* Update Brainflow plugin. -* Separated real-time source localization and forward calculation into two plugins. -* Recalculate forward solution if large head movement occurred. -* Fix thread safety in real-time source localization plugin. -* Save plugin pipeline in MNE Scan more often and everytime we start the pipeline. -* Beautify HPI plugin control settings view. -* Add different GUI modes (scientific and clinical) to appearance menu. -* Add dark and light mode to appearance menu. - -### API Libraries - -Disp -* Add new view for controlling the forward calculation. -* Make plugin tab bar show vertically in the Quick Control View. -* Create an abstract interface AbstractView for all Disp library viewers to enforce handling different GUI modes and the saving/loading of GUI settings. -* Refactor saving/settings of Disp viewers. -* Improve FilterSettingsView and add different GUI elements based on the currently set GUI mode. For example, scientific mode will enable advanced filter design tools, whereas in clinical mode only the lower and upper cut off frequencies can be defined. -* Move CovarianceSettingsView from MNE Scan's Covariance plugin to Disp/viewers. - -Disp3D -* Add temporary fix on Windows for the Disp3D library and Qt 5.15.0 where the renderers plugin is deployed manually. This will be reverted once Qt 5.15.1 is released. - -### Authors - -People who contributed to this release (preceded by number of commits): - -(64) Ruben Dörfel, -(51) Lorenz Esch, -(16) Gabriel Motta, -(2) Andrey Parfenov, -(1) Juan Garcia-Prieto - -## Version 0.1.2 - 2020/05/21 - -### Applications - -MNE Analyze: -* Fix application icon on Linux. -* Add timing labels below the signal viewer. -* Fix deployment of internal MNE Analyze libraries on Windows. -* Change list data model to child/parent item data model in AnalyzeData. -* Rename AnnotationView to AnnotationSettingsView. -* Update splashcreen to show full application name. -* Refactor RawDataViewer plugin. The controls are no longer destroyed when a different file is selected. This led to some visible glitches when switching between files. -* Do not allow floating or movable dock widgets in the WASM version. The QDockWidget behavior is a bit buggy in the current Qt WASM versions. -* Use QOpenGLWidget instead of QOGLWidget. The latter is marked as deprecated. -* Remember dock states and sizes inbetween MNE Analyze sessions. - -MNE Scan: -* Fix application icon on Linux. -* Fix deployment of internal MNE Scan libraries on Windows. -* Fix bug when receiving evoked data in source localization plugin. -* Update splashcreen to show full application name. - -### API libraries - -Disp: -* Remember dock states and sizes inbetween sessions in the MultiView. - -Inverse: -* Fix versioning bug. - -### Documentation - -* Minor improvements and typo fixes. - -### Authors - -People who contributed to this release (preceded by number of commits): - -(42) Lorenz Esch, -(9) Gabriel Motta, -(5) Juan Garcia-Prieto, -(1) Ruben Dörfel - -## Version 0.1.1 - 2020/05/14 - -### Applications - -MNE Analyze: -* Fix bug during deployment of dynamically linked MNE Analyze version on macOS. -* Renamed MNE Analyze extensions to plugins. -* Fix issue with display width, now displays only full seconds as selected. -* Jump viewer to selected annotation with 'J' key. -* Removed seemingly unused timer debug outputs. -* Documentations and variable name changes for readability. -* Add plugin control views to menu bar. -* Clean up command line output. -* Add time information on the y-axis. - -MNE Scan: -* Fix problems with Source Localization and Connectivity plugins. -* Fix problems where the QuickControlView was not populated with plugin control GUI widgets correctly. - -MNE Anonymize: -* Overall improvements and bug fixes to MNE Anonymize. - -### API libraries - -All: -* Rename libraries and fix versioning. - -Fiff: -* Fix bug when reading gantry_angle from Fiff file. - -### Tools -* Fix template class in Qt Creator wizard for MNE-CPP classes. -* Update test and example Qt Creator wizards. - -### Continuous Integration -* Only branch off when a minor or major version bump occurred. -* Remove folders which we do not want to ship from dynamic builds. - -### Documentation -* Updated information on continuous integration. -* Improved build from source guide. -* Updated guide on streaming pre-recorded data in MNE Scan. - -### Authors - -People who contributed to this release (preceded by number of commits): - -(115) Juan Garcia-Prieto, -(43) Lorenz Esch, -(7) Gabriel Motta, -(2) Ruben Dörfel, - -## Version 0.1.0 - 2020/05/04 - -### Changes - -New applications: - -* **MNE Scan** including new plugins: fiffsimulator, ftbuffer, babymeg, natus, brainamp, eegosports, gusbamp, tmsi, brainflowboard, lsladapter, dummytoolbox, rtcmne, averaging, covariance, noisereduction, neuronalconnectivity, writetofile, hpi -* **MNE Analyze** including new plugins: dataloader, datamanager, rawdataviewer, annotationmanager -* **MNE Rt Server** -* **MNE Forward Solution** -* **MNE Dipole Fit** - -New API libraries: - -* **utils** - Design patterns, generlaized classes, mathematical routines, I/O helpers -* **fs** - FreeSurfer I/O routines -* **fiff** - Fiff I/O routines -* **mne** - I/O routines for MNE objects -* **fwd** - Forward modeling -* **inverse** - Inverse modeling -* **communication** - Tools for real-time communication -* **rtprocessing** - Tools for real-time data processing -* **connectivity** - Functional connectivity metrics -* **disp** - 2D visualization routines -* **disp3D** - 3D visualization routines - -### Authors - -People who contributed to this release (preceded by number of commits): - -(3118) Lorenz Esch, -(2264) Christoph Dinh, -(384) Gabriel Motta, -(275) Ruben Doerfel, -(253) Lars Debor, -(160) Juan Garcia-Prieto, -(149) Viktor Klueber, -(113) Jana Kiesel, -(107) Ricky Tjen, -(105) Martin Henfling, -(92) Limin Sun, -(71) Daniel Knobl, -(69) Florian Schlembach, -(61) Daniel Strohmeier, -(56) Simon Heinke, -(37) Andrey Parfenov, -(35) Tim Kunze, -(31) Wayne Mead, -(24) Felix Arndt, -(16) Louise Eichhorst, -(13) Seok Lew, -(11) Christof Pieloth, -(9) Felix Griesau, -(9) Chiran Doshi, -(8) Robert Dicamillo, -(6) Johannes Vorwerk, -(6) Erik Hornberger, -(6) Sugandha Sachdeva, -(5) Faris Yahya, -(4) Blerta Hamzallari, -(4) Marco Klamke, -(4) Julius Lerm, -(3) Mainak Jas, -(3) Franco Polo, -(3) Benjamin Kay, -(3) Petros Simidyan, -(2) Martin Luessi, -(2) Eric Larson diff --git a/doc/gh-pages/pages/download/changelog_PROCESSED.md b/doc/gh-pages/pages/download/changelog_PROCESSED.md new file mode 100644 index 00000000000..f814737a9f6 --- /dev/null +++ b/doc/gh-pages/pages/download/changelog_PROCESSED.md @@ -0,0 +1,56 @@ +--- +title: Changelog +parent: Download +nav_exclude: true +--- + +# Changelog + +## Version 0.1.9 - 2021/03/02 + +### Applications + +MNE Analyze +\begin{itemize} + \item Handle removal and deletion of child item models + \item Add event for model removal + \item Changed event documentation format + \item Gave AnalyzeData a communicator to send events + \item Implemented clearing of views in plugins that use models + \item Data Loader now saves last folder data was loaded from. + \item Code cleanup to fix some compiler warnings and memory leaks + \item Show file and filter info in signal viewer. +\end{itemize} + +MNE Anonymize +\begin{itemize} + \item Fix bug when anonymizing dates + \item Update date command line option + \item Fix link to documentation web page + \item Use QDate instead of QDateTime when referring to birthday date + \item add console to CONFIG in pro file +\end{itemize} + +MNE Scan +\begin{itemize} + \item Change saving to file to account for calibration values when saving data +\end{itemize} + +EDF-To-Fiff Converter +\begin{itemize} + \item Added edf to fiff converter command line application +\end{itemize} + +### API librariers + +Disp +\begin{itemize} + \item Added clearView() function to AbstractView + \item Change default loaded values for ScalingView and FiffRawViewSettings + \item Made FilterSettingsView and FilterDesignView reflect filter parameter changes made in each other + \item Fix updating filter parameters in FilterDesignView after loading filter from file + \item Update scaling of FilterDesignView plotting and removed scroll bars. + \item Made updateFilterPlot public in FilterDesignView + \item Text color in the FilterPlotScene class is now dependant on the FilterDesignView colors, dependent on the Qt stylesheet +\end{itemize} + diff --git a/doc/pdf/Chrysanthemum.jpg b/doc/pdf/Chrysanthemum.jpg new file mode 100644 index 00000000000..757c2a628dd Binary files /dev/null and b/doc/pdf/Chrysanthemum.jpg differ diff --git a/doc/pdf/References.bib b/doc/pdf/References.bib new file mode 100644 index 00000000000..256a72650d5 --- /dev/null +++ b/doc/pdf/References.bib @@ -0,0 +1,187 @@ +@patent{wilkinson_1990, + author = {J. P. Wilkinson}, + title = {Nonlinear resonant circuit devices}, + address = {United States}, + number = {3 624 125}, + day = {16}, + month = {aug}, + year = {1990}, +} +@techreport{SP80053r4, + author = {{Joint Task Force Transformation Initiative Interagency Working Group}}, + title = {Security and Privacy Controls for Federal Information Systems and Organizations}, + institution = {National Institute of Standards and Technology}, + address= {Gaithersburg, MD}, + number = {NIST Special Publication (SP) 800-53, Rev. 4, Includes updates as of January 22, 2015}, + DOI = {10.6028/NIST.SP.800-53r4}, + year = {2013}, +} +@techreport{FIPS1402, + author = {{National Institute of Standards and Technology}}, + title = {Security Requirements for Cryptographic Modules}, + institution = {U.S. Department of Commerce}, + address= {Washington, D.C.}, + number = {Federal Information Processing Standards Publications (FIPS PUBS) 140-2, Change Notice 2 December 03, 2002}, + DOI = {10.6028/NIST.FIPS.140-2}, + year = {2001}, +} +@ARTICLE{Xiong2015, + author={H. Xiong}, + journal={Chinese Journal of Electronics}, + title={Multi-level Bell-Type Inequality from Information Causality and Noisy Computations}, + year={2015}, + volume={24}, + number={2}, + pages={408-413}, + keywords={communication complexity;probability;quantum communication;quantum computing;NS-box;RAC;Tsirelson bounds;communication complexity;independent identically distribution;information causality;multilevel Bell-type inequality;no-signaling box;noisy computations;nonlocal quantum computation;random access code;symmetric quantum channels;uniform input marginal probabilities}, + doi={10.1049/cje.2015.04.031}, + ISSN={1022-4653}, + month={},} + + +@ARTICLE{Prives2016, + author={L. Prives}, + journal={IEEE Women in Engineering Magazine}, + title={For Whom the Bell Tolls: Inventing success through creativity and analytical skills [WIE from Around the World]}, + year={2016}, + volume={10}, + number={1}, + pages={37-39}, + keywords={Creativity;Education;Engineering profession;Media;Technological innovation}, + doi={10.1109/MWIE.2016.2535841}, + ISSN={1942-065X}, + month={June},} + +@ARTICLE{Roberts1982, + author={L. J. Roberts}, + journal={SMPTE Journal}, + title={Cameras and Systems: A History of Contributions from the Bell; Howell Co. (Part I)}, + year={1982}, + volume={91}, + number={10}, + pages={934-946}, + doi={10.5594/J00229}, + ISSN={0036-1682}, + month={Oct},} + +@INPROCEEDINGS{Maloney2016, + author={T. J. Maloney}, + booktitle={38th Electrical Overstress/Electrostatic Discharge Symposium (EOS/ESD)}, + title={Unified model of 1-D pulsed heating, combining Wunsch-Bell with the Dwyer curve: This paper is co-copyrighted by Intel Corporation and the ESD association}, + year={2016}, + pages={1-8}, + keywords={electrostatic discharge;heat sinks;heat transfer;integrated circuit modelling;1-D pulsed heating;Dwyer curve;Wunsch-Bell relation;heat flow;power-to-fail curves;Analytical models;Convolution;Heat sinks;Impedance;Resistance heating;Steady-state}, + doi={10.1109/EOSESD.2016.7592562}, + volume=22, + publisher={Publisher name, location}, + month={Sept},} + +@book{giancoli2008physics, + title={Physics for Scientists and Engineers with Modern Physics}, + author={Giancoli, D.C.}, + isbn={9780131495081}, + lccn={2006039431}, + pages = {123-124}, + edition = {4}, + year={2008}, + publisher={Pearson Education} +} + +@inbook{Eston1993, + author = {Peter Eston}, + title = {Book section title}, + pages = {201-213}, + chapter = {8}, + publisher = {The name of the publisher}, + address = {The address of the publisher}, + year = {1993}, + volume = {4}, + edition = {3}, + month = {7}, +} + +@TECHREPORT{MSU-CSE-06-2, + AUTHOR = {R. Behrends and L. K. Dillon and S. D. Fleming and + R. E. K. Stirewalt}, + TITLE = {White paper: Programming according to the fences and gates + model for developing assured, secure software + systems}, + NUMBER = {MSU-CSE-06-2}, + INSTITUTION = {Department of Computer Science, Michigan State University}, + ADDRESS = {East Lansing, Michigan}, + ABSTRACT = {This white paper describes extensions to our work on the + Synchronization Units Model (Szumo) to address the + access-control problem in systems assembled dynamically from + trusted and untrusted components. Our extension employs + explicitly declared design contracts, the semantics of which + are founded on Landwehr's model of fences and gates. + }, + KEYWORDS = {access control, security, contracts, Szumo}, + NOTE = {}, + MONTH = {January}, + YEAR = {2006}, + AUTHOR1_URL = {http://www.poker-ping.info}, + AUTHOR1_EMAIL = {kel@wondering-jons.com}, + AUTHOR1_URL = {}, + AUTHOR1_EMAIL = {behrends@cse.msu.edu}, + AUTHOR2_URL = {Sle}, + AUTHOR2_EMAIL = {Poker Ping}, + AUTHOR2_URL = {http://www.cse.msu.edu/~stire}, + AUTHOR2_EMAIL = {stire@cse.msu.edu}, + PAGES = {3}, + FILE = {/user/web/htdocs/publications/tech/TR/MSU-CSE-06-2.ps}, + DOI = {}, + CONTACT = {stire@cse.msu.edu} +} + + +@incollection{Farindon, + author = {Peter Farindon}, + title = {The title of the collection section}, + booktitle = {The title of the book}, + publisher = {The name of the publisher}, + year = {1993}, + editor = {Firstname Lastname}, + volume = {4}, + chapter = {8}, + pages = {201-213}, + address = {The address of the publisher}, + edition = {3}, + month = {7}, + DOI = {} +} + +@unpublished{Marcheford, + author = {Peter Marcheford}, + title = {The title of the unpublished work}, + month = {7}, + year = {1993} +} + +@phdthesis{Joslin, + author = {Peter Joslin}, + title = {The title of the PhD Thesis}, + school = {The school of the thesis}, + year = {1993}, + address = {The address of the publisher}, + month = {7}, + note = {An optional note} +} +@booklet{Caxton, + title = {The title of the booklet}, + author = {Peter Caxton}, + howpublished = {How it was published}, + address = {The address of the publisher}, + month = {7}, + year = {1993}, + note = {An optional note} +} + + +@misc{Isley, + author = {Peter Isley}, + title = {The title of the webpage}, + month = {7}, + year = {1993}, + url = {https://nist.gov} +} \ No newline at end of file diff --git a/doc/pdf/doc.tex b/doc/pdf/doc.tex new file mode 100644 index 00000000000..08fd723e809 --- /dev/null +++ b/doc/pdf/doc.tex @@ -0,0 +1,294 @@ +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% This document is a heavily modified version of the +% NIST Technical report developed by K. Miller, kmm5@nist.gov +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\documentclass[12pt, twoside]{article} +\usepackage{amsmath} +\usepackage{amsfonts} % if you want the fonts +\usepackage{amssymb} % if you want extra symbols +\usepackage{graphicx} % need for figures +\usepackage{xcolor} +\usepackage{bm} +\usepackage{secdot} +\usepackage{mathptmx} +\usepackage{float} +\usepackage[utf8]{inputenc} +\usepackage{textcomp} +\usepackage[hang,flushmargin,bottom]{footmisc} % footnote format +\usepackage{fancyhdr} +\usepackage[useregional]{datetime2} +\usepackage{blindtext} +\pagestyle{fancy} + +\usepackage{titlesec} +\titleformat{\section}{\normalsize\bfseries}{\thesection.}{1em}{} % required for heading numbering style +\titleformat*{\subsection}{\normalsize\bfseries} + +\usepackage{tocloft} % change typeset, titles, and format list of appendices/figures/tables +\renewcommand{\cftdot}{} +\renewcommand{\contentsname}{Table of Contents} +\renewcommand{\cftpartleader}{\cftdotfill{\cftdotsep}} % for parts +\renewcommand{\cftsecleader}{\cftdotfill{\cftdotsep}} +\renewcommand\cftbeforesecskip{\setlength{4pt}{}} +\addtolength{\cftfignumwidth}{1em} +\renewcommand{\cftfigpresnum}{\figurename\ } +\addtolength{\cfttabnumwidth}{1em} +\renewcommand{\cfttabpresnum}{\tablename\ } +\setlength{\cfttabindent}{0in} %% adjust as you like +\setlength{\cftfigindent}{0in} + +\usepackage{enumitem} % to control spacing between bullets/numbered lists + +\usepackage[numbers,sort&compress]{natbib} % format bibliography +\renewcommand{\bibsection}{} +\setlength{\bibsep}{0.0pt} + +\usepackage{hyperref} +\hypersetup{ + colorlinks = true, + urlcolor = {blue}, + % linkbordercolor = {blue} + % urlbordercolor = {blue} + % citebordercolor = {blue} + % pdfborderstyle = {/S/U/W 1} + citecolor = {.}, + linkcolor = {blue}, + anchorcolor = {.}, + filecolor = {.}, + menucolor = {.}, + runcolor = {.} + pdftitle={}, + pdfsubject={}, + pdfauthor={}, + pdfkeywords={} +} +\urlstyle{same} + +\usepackage{epstopdf} % converting EPS figure files to PDF + +\usepackage{fancyhdr, lastpage} % formatting document, calculating number of pages, formatting headers +\setlength{\topmargin}{-0.5in} +\setlength{\headheight}{35pt} +\setlength{\oddsidemargin}{0.25in} +\setlength{\evensidemargin}{0.25in} +\setlength{\textwidth}{6.0in} +\setlength{\textheight}{8.5in} + +\usepackage{caption} % required for Figure labels +\captionsetup{font=small,labelfont=bf,figurename=Fig.,labelsep=period,justification=raggedright} + +\pdfminorversion=7 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\setcounter{secnumdepth}{3} +\newcommand{\versionnumber}{0.1.9} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Document +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{document} +\urlstyle{rm} % Format style of \url + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Title +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{titlepage} +\begin{figure} +\begin{tabular}{@{}l@{}} +\includegraphics[width=25cm]{mne-cpp_logo_notext.png} +\end{tabular} +\end{figure} + + +\begin{flushright} +\vspace{12pt} +\vfill +\LARGE{\textbf{MNE-CPP Project}} \\ + +\Huge{\textbf{User and Developer Documentation}} \\ +\Huge{\textbf{Version \versionnumber}} \\ +% \vfill +\vspace{20pt} +\LARGE{Date: \today} \\ +\vfill +% \large Lorenz Esch \\ +% \large Gabriel Motta \\ +% \large Juan Garcia-Prieto \\ +% \vspace{12pt} +% \textit{Athinoula A. Martinos Center for Biomedical Imaging}\\ +% \textit{Department of Radiology, Massachusetts General Hospital}\\ +% \textit{Harvard Medical School}\\ +% \textit{Boston, MA} +% \vspace{12pt} +% \vfill + + +\end{flushright} +\end{titlepage} +\let\cleardoublepage\clearpage + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Disclamer - Information page +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{titlepage} +\noindent \normalsize This document has been generated automatically. \\ +It is a printable version of the \href{https://mne-cpp.github.io}{MNE-CPP Project documentation web page}\footnote{https://mne-cpp.github.io}. +\vfill +\noindent\normalsize \textbf{MNE Toolbox and the applications contained in the project are available free of charge.} \\ +\vfill +\noindent +\footnotesize \noindent \textbf{Terms of Use: Certain commercial entities, equipment, or materials may be identified in this document in order to describe an experimental procedure or concept adequately. Such identification is not intended to imply recommendation or endorsement by the National Institute of Standards and Technology, nor is it intended to imply that the entities, materials, or equipment are necessarily the best available for the purpose.}\\ +\vfill +\footnotesize License terms... +\vfill +\end{titlepage} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Inspirational Quote +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{titlepage} +\begin{flushright} +\vspace*{\fill} +\noindent\normalsize\textbf{If the tools are good, nature will give a clear answer to a clear question.} \\ +\textit{Dyson F (1999) The Sun, the Genome, the Internet. \\Oxford University Press, New York} \\ +\vspace*{\fill} +\end{flushright} +\end{titlepage} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\fancyhf{} +\fancyhead[LE]{\includegraphics[width=4cm]{mne-cpp_logo.png}} +\fancyhead[CE]{Version: \versionnumber} +\fancyhead[RE]{\today} +\fancyhead[LO]{\nouppercase\leftmark} +\fancyhead[RO]{\nouppercase\rightmark} +\renewcommand{\subsectionmark}[1]{\markright{\thesubsection\ #1}} +\setlength\headheight{26pt} +\fancyheadoffset{0cm} + +\fancyfoot[LE,RO]{\thepage} + +% \section*{Foreword} +% \pagenumbering{roman} +% \normalsize Delete if not applicable\\ +% \section*{Preface} +% \normalsize Delete if not applicable\\ +% \section*{Abstract} +% \normalsize Required\\ +% \section*{Key words} +% \normalsize Required, alphabetized, separated by semicolon, and end in a period.\\ +% \pagebreak + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Table of Contents - Glossary +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +{ + \hypersetup{linkcolor=black} + \tableofcontents + \vfill + \pagebreak + % \listoftables + % \pagebreak + % \listoffigures + % \pagebreak + \section*{Glossary} + \pagebreak +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Start body of text - page number starts with "1" +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\part{HOME} +\label{sec:intro} +MNE-CPP is a cross-platform, open-source framework which offers a variety of software tools to the neuroscientific research community. We provide applications for the acquisition and processing of MEG/EEG data, both in real-time and offline. All applications are built on top of our cross-platform library which is available via an API and can be used to develop new tools. +\blindtext[2] +\section{SectionA}\label{sec:SectionA} +\blindtext[3] +This can be seen in Eq. (1) and Table 1 \cite{Roberts1982}. Information about flowers is available in Sec.~\ref{sec:intro}.\footnote{NIST disclaimer text here.} + +% \begin{equation} +% {x}^{n} + {y}^{n} = {z}^{n} +% \end{equation} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Equation references are “Eq. (X)��. +% “Equation (1) is used at beginning of sentence. +% Equations are numbered (#) on the right, per the standard LaTeX format +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{SubsectionAX}\label{ssec:subsectionAX} +\blindtext[5] +\subsection{SubsectionAY}\label{ssec:subsectionAY} +\blindtext[2] +\subsubsection{SubsubsectionY}\label{ssec:subsubsectionY} +\blindtext[2] + + +\begin{table}[H] + \centering + \caption{Title.} + \small + \begin{tabular}{cc} + \hline + ColumnA & ColumnB \\ \hline + text & text{\scriptsize $^{\rm a}$} \\ + text & text \\ + text & text \\ + text & text \\ + \hline + \end{tabular} + + {\footnotesize {\scriptsize $^{\rm a}$}Footnote} +\end{table} + +\section{Section2}\label{ssec:section2} +\blindtext[2] +\subsection{Section2SubsectionX}\label{ssec:section2subsectionx} +\subsubsection{SubsubsectionZ}\label{ssec:subsubsectionZ} +\blindtext[3] + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Tables should appear after they are mentioned in the text. +% Superscripted letters (a, b, c, etc.) should be used for table footnotes. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{figure}[h] + \centering \includegraphics[width=0.5\linewidth]{Chrysanthemum.jpg} + \caption{This is the caption text.} + \label{fig:Chrysanthemum} +\end{figure} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Figure references are “Fig. X��. +% “Figure X�� is used at beginning of sentence. +% Figures should appear after they are mentioned in the text. +% Figures must have embedded alternate text or “alt text�� in order +% to comply with Section 508 accessibility standards. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsubsection{SubsubsectionX}\label{ssec:subsubsectionX2} +\blindtext[2] + + +\part{References} +% \addcontentsline{toc}{section}{References} +\bibliographystyle{techpubs} +\bibliography{References} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Please use the techpubs BibTeX style when compiling bibliography, or follow the instructions on tinyurl.com/techpubsnist to format your .bib / .bbl file appropriately. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% \section*{Appendix A: Supplemental Materials} +% \addcontentsline{toc}{section}{Appendix A: Supplemental Materials} +% Brief description of supplemental files\\ + +% \section*{Appendix B: Change Log} +% \addcontentsline{toc}{section}{Appendix B: Change Log} +% If updating document with errata, detail changes made to document – delete if not applicable. \\ + +\end{document} diff --git a/doc/pdf/mne-cpp_logo.png b/doc/pdf/mne-cpp_logo.png new file mode 100644 index 00000000000..2e58e0faf84 Binary files /dev/null and b/doc/pdf/mne-cpp_logo.png differ diff --git a/doc/pdf/mne-cpp_logo_notext.png b/doc/pdf/mne-cpp_logo_notext.png new file mode 100644 index 00000000000..f8871debc41 Binary files /dev/null and b/doc/pdf/mne-cpp_logo_notext.png differ diff --git a/doc/pdf/mnecpp_doc.tex b/doc/pdf/mnecpp_doc.tex new file mode 100644 index 00000000000..91dd010dc78 --- /dev/null +++ b/doc/pdf/mnecpp_doc.tex @@ -0,0 +1,207 @@ +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% This document is a heavily modified version of the +% NIST Technical report developed by K. Miller, kmm5@nist.gov +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\documentclass[12pt, twoside]{article} +\usepackage{amsmath} +\usepackage{amsfonts} % if you want the fonts +\usepackage{amssymb} % if you want extra symbols +\usepackage{graphicx} % need for figures +\usepackage{xcolor} +\usepackage{bm} +\usepackage{secdot} +\usepackage{mathptmx} +\usepackage{float} +\usepackage[utf8]{inputenc} +\usepackage{textcomp} +\usepackage[hang,flushmargin,bottom]{footmisc} % footnote format +\usepackage{fancyhdr} +\usepackage[useregional] {datetime2} +\usepackage{blindtext} +\pagestyle{fancy} + +\usepackage{titlesec} +\titleformat{\section}{\normalsize\bfseries}{\thesection.}{1em}{} % required for heading numbering style +\titleformat*{\subsection}{\normalsize\bfseries} + +\usepackage{tocloft} % change typeset, titles, and format list of appendices/figures/tables +\renewcommand{\cftdot}{} +\renewcommand{\contentsname}{Table of Contents} +\renewcommand{\cftpartleader}{\cftdotfill{\cftdotsep}} % for parts +\renewcommand{\cftsecleader}{\cftdotfill{\cftdotsep}} +\renewcommand\cftbeforesecskip{\setlength{4pt}{}} +\addtolength{\cftfignumwidth}{1em} +\renewcommand{\cftfigpresnum}{\figurename\ } +\addtolength{\cfttabnumwidth}{1em} +\renewcommand{\cfttabpresnum}{\tablename\ } +\setlength{\cfttabindent}{0in} %% adjust as you like +\setlength{\cftfigindent}{0in} + +\usepackage{enumitem} % to control spacing between bullets/numbered lists + +\usepackage[numbers,sort&compress]{natbib} % format bibliography +\renewcommand{\bibsection}{} +\setlength{\bibsep}{0.0pt} + +\usepackage{hyperref} +\hypersetup{ + colorlinks = true, + urlcolor = {blue}, + % linkbordercolor = {blue} + % urlbordercolor = {blue} + % citebordercolor = {blue} + % pdfborderstyle = {/S/U/W 1} + citecolor = {.}, + linkcolor = {blue}, + anchorcolor = {.}, + filecolor = {.}, + menucolor = {.}, + runcolor = {.} + pdftitle={}, + pdfsubject={}, + pdfauthor={}, + pdfkeywords={} +} +\urlstyle{same} + +\usepackage{epstopdf} % converting EPS figure files to PDF + +\usepackage{fancyhdr, lastpage} % formatting document, calculating number of pages, formatting headers +\setlength{\topmargin}{-0.5in} +\setlength{\headheight}{35pt} +\setlength{\oddsidemargin}{0.25in} +\setlength{\evensidemargin}{0.25in} +\setlength{\textwidth}{6.0in} +\setlength{\textheight}{8.5in} + +\usepackage{caption} % required for Figure labels +\captionsetup{font=small,labelfont=bf,figurename=Fig.,labelsep=period,justification=raggedright} + +\pdfminorversion=7 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\setcounter{secnumdepth}{3} +\newcommand{\versionnumber}{0.1.9} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Document +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{document} +\urlstyle{rm} % Format style of \url + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Title +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{titlepage} +\begin{figure} +\begin{tabular}{@{}l@{}} +\includegraphics[width=25cm]{mne-cpp_logo_notext.png} +\end{tabular} +\end{figure} + + +\begin{flushright} +\vspace{12pt} +\vfill +\LARGE{\textbf{MNE-CPP Project}} \\ + +\Huge{\textbf{User and Developer Documentation}} \\ +\large{Version: \versionnumber} \\ +\large{Date: \today} \\ +\vfill +\large Lorenz Esch \\ +\large Gabriel Motta \\ +\large Juan Garcia-Prieto \\ +\vspace{12pt} +\textit{Athinoula A. Martinos Center for Biomedical Imaging}\\ +\textit{Department of Radiology, Massachusetts General Hospital}\\ +\textit{Harvard Medical School}\\ +\textit{Boston, MA} +\vspace{12pt} +\vfill + + +\end{flushright} +\end{titlepage} +\let\cleardoublepage\clearpage + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Disclamer - Information page +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{titlepage} +\noindent \normalsize This document has been generated automatically. \\ +It is a printable version of the \href{https://mne-cpp.github.io}{\underline{MNE-CPP Project documentation web page}}\footnote{https://mne-cpp.github.io}. +\vfill +\noindent\normalsize \textbf{MNE Toolbox and the applications contained in the project are available free of charge.} \\ +\vfill +\noindent +\footnotesize \noindent \textbf{Terms of Use: Certain commercial entities, equipment, or materials may be identified in this document in order to describe an experimental procedure or concept adequately. Such identification is not intended to imply recommendation or endorsement by the National Institute of Standards and Technology, nor is it intended to imply that the entities, materials, or equipment are necessarily the best available for the purpose.}\\ +\vfill +\footnotesize License terms... +\vfill +\end{titlepage} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Inspirational Quote +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{titlepage} +\begin{flushright} +\vspace*{\fill} +\noindent\normalsize\textbf{If the tools are good, nature will give a clear answer to a clear question.} \\ +\textit{Dyson F (1999) The Sun, the Genome, the Internet. \\Oxford University Press, New York} \\ +\vspace*{\fill} +\end{flushright} +\end{titlepage} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\fancyhf{} +\fancyhead[LE]{\includegraphics[width=4cm]{mne-cpp_logo.png}} +\fancyhead[CE]{Version: \versionnumber} +\fancyhead[RE]{\today} +\fancyhead[LO]{\nouppercase\leftmark} +\fancyhead[RO]{\nouppercase\rightmark} +\renewcommand{\subsectionmark}[1]{\markright{\thesubsection\ #1}} +\setlength\headheight{26pt} +\fancyheadoffset{0cm} + +\fancyfoot[LE,RO]{\thepage} + +% \section*{Foreword} +% \pagenumbering{roman} +% \normalsize Delete if not applicable\\ +% \section*{Preface} +% \normalsize Delete if not applicable\\ +% \section*{Abstract} +% \normalsize Required\\ +% \section*{Key words} +% \normalsize Required, alphabetized, separated by semicolon, and end in a period.\\ +% \pagebreak + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Table of Contents - Glossary +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +{ + \hypersetup{linkcolor=black} + \tableofcontents + \vfill + \pagebreak + % \listoftables + % \pagebreak + % \listoffigures + % \pagebreak + \section*{Glossary} + \pagebreak +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Start body of text - page number starts with "1" +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/doc/pdf/mnecpp_doc_template.tex b/doc/pdf/mnecpp_doc_template.tex new file mode 100644 index 00000000000..91dd010dc78 --- /dev/null +++ b/doc/pdf/mnecpp_doc_template.tex @@ -0,0 +1,207 @@ +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% This document is a heavily modified version of the +% NIST Technical report developed by K. Miller, kmm5@nist.gov +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\documentclass[12pt, twoside]{article} +\usepackage{amsmath} +\usepackage{amsfonts} % if you want the fonts +\usepackage{amssymb} % if you want extra symbols +\usepackage{graphicx} % need for figures +\usepackage{xcolor} +\usepackage{bm} +\usepackage{secdot} +\usepackage{mathptmx} +\usepackage{float} +\usepackage[utf8]{inputenc} +\usepackage{textcomp} +\usepackage[hang,flushmargin,bottom]{footmisc} % footnote format +\usepackage{fancyhdr} +\usepackage[useregional] {datetime2} +\usepackage{blindtext} +\pagestyle{fancy} + +\usepackage{titlesec} +\titleformat{\section}{\normalsize\bfseries}{\thesection.}{1em}{} % required for heading numbering style +\titleformat*{\subsection}{\normalsize\bfseries} + +\usepackage{tocloft} % change typeset, titles, and format list of appendices/figures/tables +\renewcommand{\cftdot}{} +\renewcommand{\contentsname}{Table of Contents} +\renewcommand{\cftpartleader}{\cftdotfill{\cftdotsep}} % for parts +\renewcommand{\cftsecleader}{\cftdotfill{\cftdotsep}} +\renewcommand\cftbeforesecskip{\setlength{4pt}{}} +\addtolength{\cftfignumwidth}{1em} +\renewcommand{\cftfigpresnum}{\figurename\ } +\addtolength{\cfttabnumwidth}{1em} +\renewcommand{\cfttabpresnum}{\tablename\ } +\setlength{\cfttabindent}{0in} %% adjust as you like +\setlength{\cftfigindent}{0in} + +\usepackage{enumitem} % to control spacing between bullets/numbered lists + +\usepackage[numbers,sort&compress]{natbib} % format bibliography +\renewcommand{\bibsection}{} +\setlength{\bibsep}{0.0pt} + +\usepackage{hyperref} +\hypersetup{ + colorlinks = true, + urlcolor = {blue}, + % linkbordercolor = {blue} + % urlbordercolor = {blue} + % citebordercolor = {blue} + % pdfborderstyle = {/S/U/W 1} + citecolor = {.}, + linkcolor = {blue}, + anchorcolor = {.}, + filecolor = {.}, + menucolor = {.}, + runcolor = {.} + pdftitle={}, + pdfsubject={}, + pdfauthor={}, + pdfkeywords={} +} +\urlstyle{same} + +\usepackage{epstopdf} % converting EPS figure files to PDF + +\usepackage{fancyhdr, lastpage} % formatting document, calculating number of pages, formatting headers +\setlength{\topmargin}{-0.5in} +\setlength{\headheight}{35pt} +\setlength{\oddsidemargin}{0.25in} +\setlength{\evensidemargin}{0.25in} +\setlength{\textwidth}{6.0in} +\setlength{\textheight}{8.5in} + +\usepackage{caption} % required for Figure labels +\captionsetup{font=small,labelfont=bf,figurename=Fig.,labelsep=period,justification=raggedright} + +\pdfminorversion=7 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\setcounter{secnumdepth}{3} +\newcommand{\versionnumber}{0.1.9} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Document +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{document} +\urlstyle{rm} % Format style of \url + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Title +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{titlepage} +\begin{figure} +\begin{tabular}{@{}l@{}} +\includegraphics[width=25cm]{mne-cpp_logo_notext.png} +\end{tabular} +\end{figure} + + +\begin{flushright} +\vspace{12pt} +\vfill +\LARGE{\textbf{MNE-CPP Project}} \\ + +\Huge{\textbf{User and Developer Documentation}} \\ +\large{Version: \versionnumber} \\ +\large{Date: \today} \\ +\vfill +\large Lorenz Esch \\ +\large Gabriel Motta \\ +\large Juan Garcia-Prieto \\ +\vspace{12pt} +\textit{Athinoula A. Martinos Center for Biomedical Imaging}\\ +\textit{Department of Radiology, Massachusetts General Hospital}\\ +\textit{Harvard Medical School}\\ +\textit{Boston, MA} +\vspace{12pt} +\vfill + + +\end{flushright} +\end{titlepage} +\let\cleardoublepage\clearpage + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Disclamer - Information page +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{titlepage} +\noindent \normalsize This document has been generated automatically. \\ +It is a printable version of the \href{https://mne-cpp.github.io}{\underline{MNE-CPP Project documentation web page}}\footnote{https://mne-cpp.github.io}. +\vfill +\noindent\normalsize \textbf{MNE Toolbox and the applications contained in the project are available free of charge.} \\ +\vfill +\noindent +\footnotesize \noindent \textbf{Terms of Use: Certain commercial entities, equipment, or materials may be identified in this document in order to describe an experimental procedure or concept adequately. Such identification is not intended to imply recommendation or endorsement by the National Institute of Standards and Technology, nor is it intended to imply that the entities, materials, or equipment are necessarily the best available for the purpose.}\\ +\vfill +\footnotesize License terms... +\vfill +\end{titlepage} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Inspirational Quote +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{titlepage} +\begin{flushright} +\vspace*{\fill} +\noindent\normalsize\textbf{If the tools are good, nature will give a clear answer to a clear question.} \\ +\textit{Dyson F (1999) The Sun, the Genome, the Internet. \\Oxford University Press, New York} \\ +\vspace*{\fill} +\end{flushright} +\end{titlepage} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\fancyhf{} +\fancyhead[LE]{\includegraphics[width=4cm]{mne-cpp_logo.png}} +\fancyhead[CE]{Version: \versionnumber} +\fancyhead[RE]{\today} +\fancyhead[LO]{\nouppercase\leftmark} +\fancyhead[RO]{\nouppercase\rightmark} +\renewcommand{\subsectionmark}[1]{\markright{\thesubsection\ #1}} +\setlength\headheight{26pt} +\fancyheadoffset{0cm} + +\fancyfoot[LE,RO]{\thepage} + +% \section*{Foreword} +% \pagenumbering{roman} +% \normalsize Delete if not applicable\\ +% \section*{Preface} +% \normalsize Delete if not applicable\\ +% \section*{Abstract} +% \normalsize Required\\ +% \section*{Key words} +% \normalsize Required, alphabetized, separated by semicolon, and end in a period.\\ +% \pagebreak + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Table of Contents - Glossary +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +{ + \hypersetup{linkcolor=black} + \tableofcontents + \vfill + \pagebreak + % \listoftables + % \pagebreak + % \listoffigures + % \pagebreak + \section*{Glossary} + \pagebreak +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Start body of text - page number starts with "1" +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/doc/pdf/techpubs.bst b/doc/pdf/techpubs.bst new file mode 100644 index 00000000000..4ce8ee56d8a --- /dev/null +++ b/doc/pdf/techpubs.bst @@ -0,0 +1,1493 @@ +%% +%% This is file `jresnistdoi01.bst', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% merlin.mbs (with options: `seq-no,vonx,nm-rvx,ed-rev,jnrlst,mcite,mct-1,mct-x5,dt-beg,yr-par,xmth,yrp-x,jxper,pp-last,num-xser,numser,ser-vol,ser-ed,jnm-x,pub-par,pre-pub,doi,edparxc,edby,edbyx,blk-com,com-blank,blknt,in-x,pp,ed,ord,jabr,xand,etal-xc,revdata,eprint,url,url-blk,nfss,') +%% ---------------------------------------- +%% *** BibTeX style for J Res NIST, with DOI entries *** +%% +%% Copyright 1994-2011 Patrick W Daly +% =============================================================== +% IMPORTANT NOTICE: +% This bibliographic style (bst) file has been generated from one or +% more master bibliographic style (mbs) files, listed above. +% +% This generated file can be redistributed and/or modified under the terms +% of the LaTeX Project Public License Distributed from CTAN +% archives in directory macros/latex/base/lppl.txt; either +% version 1 of the License, or any later version. +% =============================================================== +% Name and version information of the main mbs file: +% \ProvidesFile{merlin.mbs}[2011/11/18 4.33 (PWD, AO, DPC)] +% For use with BibTeX version 0.99a or later +%------------------------------------------------------------------- +% This bibliography style file is intended for texts in ENGLISH +% This is a numerical citation style, and as such is standard LaTeX. +% It requires no extra package to interface to the main text. +% The form of the \bibitem entries is +% \bibitem{key}... +% Usage of \cite is as follows: +% \cite{key} ==>> [#] +% \cite[chap. 2]{key} ==>> [#, chap. 2] +% where # is a number determined by the ordering in the reference list. +% The order in the reference list is that by which the works were originally +% cited in the text, or that in the database. +%--------------------------------------------------------------------- + +ENTRY +{ address +archive +author +booktitle +chapter +collaboration +doi +edition +editor +eid +eprint +howpublished +institution +journal +key +month +note +number +numpages +organization +pages +publisher +school +series +title +type +url +volume +year +} +{} +{ label } +INTEGERS { output.state before.all mid.sentence after.sentence after.block } +FUNCTION {init.state.consts} +{ #0 'before.all := +#1 'mid.sentence := +#2 'after.sentence := +#3 'after.block := +} +STRINGS { s t} +FUNCTION {output.nonnull} +{ 's := +output.state mid.sentence = +{ " " * write$ } +{ output.state after.block = +{ add.period$ write$ +newline$ +"\newblock " write$ +} +{ output.state before.all = +'write$ +{ add.period$ " " * write$ } +if$ +} +if$ +mid.sentence 'output.state := +} +if$ +s +} +FUNCTION {output} +{ duplicate$ empty$ +'pop$ +'output.nonnull +if$ +} +FUNCTION {output.check} +{ 't := +duplicate$ empty$ +{ pop$ "empty " t * " in " * cite$ * warning$ } +'output.nonnull +if$ +} +FUNCTION {fin.entry} +{ doi empty$ +{ add.period$ } +{ } +if$ +write$ +newline$ +} + +FUNCTION {new.block} +{ output.state before.all = +'skip$ +{ after.block 'output.state := } +if$ +} +FUNCTION {new.sentence} +{ output.state after.block = +'skip$ +{ output.state before.all = +'skip$ +{ after.sentence 'output.state := } +if$ +} +if$ +} +FUNCTION {add.blank} +{ " " * before.all 'output.state := +} + +FUNCTION {date.block} +{ +add.blank +} + +FUNCTION {not} +{ { #0 } +{ #1 } +if$ +} +FUNCTION {and} +{ 'skip$ +{ pop$ #0 } +if$ +} +FUNCTION {or} +{ { pop$ #1 } +'skip$ +if$ +} +STRINGS {z} + +FUNCTION {remove.dots} +{ 'z := +"" +{ z empty$ not } +{ z #1 #2 substring$ +duplicate$ "\." = +{ z #3 global.max$ substring$ 'z := * } +{ pop$ +z #1 #1 substring$ +z #2 global.max$ substring$ 'z := +duplicate$ "." = 'pop$ +{ * } +if$ +} +if$ +} +while$ +} +FUNCTION {new.block.checka} +{ empty$ +'skip$ +'new.block +if$ +} +FUNCTION {new.block.checkb} +{ empty$ +swap$ empty$ +and +'skip$ +'new.block +if$ +} +FUNCTION {new.sentence.checka} +{ empty$ +'skip$ +'new.sentence +if$ +} +FUNCTION {new.sentence.checkb} +{ empty$ +swap$ empty$ +and +'skip$ +'new.sentence +if$ +} +FUNCTION {field.or.null} +{ duplicate$ empty$ +{ pop$ "" } +'skip$ +if$ +} +FUNCTION {emphasize} +{ duplicate$ empty$ +{ pop$ "" } +{ "\emph{" swap$ * "}" * } +if$ +} +FUNCTION {tie.or.space.prefix} +{ duplicate$ text.length$ #3 < +{ "~" } +{ " " } +if$ +swap$ +} + +FUNCTION {capitalize} +{ "u" change.case$ "t" change.case$ } + +FUNCTION {space.word} +{ " " swap$ * " " * } +% Here are the language-specific definitions for explicit words. +% Each function has a name bbl.xxx where xxx is the English word. +% The language selected here is ENGLISH +FUNCTION {bbl.and} +{ "and"} + +FUNCTION {bbl.etal} +{ "et~al." } + +FUNCTION {bbl.editors} +{ "eds" } + +FUNCTION {bbl.editor} +{ "ed" } + +FUNCTION {bbl.edby} +{ "edited by" } + +FUNCTION {bbl.edition} +{ "Ed." } + +FUNCTION {bbl.volume} +{ "Vol." } + +FUNCTION {bbl.of} +{ "of" } + +FUNCTION {bbl.number} +{ "number" } + +FUNCTION {bbl.nr} +{ "no." } + +FUNCTION {bbl.in} +{ "in" } + +FUNCTION {bbl.pages} +{ "pp" } + +FUNCTION {bbl.page} +{ "p" } + +FUNCTION {bbl.eidpp} +{ "pages" } + +FUNCTION {bbl.chapter} +{ "Chapter" } + +FUNCTION {bbl.techrep} +{ "" } + +FUNCTION {bbl.patent} +{ "Patent" } + +FUNCTION {bbl.mthesis} +{ "Master's thesis" } + +FUNCTION {bbl.phdthesis} +{ "Ph.D. thesis." } + +FUNCTION {bbl.first} +{ "1st" } + +FUNCTION {bbl.second} +{ "2nd" } + +FUNCTION {bbl.third} +{ "3rd" } + +FUNCTION {bbl.fourth} +{ "4th" } + +FUNCTION {bbl.fifth} +{ "5th" } + +FUNCTION {bbl.st} +{ "st" } + +FUNCTION {bbl.nd} +{ "nd" } + +FUNCTION {bbl.rd} +{ "rd" } + +FUNCTION {bbl.th} +{ "th" } + +MACRO {jan} {"January"} + +MACRO {feb} {"February"} + +MACRO {mar} {"March"} + +MACRO {apr} {"April"} + +MACRO {may} {"May"} + +MACRO {jun} {"June"} + +MACRO {jul} {"July"} + +MACRO {aug} {"August"} + +MACRO {sep} {"September"} + +MACRO {oct} {"October"} + +MACRO {nov} {"November"} + +MACRO {dec} {"December"} + +FUNCTION {eng.ord} +{ duplicate$ "1" swap$ * +#-2 #1 substring$ "1" = +{ bbl.th * } +{ duplicate$ #-1 #1 substring$ +duplicate$ "1" = +{ pop$ bbl.st * } +{ duplicate$ "2" = +{ pop$ bbl.nd * } +{ "3" = +{ bbl.rd * } +{ bbl.th * } +if$ +} +if$ +} +if$ +} +if$ +} + +MACRO {acmcs} {"ACM Comput. Surv."} + +MACRO {acta} {"Acta Inf."} + +MACRO {cacm} {"Commun. ACM"} + +MACRO {ibmjrd} {"IBM J. Res. Dev."} + +MACRO {ibmsj} {"IBM Syst.~J."} + +MACRO {ieeese} {"IEEE Trans. Software Eng."} + +MACRO {ieeetc} {"IEEE Trans. Comput."} + +MACRO {ieeetcad} +{"IEEE Trans. Comput. Aid. Des."} + +MACRO {ipl} {"Inf. Process. Lett."} + +MACRO {jacm} {"J.~ACM"} + +MACRO {jcss} {"J.~Comput. Syst. Sci."} + +MACRO {scp} {"Sci. Comput. Program."} + +MACRO {sicomp} {"SIAM J. Comput."} + +MACRO {tocs} {"ACM Trans. Comput. Syst."} + +MACRO {tods} {"ACM Trans. Database Syst."} + +MACRO {tog} {"ACM Trans. Graphic."} + +MACRO {toms} {"ACM Trans. Math. Software"} + +MACRO {toois} {"ACM Trans. Office Inf. Syst."} + +MACRO {toplas} {"ACM Trans. Progr. Lang. Syst."} + +MACRO {tcs} {"Theor. Comput. Sci."} + +FUNCTION {bibinfo.check} +{ swap$ +duplicate$ missing$ +{ +pop$ pop$ +"" +} +{ duplicate$ empty$ +{ +swap$ pop$ +} +{ swap$ +pop$ +} +if$ +} +if$ +} +FUNCTION {bibinfo.warn} +{ swap$ +duplicate$ missing$ +{ +swap$ "missing " swap$ * " in " * cite$ * warning$ pop$ +"" +} +{ duplicate$ empty$ +{ +swap$ "empty " swap$ * " in " * cite$ * warning$ +} +{ swap$ +pop$ +} +if$ +} +if$ +} +FUNCTION {format.eprint} +{ eprint duplicate$ empty$ +'skip$ +{ "\eprint" +archive empty$ +'skip$ +{ "[" * archive * "]" * } +if$ +"{" * swap$ * "}" * +} +if$ +} +FUNCTION {format.url} +{ +url +duplicate$ empty$ +{ pop$ "" } +{ "\urlprefix\url{" swap$ * "}" * } +if$ +} + +INTEGERS { nameptr namesleft numnames } + + +STRINGS { bibinfo} + +FUNCTION {format.names} +{ 'bibinfo := +duplicate$ empty$ 'skip$ { +'s := +"" 't := +#1 'nameptr := +s num.names$ 'numnames := +numnames 'namesleft := +{ namesleft #0 > } +{ s nameptr +"{vv~}{ll}{ f{}}{ jj}" +format.name$ +remove.dots +bibinfo bibinfo.check +'t := +nameptr #1 > +{ +nameptr #1 +#1 + = +numnames #99 +> and +{ "others" 't := +#1 'namesleft := } +'skip$ +if$ +namesleft #1 > +{ ", " * t * } +{ +s nameptr "{ll}" format.name$ duplicate$ "others" = +{ 't := } +{ pop$ } +if$ +"," * +t "others" = +{ +" " * bbl.etal * +} +{ " " * t * } +if$ +} +if$ +} +'t +if$ +nameptr #1 + 'nameptr := +namesleft #1 - 'namesleft := +} +while$ +} if$ +} +FUNCTION {format.names.ed} +{ +format.names +} +FUNCTION {format.authors} +{ author "author" format.names +duplicate$ empty$ 'skip$ +{ collaboration "collaboration" bibinfo.check +duplicate$ empty$ 'skip$ +{ " (" swap$ * ")" * } +if$ +* +} +if$ +} +FUNCTION {get.bbl.editor} +{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ } + +FUNCTION {format.editors} +{ editor "editor" format.names duplicate$ empty$ 'skip$ +{ +" " * +get.bbl.editor +"(" swap$ * ")" * +* +} +if$ +} +FUNCTION {doilink} +{ duplicate$ empty$ +{ pop$ "" } +{doi empty$ +{ skip$ } +{ "\href{https://doi.org/" doi * "}{" * swap$ * "}" * } +if$ +} +if$ +} +FUNCTION {format.doi} +{ doi empty$ +{ "" } +{ +"\doi{" doi * "}" * +} +if$ +doilink +} +FUNCTION {format.note} +{ +note empty$ +{ "" } +{ note #1 #1 substring$ +duplicate$ "{" = +'skip$ +{ output.state mid.sentence = +{ "l" } +{ "u" } +if$ +change.case$ +} +if$ +note #2 global.max$ substring$ * "note" bibinfo.check +} +if$ +} + +FUNCTION {format.title} +{ title +duplicate$ empty$ 'skip$ +{ "t" change.case$ } +if$ +"title" bibinfo.check +} +FUNCTION {output.bibitem} +{ newline$ +"\bibitem{" write$ +cite$ write$ +"}" write$ +newline$ +"" +before.all 'output.state := +} + +FUNCTION {n.dashify} +{ +'t := +"" +{ t empty$ not } +{ t #1 #1 substring$ "-" = +{ t #1 #2 substring$ "--" = not +{ "--" * +t #2 global.max$ substring$ 't := +} +{ { t #1 #1 substring$ "-" = } +{ "-" * +t #2 global.max$ substring$ 't := +} +while$ +} +if$ +} +{ t #1 #1 substring$ * +t #2 global.max$ substring$ 't := +} +if$ +} +while$ +} + +FUNCTION {word.in} +{ "" } + +FUNCTION {format.date} +{ +"" +duplicate$ empty$ +year "year" bibinfo.check duplicate$ empty$ +{ swap$ 'skip$ +{ "there's a month but no year in " cite$ * warning$ } +if$ +* +} +{ swap$ 'skip$ +{ +swap$ +" " * swap$ +} +if$ +* +} +if$ +duplicate$ empty$ +'skip$ +{ +before.all 'output.state := +" (" swap$ * ")" * +} +if$ +} +FUNCTION {format.btitle} +{ title "title" bibinfo.check +duplicate$ empty$ 'skip$ +{ +emphasize +} +if$ +} +FUNCTION {either.or.check} +{ empty$ +'pop$ +{ "can't use both " swap$ * " fields in " * cite$ * warning$ } +if$ +} +FUNCTION {format.bvolume} +{ volume empty$ +{ "" } +{ bbl.volume volume tie.or.space.prefix +"volume" bibinfo.check * * +series "series" bibinfo.check +duplicate$ empty$ 'pop$ +{ emphasize ", " * swap$ * } +if$ +"volume and number" number either.or.check +} +if$ +} +FUNCTION {format.number.series} +{ volume empty$ +{ number empty$ +{ series field.or.null } +{ series empty$ +{ number "number" bibinfo.check } +{ output.state mid.sentence = +{ bbl.number } +{ bbl.number capitalize } +if$ +number tie.or.space.prefix "number" bibinfo.check * * +bbl.in space.word * +series "series" bibinfo.check * +} +if$ +} +if$ +} +{ "" } +if$ +} +FUNCTION {is.num} +{ chr.to.int$ +duplicate$ "0" chr.to.int$ < not +swap$ "9" chr.to.int$ > not and +} + +FUNCTION {extract.num} +{ duplicate$ 't := +"" 's := +{ t empty$ not } +{ t #1 #1 substring$ +t #2 global.max$ substring$ 't := +duplicate$ is.num +{ s swap$ * 's := } +{ pop$ "" 't := } +if$ +} +while$ +s empty$ +'skip$ +{ pop$ s } +if$ +} + +FUNCTION {convert.edition} +{ extract.num "l" change.case$ 's := +s "first" = s "1" = or +{ bbl.first 't := } +{ s "second" = s "2" = or +{ bbl.second 't := } +{ s "third" = s "3" = or +{ bbl.third 't := } +{ s "fourth" = s "4" = or +{ bbl.fourth 't := } +{ s "fifth" = s "5" = or +{ bbl.fifth 't := } +{ s #1 #1 substring$ is.num +{ s eng.ord 't := } +{ edition 't := } +if$ +} +if$ +} +if$ +} +if$ +} +if$ +} +if$ +t +} + +FUNCTION {format.edition} +{ edition duplicate$ empty$ 'skip$ +{ +convert.edition +output.state mid.sentence = +{ "l" } +{ "t" } +if$ change.case$ +"edition" bibinfo.check +" " * bbl.edition * +} +if$ +} +INTEGERS { multiresult } +FUNCTION {multi.page.check} +{ 't := +#0 'multiresult := +{ multiresult not +t empty$ not +and +} +{ t #1 #1 substring$ +duplicate$ "-" = +swap$ duplicate$ "," = +swap$ "+" = +or or +{ #1 'multiresult := } +{ t #2 global.max$ substring$ 't := } +if$ +} +while$ +multiresult +} +FUNCTION {format.pages} +{ pages duplicate$ empty$ 'skip$ +{ duplicate$ multi.page.check +{ +bbl.pages swap$ +n.dashify +} +{ +bbl.page swap$ +} +if$ +tie.or.space.prefix +"pages" bibinfo.check +* * +} +if$ +} +FUNCTION {format.journal.pages} +{ pages duplicate$ empty$ 'pop$ +{ swap$ duplicate$ empty$ +{ pop$ pop$ format.pages } +{ +":" * +swap$ +n.dashify +"pages" bibinfo.check +* +} +if$ +} +if$ +} +FUNCTION {format.journal.eid} +{ eid "eid" bibinfo.check +duplicate$ empty$ 'pop$ +{ swap$ duplicate$ empty$ 'skip$ +{ +":" * +} +if$ +swap$ * +numpages empty$ 'skip$ +{ bbl.eidpp numpages tie.or.space.prefix +"numpages" bibinfo.check * * +" (" swap$ * ")" * * +} +if$ +} +if$ +} +FUNCTION {format.vol.num.pages} +{ volume field.or.null +duplicate$ empty$ 'skip$ +{ +"volume" bibinfo.check +} +if$ +number "number" bibinfo.check duplicate$ empty$ 'skip$ +{ +swap$ duplicate$ empty$ +{ "there's a number but no volume in " cite$ * warning$ } +'skip$ +if$ +swap$ +"(" swap$ * ")" * +} +if$ * +} + +FUNCTION {format.chapter.pages} +{ chapter empty$ +{ "" } +{ type empty$ +{ bbl.chapter } +{ type "l" change.case$ +"type" bibinfo.check +} +if$ +chapter tie.or.space.prefix +"chapter" bibinfo.check +* * +} +if$ +} + +FUNCTION {format.booktitle} +{ +booktitle "booktitle" bibinfo.check +emphasize +} +FUNCTION {format.in.ed.booktitle} +{ format.booktitle duplicate$ empty$ 'skip$ + { + editor "editor" format.names.ed duplicate$ empty$ 'pop$ + { + get.bbl.editor + " " * swap$ * + swap$ + "," * + " " * swap$ + * } + if$ +word.in swap$ * +} +if$ +} + +FUNCTION {empty.misc.check} +{ author empty$ title empty$ howpublished empty$ +month empty$ year empty$ note empty$ +and and and and and +{ "all relevant fields are empty in " cite$ * warning$ } +'skip$ +if$ +} +FUNCTION {format.thesis.type} +{ type duplicate$ empty$ +'pop$ +{ swap$ pop$ +"t" change.case$ "type" bibinfo.check +} +if$ +} +FUNCTION {format.tr.number} +{ number "number" bibinfo.check +type duplicate$ empty$ +{ pop$ bbl.techrep } +'skip$ +if$ +"type" bibinfo.check +swap$ duplicate$ empty$ +{ pop$ "t" change.case$ } +{ tie.or.space.prefix * * } +if$ +} +FUNCTION {format.pat.number} +{ number "number" bibinfo.check +type duplicate$ empty$ +{ pop$ bbl.patent } +'skip$ +if$ +"type" bibinfo.check +swap$ duplicate$ empty$ +{ pop$ "t" change.case$ } +{ tie.or.space.prefix * * } +if$ +} +FUNCTION {format.article.crossref} +{ +key duplicate$ empty$ +{ pop$ +journal duplicate$ empty$ +{ "need key or journal for " cite$ * " to crossref " * crossref * warning$ } +{ "journal" bibinfo.check emphasize word.in swap$ * } +if$ +} +{ word.in swap$ * " " *} +if$ +" \cite{" * crossref * "}" * +} +FUNCTION {format.crossref.editor} +{ editor #1 "{vv~}{ll}" format.name$ +"editor" bibinfo.check +editor num.names$ duplicate$ +#2 > +{ pop$ +"editor" bibinfo.check +" " * bbl.etal +* +} +{ #2 < +'skip$ +{ editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = +{ +"editor" bibinfo.check +" " * bbl.etal +* +} +{ +bbl.and space.word +* editor #2 "{vv~}{ll}" format.name$ +"editor" bibinfo.check +* +} +if$ +} +if$ +} +if$ +} +FUNCTION {format.book.crossref} +{ volume duplicate$ empty$ +{ "empty volume in " cite$ * "'s crossref of " * crossref * warning$ +pop$ word.in +} +{ bbl.volume +swap$ tie.or.space.prefix "volume" bibinfo.check * * bbl.of space.word * +} +if$ +editor empty$ +editor field.or.null author field.or.null = +or +{ key empty$ +{ series empty$ +{ "need editor, key, or series for " cite$ * " to crossref " * +crossref * warning$ +"" * +} +{ series emphasize * } +if$ +} +{ key * } +if$ +} +{ format.crossref.editor * } +if$ +" \cite{" * crossref * "}" * +} +FUNCTION {format.incoll.inproc.crossref} +{ +editor empty$ +editor field.or.null author field.or.null = +or +{ key empty$ +{ format.booktitle duplicate$ empty$ +{ "need editor, key, or booktitle for " cite$ * " to crossref " * +crossref * warning$ +} +{ word.in swap$ * } +if$ +} +{ word.in key * " " *} +if$ +} +{ word.in format.crossref.editor * " " *} +if$ +" \cite{" * crossref * "}" * +} +FUNCTION {format.org.or.pub} +{ 't := +"" +address empty$ t empty$ and +'skip$ +{ +add.blank "(" * +t empty$ +{ address "address" bibinfo.check * +} +{ t * +address empty$ +'skip$ +{ ", " * address "address" bibinfo.check * } +if$ +} +if$ +")" * +} +if$ +} +FUNCTION {format.publisher.address} +{ publisher "publisher" bibinfo.warn format.org.or.pub +} + +FUNCTION {format.organization.address} +{ organization "organization" bibinfo.check format.org.or.pub +} + +FUNCTION {format.institution.address} +{ institution "institution" bibinfo.check format.org.or.pub +} + +FUNCTION {article} +{ output.bibitem +format.authors "author" output.check +format.date "year" output.check +date.block +format.title "title" output.check +new.sentence +crossref missing$ +{ +journal +remove.dots +"journal" bibinfo.check +emphasize +"journal" output.check +add.blank +format.vol.num.pages output +} +{ format.article.crossref output.nonnull +} +if$ +eid empty$ +{ format.journal.pages } +{ format.journal.eid } +if$ +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} +FUNCTION {book} +{ output.bibitem +author empty$ +{ format.editors "author and editor" output.check +add.blank +} +{ format.authors output.nonnull +crossref missing$ +{ "author and editor" editor either.or.check } +'skip$ +if$ +} +if$ +format.date "year" output.check +date.block +format.btitle "title" output.check +new.sentence +crossref missing$ +{ format.bvolume output +format.number.series output +format.publisher.address output +} +{ +format.book.crossref output.nonnull +} +if$ +", " * format.edition output +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} +FUNCTION {booklet} +{ output.bibitem +format.authors output +format.date output +date.block +format.title "title" output.check +new.sentence +howpublished "howpublished" bibinfo.check output +", " * address "address" bibinfo.check output +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} + +FUNCTION {inbook} +{ output.bibitem +author empty$ +{ format.editors "author and editor" output.check +} +{ format.authors output.nonnull +crossref missing$ +{ "author and editor" editor either.or.check } +'skip$ +if$ +} +if$ +format.date "year" output.check +date.block +format.btitle "title" output.check +new.sentence +crossref missing$ +{ +format.number.series output +format.publisher.address output +", " * format.bvolume output +", " * format.chapter.pages "chapter and pages" output.check +} +{ +format.chapter.pages "chapter and pages" output.check +format.book.crossref output.nonnull +} +if$ +", " * format.edition output +", " * format.pages "pages" output.check +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} + +FUNCTION {incollection} +{ output.bibitem +format.authors "author" output.check +format.date "year" output.check +date.block +format.title "title" output.check +new.sentence +crossref missing$ +{ format.in.ed.booktitle "booktitle" output.check +format.number.series output +publisher empty$ +{ format.organization.address output } +{ organization "organization" bibinfo.check output +format.publisher.address output +} +if$ +", " * format.bvolume output +} +{ format.incoll.inproc.crossref output.nonnull +} +if$ +", " * format.pages "pages" output.check +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} +FUNCTION {inproceedings} +{ output.bibitem +format.authors "author" output.check +format.date "year" output.check +date.block +format.title "title" output.check +new.sentence +crossref missing$ +{ format.in.ed.booktitle "booktitle" output.check +format.number.series output +publisher empty$ +{ format.organization.address output } +{ organization "organization" bibinfo.check output +format.publisher.address output +} +if$ +", " * format.bvolume output +} +{ format.incoll.inproc.crossref output.nonnull +} +if$ +", " * format.pages "pages" output.check +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} +FUNCTION {conference} { inproceedings } +FUNCTION {manual} +{ output.bibitem +author empty$ +{ organization "organization" bibinfo.check +duplicate$ empty$ 'pop$ +{ output +address "address" bibinfo.check output +} +if$ +} +{ format.authors output.nonnull } +if$ +format.date output +date.block +format.btitle "title" output.check +author empty$ +{ organization empty$ +{ +address "address" bibinfo.check output +} +'skip$ +if$ +} +{ +organization "organization" bibinfo.check output +address "address" bibinfo.check output +} +if$ +", " * format.edition output +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} + +FUNCTION {mastersthesis} +{ output.bibitem +format.authors "author" output.check +format.date "year" output.check +date.block +format.btitle +"title" output.check +bbl.mthesis format.thesis.type output.nonnull +school "school" bibinfo.warn output +address "address" bibinfo.check output +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} + +FUNCTION {misc} +{ output.bibitem +format.authors output +format.date output +format.title output +howpublished empty$ +'skip$ +{", " * howpublished "howpublished" bibinfo.check output} +if$ +new.sentence +format.doi output +"." * +format.note output +format.eprint output +format.url output +fin.entry +empty.misc.check +} +FUNCTION {phdthesis} +{ output.bibitem +format.authors "author" output.check +format.date "year" output.check +date.block +format.btitle +"title" output.check +new.sentence +bbl.phdthesis format.thesis.type output.nonnull +school "school" bibinfo.warn output +", " * address "address" bibinfo.check output +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} + +FUNCTION {proceedings} +{ output.bibitem +editor empty$ +{ organization "organization" bibinfo.check output +} +{ format.editors output.nonnull } +if$ +format.date "year" output.check +date.block +format.btitle "title" output.check +new.sentence +", " +editor empty$ +{ publisher empty$ +{ format.number.series output } +{ + +format.publisher.address output +} +if$ +} +{ publisher empty$ +{ +format.number.series output +format.organization.address output } +{ +format.number.series output +organization "organization" bibinfo.check output +format.publisher.address output +} +if$ +} +if$ +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} + +FUNCTION {techreport} +{ output.bibitem +format.authors "author" output.check +format.date "year" output.check +date.block +format.title +"title" output.check +new.sentence +format.institution.address output +", " * format.tr.number output.nonnull +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} + +FUNCTION {patent} +{ output.bibitem +format.authors "author" output.check +format.date "year" output.check +date.block +format.title +"title" output.check +new.sentence +institution "institution" bibinfo.warn output +address "address" bibinfo.check output +" " * format.pat.number output.nonnull +new.sentence +format.doi output +new.sentence +format.note output +format.eprint output +format.url output +fin.entry +} + +FUNCTION {unpublished} +{ output.bibitem +format.authors "author" output.check +format.date output +date.block +format.title "title" output.check +new.sentence +format.doi output +new.sentence +format.note "note" output.check +format.eprint output +format.url output +fin.entry +} + + + +FUNCTION {default.type} { misc } +READ +STRINGS { longest.label } +INTEGERS { number.label longest.label.width } +FUNCTION {initialize.longest.label} +{ "" 'longest.label := +#1 'number.label := +#0 'longest.label.width := +} +FUNCTION {longest.label.pass} +{ number.label int.to.str$ 'label := +number.label #1 + 'number.label := +label width$ longest.label.width > +{ label 'longest.label := +label width$ 'longest.label.width := +} +'skip$ +if$ +} +EXECUTE {initialize.longest.label} +ITERATE {longest.label.pass} +FUNCTION {begin.bib} +{ preamble$ empty$ +'skip$ +{ preamble$ write$ newline$ } +if$ +"\begin{thebibliography}{" longest.label * "}" * +write$ newline$ +"\providecommand{\url}[1]{\texttt{#1}}" +write$ newline$ +"\providecommand{\urlprefix}{Available at }" +write$ newline$ +"\expandafter\ifx\csname urlstyle\endcsname\relax" +write$ newline$ +" \providecommand{\doi}[1]{https://doi.org/\discretionary{}{}{}#1}\else" +write$ newline$ +" \providecommand{\doi}{https://doi.org/\discretionary{}{}{}\begingroup \urlstyle{rm}\Url}\fi" +write$ newline$ +"\providecommand{\eprint}[2][]{\url{#2}}" +write$ newline$ +} +EXECUTE {begin.bib} +EXECUTE {init.state.consts} +ITERATE {call.type$} +FUNCTION {end.bib} +{ newline$ +"\end{thebibliography}" write$ newline$ +} +EXECUTE {end.bib} +%% End of customized bst file +%% +%% End of file `jresnistdoi01.bst'. diff --git a/doc/pdf/trash.py b/doc/pdf/trash.py new file mode 100644 index 00000000000..abb6e8a91f8 --- /dev/null +++ b/doc/pdf/trash.py @@ -0,0 +1,61 @@ +import re + +# fp = open("index.md","r",encoding="utf8") + + +# text = fp.read() + +# header = re.search("---(.*\n)*---",text) + +# htmlText = re.search('(.*\n)*', text) + +# p = re.compile('(.*\n)*') +# text2 = p.sub('',text) + +juangpc@gmail.com + +param\[\w+,?\w*\]\s+(\w+)\s+ +<\s*img\s+src="([A-Za-z0-9/]*)" (?=width) + +# print(fp) + +# textRe = "[^]]*" +# imgRe = "\/.*?\.[\w:]+" +# markupRegex = '!\[({0})]\(\s*({1})\s*\)'.format(textRe, imgRe) +# imgList = re.findall(markupRegex, str) +aabbb +aaaaaa +# ##################################################### + +text_to_search = ''' +abcdefghijklmnopqurtuvwxyz +ABCDEFGHIJKLMNOPQRSTUVWXYZ +1234567890 +Ha HaHa +MetaCharacters (Need to be escaped): +. ^ $ * + ? { } [ ] \ | ( ) +coreyms.com +321-555-4321 +123.555.1234 +123*555*1234 +800-555-1234 +900-555-1234 +Mr. Schafer +Mr Smith +Ms Davis +Mrs. Robinson +Mr. T +''' + +sentence = "Start a sentence and then bring it to an end" + +pattern = re.compile(r'abc') + +matches = pattern.finditer(text_to_search) + +for match in matches: + print(match) + + + + diff --git a/tools/python/demo_recursive_folder_process.py b/tools/python/demo_recursive_folder_process.py new file mode 100644 index 00000000000..126d2cdf37d --- /dev/null +++ b/tools/python/demo_recursive_folder_process.py @@ -0,0 +1,18 @@ +import mne_cpp.core as mne +# import mne_cpp.pdf_doc +from os import stat + +mne.version() + +projectFolder = mne.baseFolder() + +# Recursively list all the files in a directory and order by size and print results. +listOfFiles = [] +mne.recursiveFolderProcess(projectFolder + 'doc/gh-pages', lambda f: \ + listOfFiles.append((f, stat(f).st_size)) \ + if f.name.endswith('.md') \ + else None ) +listOfFiles.sort(reverse=True, key=lambda f:f[1]) +for f in listOfFiles: + print('File: ' + f[0].path + ' - (' + mne.sizeHumanReadable(f[1]) + ')') + diff --git a/tools/python/documentation_pdf_generator.py b/tools/python/documentation_pdf_generator.py new file mode 100644 index 00000000000..9c1844f1df5 --- /dev/null +++ b/tools/python/documentation_pdf_generator.py @@ -0,0 +1,93 @@ +import mne_cpp.core +import mne_cpp.pdf_doc as mnepdf + +projectFolder = mne_cpp.core.baseFolder() +webBaseFolder = projectFolder + 'doc/gh-pages' + +# webDocuments = mnepdf.scanFolder(webBaseFolder) +# print(webDocuments) + +# web = mnepdf.buildWebStructure(webDocuments) +# print('Printing Web Structure:') +# print(web) + +# (pathLabel, filePath, fileName, fileExt, fullPath) = mne_cpp.core.extractFilePaths('../../doc/gh-pages/pages/documentation/anonymize.md') +# (pathLabel, filePath, fileName, fileExt, fullPath) = mne_cpp.core.extractFilePaths('../../doc/gh-pages/pages/contact.md') + +# inFile = open(fullPath, mode = 'r', encoding = 'utf8') +# inText = inFile.read() +# inFile.close() + +# outText = mnepdf.parseUnorderedList(inText) +# outFile = open(pathLabel + filePath + fileName + '.PROCESSED' + '.' + fileExt, mode = 'w', encoding = 'utf8') +# outFile.write(outText) +# outFile.close() + +inText = r''' +--- +layout: default +title: Markdown kitchen sink +nav_order: 99 +--- +(\n(( *[-*] *)|(\s*\d+\.\s*))[^\-*\n ].+)+ +(\n(( *[-*] *)|( *\d+\. *))[^\-*\n ].+)+ +(\n(( *[-*] *)|( *\d+\. *))[^\-*\n ].+)+ +Text can be **bold**, _italic_, or ~~strikethrough~~. + +[Link to another page](another-page). + +There should be whitespace between paragraphs. + +There should be whitespace between paragraphs. We recommend including a README, or a file with information about your project. + +# [](#header-1)Header 1 + +This is a normal paragraph following a header. GitHub is a code hosting platform for version control and collaboration. It lets you and others work together on projects from anywhere. + +## [](#header-2)Header 2 + +> This is a blockquote following a header. +> +> When something is important enough, you do it even if the odds are not in your favor. + +### [](#header-3)Header 3 + +```js +// Javascript code with syntax highlighting. +var fun = function lang(l) { + dateformat.i18n = require('./lang/' + l) + return true; +} +``` + +```ruby +# Ruby code with syntax highlighting +GitHubPages::Dependencies.gems.each do |gem, version| + s.add_dependency(gem, "= #{version}") +end +``` +- level 1 item + - level 2 item + - level 2 item + - level 3 item + - level 3 item +- level 1 item + - level 2 item + - level 2 item + - level 2 item +- level 1 item + - level 2 item + - level 2 item +- level 1 item +''' + +outText = mnepdf.parseLists(inText) + + + + + +a = 3 + + + diff --git a/tools/python/list_trash_text1.txt b/tools/python/list_trash_text1.txt new file mode 100644 index 00000000000..b8722d23132 --- /dev/null +++ b/tools/python/list_trash_text1.txt @@ -0,0 +1,15 @@ +\begin{itemize} + \item level 1 item + - level 2 item + - level 2 item + - level 3 item + - level 3 item + \item level 1 item + - level 2 item + - level 2 item + - level 2 item + \item level 1 item + - level 2 item + - level 2 item + \item level 1 item +\end{itemize} \ No newline at end of file diff --git a/tools/python/list_trash_text2.txt b/tools/python/list_trash_text2.txt new file mode 100644 index 00000000000..dd5efdd10d0 --- /dev/null +++ b/tools/python/list_trash_text2.txt @@ -0,0 +1,26 @@ +\begin{itemize} + \item level 1 item + \begin{itemize} + \item level 2 item + \item level 2 item + \begin{itemize} + \item level 3 item + \item level 3 item + \end{itemize} + \end{itemize} + \item level 1 item + \begin{itemize} + \item level 2 item + \item level 2 item + \item level 2 item + \end{itemize} + \item level 1 item + \begin{itemize} + \item level 2 item + \item level 2 item + \end{itemize} + \item level 1 item +\end{itemize} + + + \ No newline at end of file diff --git a/tools/python/mne_cpp/__init__.py b/tools/python/mne_cpp/__init__.py new file mode 100644 index 00000000000..e4d871f74e3 --- /dev/null +++ b/tools/python/mne_cpp/__init__.py @@ -0,0 +1,34 @@ +#============================================================================================================= +# +# @file __init__.py in mne_cpp module +# @author jgarciaprieto@mgh.harvard.edu +# @since 0.1.9 +# @date March, 2021 +# +# @section LICENSE +# +# Copyright (C) 2017, Juan Garcia-Prieto. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that +# the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, this list of conditions and the +# following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and +# the following disclaimer in the documentation and/or other materials provided with the distribution. +# * Neither the name of MNE-CPP authors nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# +# MNE-CPP Project Python main module init file. +import mne_cpp.core + + diff --git a/tools/python/mne_cpp/__pycache__/__init__.cpython-39.pyc b/tools/python/mne_cpp/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000000..4c843d25339 Binary files /dev/null and b/tools/python/mne_cpp/__pycache__/__init__.cpython-39.pyc differ diff --git a/tools/python/mne_cpp/__pycache__/core.cpython-39.pyc b/tools/python/mne_cpp/__pycache__/core.cpython-39.pyc new file mode 100644 index 00000000000..8e9b69449e5 Binary files /dev/null and b/tools/python/mne_cpp/__pycache__/core.cpython-39.pyc differ diff --git a/tools/python/mne_cpp/__pycache__/pdf_doc.cpython-39.pyc b/tools/python/mne_cpp/__pycache__/pdf_doc.cpython-39.pyc new file mode 100644 index 00000000000..d56980db3f2 Binary files /dev/null and b/tools/python/mne_cpp/__pycache__/pdf_doc.cpython-39.pyc differ diff --git a/tools/python/mne_cpp/core.py b/tools/python/mne_cpp/core.py new file mode 100644 index 00000000000..c8ee04ae505 --- /dev/null +++ b/tools/python/mne_cpp/core.py @@ -0,0 +1,182 @@ +#============================================================================================================= +# +# @file mne_cpp.py +# @author jgarciaprieto@mgh.harvard.edu +# @since 0.1.9 +# @date March, 2021 +# +# @section LICENSE +# +# Copyright (C) 2017, Juan Garcia-Prieto. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that +# the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, this list of conditions and the +# following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and +# the following disclaimer in the documentation and/or other materials provided with the distribution. +# * Neither the name of MNE-CPP authors nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# +# @brief MNE-CPP Project Python main module. +# +import sys +from os import path, scandir +from enum import Enum +import re +from math import log2 + +# This file should be kept inside the following folder: mne_mneBaseFolder/tools/python/mne_cpp + +def version(): + print('MNE-CPP Project python module. - Version: 0.1.9') + print('Copyright (C) 2021, Juan Garcia-Prieto. All rights reserved.') + +def __pathToThisFile(): + return path.abspath(path.dirname(sys.argv[0])) + +def baseFolder(): + this_script_path = __pathToThisFile().split(path.sep) + project_path = '' + for f in this_script_path[:-2]: + project_path += f + '/' + return project_path + +def extractFilePaths(text: str, **inputArgs): + + (fileExtensionSeparator, ) = parseInputArguments(inputArgs, opts = (('fileExtensionSeparator', 'last'), )) + + if fileExtensionSeparator == 'first': # first '.' in filename separates ext + expression = re.compile(r""" + (?P[A-Za-z]:)? # Device Label. c: D: etc... for windows. + (?P([/\\]?) # filePath: absolute or relative path. /folder/file.txt vs folder/file.txt + # ^ ^ + (?P(\.{1,2}|[^\n.<>:"|?*/\\,()\[\]]+)[/\\])+ # An undefined number of nested folders '.' and '..' admitted. + # The forbidden char set is mostly due to windows = [^\n.<>:"|?*/\\] but + # using them in linux is kind of asking for trouble. So out! + ) + (?P([^/\\{}\n?*":\' ][^/\\{}\n?*":\'][^/\\{}\n?*":\' .]*?)+?) #notice the not greedy. Thats what makes it first select the first '.' + \. # + (?P[A-Za-z0-9_.]*) + """,re.X) + elif fileExtensionSeparator == 'last': # last '.' in the filename separates the file extension + expression = re.compile(r""" + (?P[A-Za-z]:)? # Device Label. c: D: etc... for windows. + (?P([/\\]?) # filePath: absolute or relative path. /folder/file.txt vs folder/file.txt + # ^ ^ + (?P(\.{1,2}|[^\n.<>:"|?*/\\,()\[\]]+)[/\\])+ # An undefined number of nested folders '.' and '..' admitted. + # The forbidden char set is mostly due to windows = [^\n.<>:"|?*/\\] but + # using them in linux is kind of asking for trouble. So out! + ) + (?P([^/\\{}\n?*":\' ][^/\\{}\n?*":\'][^/\\{}\n?*":\' .]*?)+) + \. #this will be surely the last '.' in a possibly "multy" extension file + (?P[A-Za-z0-9_.]*) + """,re.X) + else: + raise NameError('Unkown extension separator option used: ' + str(fileExtensionSeparator)) + pattern = re.compile(expression) + fileMatches = pattern.finditer(text) + for f in fileMatches: + deviceLabel = noneIfEmpty(f.group('deviceLabel')) #f.string[f.start('deviceLabel'):f.end('deviceLabel')] + filePath = noneIfEmpty(f.group('filePath')) #f.string[f.start('filePath'):f.end('filePath')-1] + fileName = noneIfEmpty(f.group('fileName')) #f.string[f.start('fileName'):f.end('fileName')] + fileExt = noneIfEmpty(f.group('fileExtension')) #f.string[f.start('fileExtension'):f.end('fileExtension')] + absFilePath = deviceLabel + filePath + fileName + '.' + fileExt + print(absFilePath) + return (deviceLabel, filePath, fileName, fileExt, absFilePath) + +def recursiveFolderProcess(folderPath, func): + for file in scandir(folderPath): + if file.is_dir(): + recursiveFolderProcess(file, func) + if file.is_file(): + func(file) + +def noneIfEmpty(s): + return '' if s is None else s + +def parseFilePathNameExt(inText): + pattern = re.compile(r""" + ^(?P # filePath group starts at the beginning of the text + (?P([A-Za-z]:[/\\])|[/\\])? # deviceLabel is for windows plat. i.e. C:\ (optional) + (?P[\w.-]+[/\\])* # lastFolder is the immediately parent folder to the file. (optional) + )? # filePath group ends here. (optional) + (?P[\w\-.]+?) # fileName can contain dots, dash or any character A-Za-z0-9_. min size of 1. Not greedy + (\.(?P\w+))? # fileExt starts *after* the *last* dot within the fileName. (optional) + $""", re.X) + match = re.seach(pattern, inText) + deviceLabel = '' + filePath = '' + lastFolder = '' + fileName = '' + fileExt = '' + if match: + deviceLabel = noneIfEmpty(match.group('deviceLabel')) + filePath = noneIfEmpty(match.group('filePath')) + lastFolder = noneIfEmpty(match.group('lastFolder')) + fileName = noneIfEmpty(match.group('fileName')) + fileExt = noneIfEmpty(match.group('fileExt')) + return (deviceLabel, filePath, lastFolder, fileName, fileExt) + +def parseInputArguments(argsToParse, **opts): + caseSensitive = True + relaxedMode = False + inputOptions = () + for key, value in opts.items(): + if key == 'case_sensitive': + caseSensitive = value + if key == 'admit_unknown_options': + relaxedMode = value + if key == 'opts': + inputOptions = value + options = {} + for opt in inputOptions: + if caseSensitive: + key = opt[0] + else: + key = opt[0].lower() + options[key] = opt[1] + for arg in argsToParse: + if caseSensitive: + arg_adapted = arg + else: + arg_adapted = arg.lower() + if arg_adapted not in options: + if not relaxedMode: + raise NameError('Unkown option specified.') + else: + options[arg_adapted] = argsToParse[arg] + return (v for k, v in options.items()) + +def sizeHumanReadable(size): + _suffixes = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] + # determine binary order in steps of size 10 + # (coerce to int, // still returns a float) + order = int(log2(size) / 10) if size else 0 + # format file size + # (.4g results in rounded numbers for exact matches and max 3 decimals, + # should never resort to exponent values) + return '{:.4g} {}'.format(size / (1 << (order * 10)), _suffixes[order]) + +def getListOfFiles(folder): + """Retrieve a list of files inside (recursive) a folder. + + Args: + folder Str: Path of the folder. + + Returns: + List: Files found. + """ + listOfFiles = [] + recursiveFolderProcess(folder,lambda f:listOfFiles.append(f)) + return listOfFiles diff --git a/tools/python/mne_cpp/pdf_doc.py b/tools/python/mne_cpp/pdf_doc.py new file mode 100644 index 00000000000..6814f2d2296 --- /dev/null +++ b/tools/python/mne_cpp/pdf_doc.py @@ -0,0 +1,427 @@ +#============================================================================================================= +# +# @file pdf_doc.py +# @author jgarciaprieto@mgh.harvard.edu +# @since 0.1.9 +# @date March, 2021 +# +# @section LICENSE +# +# Copyright (C) 2017, Juan Garcia-Prieto. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that +# the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, this list of conditions and the +# following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and +# the following disclaimer in the documentation and/or other materials provided with the distribution. +# * Neither the name of MNE-CPP authors nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# +# @brief MNE-CPP Project pdf documentation generation from the website. +# +import sys +from pathlib import Path +from os import scandir, path +import re +import mne_cpp.core +from svglib.svglib import svg2rlg +from reportlab.graphics import renderPM +from PIL import Image + +def parseFile(file, verboseMode = False): + with open(file, 'r', encoding='utf8') as fileOpened: + insideHeader = False + codeText = False + validContentFile = False + doc = Document(file.path) + for line in fileOpened: + if not codeText and (line.startswith('```') or line.count('```')%2 != 0): + codeText = True + continue + if codeText and (line.startswith('```') or line.count('```')%2 != 0): + codeText = False + continue + if line.startswith('---') and not insideHeader: + insideHeader = True + continue + if line.startswith('---') and insideHeader: + insideHeader = False + break + if insideHeader and not codeText: + if line.lstrip().startswith('title'): + doc.setTitle(line.split(':')[1].lstrip().rstrip()) + validContentFile = True + continue + if line.lstrip().startswith('parent'): + doc.setParent(line.split(':')[1].lstrip().rstrip()) + continue + if line.lstrip().startswith('nav_order'): + doc.setNavOrder(int(line.split(':')[1].lstrip().rstrip())) + continue + if line.lstrip().startswith('has_children'): + doc.setHasChildren(bool(line.split(':')[1].lstrip().rstrip())) + continue + if line.lstrip().startswith('nav_exclude'): + doc.setNavExclude(bool(line.split(':')[1].lstrip().rstrip())) + continue + if line.lstrip().startswith('grand_parent'): + doc.setGrandParent(line.split(':')[1].lstrip().rstrip()) + continue + if validContentFile and verboseMode: + print(doc) + return doc, validContentFile + +def scanFolder(folderPath, documents = []): + for file in scandir(folderPath): + if file.is_file() and file.name.endswith('md'): + # print('parsing file: ' + file.path) + doc, valid = parseFile(file) + if valid: + documents.append(doc) + if file.is_dir(): + scanFolder(file, documents) + return documents + +class Document: + def __init__(self, path): + self.title = '' + self.parent = '' + self.grand_parent = '' + self.nav_order = 0 + self.has_children = False + self.nav_exclude = False + self.fullPath = path + + def setTitle(self, title): + self.title = title + + def setParent(self, parent): + self.parent = parent + + def setGrandParent(self, grandParent): + self.grand_parent = grandParent + + def setNavOrder(self, nav_order): + self.nav_order = nav_order + + def setHasChildren(self, hasChildren): + self.has_children = hasChildren + + def setNavExclude(self, navExclude): + self.nav_exclude = navExclude + + def setFullPath(self, path): + self.fullPath = path + + def __str__(self): + s = '' + # s += '--- Class: ' + type(self).__name__ + ' ---\n' + s += 'title: ' + self.title + ' - ' + s += 'path: ' + self.fullPath + '\n' + # s += 'parent: ' + self.parent + '\n' + # s += 'nav_order: ' + str(self.nav_order) + '\n' + # s += 'has_children: ' + str(self.has_children) + '\n' + # s += 'nav_exclude: ' + str(self.nav_exclude) + '\n' + return s + + def __repr__(self): + return str(self) + +class Page: + def __init__(self,doc): + self.doc = doc + self.children = [] + def insert(self,d2): + if d2.parent == self.doc.title and \ + d2.grand_parent == self.doc.parent : + self.children.append(Page(d2)) + self.children.sort(key=lambda p:p.doc.nav_order) + return True + else: + for c in self.children: + found = c.insert(d2) + if found: + return True + return False + def print(self, spaces = 0): + s = ' ' * spaces + ' - ' + self.doc.title + ' (' + self.doc.fullPath + ')\n' + for p in self.children: + s += ' ' * spaces + p.print(spaces+2) + return s + + def __str__(self): + return self.print() + + def __repr__(self): + return str(self) + +def buildWebStructure(documents): + web = Page(Document('')) + while documents: + for d in documents: + if web.insert(d): + documents.remove(d) + return web + +def parseWeb(web, sectionLevel = 0): + print('Parsing file: ' + web.doc.fullPath) + parseMarkDownFile(web.doc, latexFile = 'teseta.tex', sectionLevel = 0, verboseMode = True) + for p in web.children: + parseWeb(p,sectionLevel = sectionLevel+1, verboseMode = True) + +def parseMarkDownFile(file, **inputArgs): + opts = (('latexFile', 'mne_pdf_manual.tex'), + ('verboseMode', False), + ('sectionLevel', 0)) + (texFile, verboseMode, sectionLevel) = mne_cpp.core.parseInputArgs(inputArgs, opts = opts) + if file.fullPath == '': + return + else: + with open(file.fullPath, 'r', encoding='utf8') as markDownFile, \ + open(texFile,'a+') as texFile: + # The order here is relevant. Some of the regex depend on not having conflicting patterns. + # i.e. empty lines can sometimes interfere with some lists patterns + # i.e.2 horizontal lines (\n* * *) pattern can sometimes be understood as a list. + # I've tried to minimize these conflicts but I'm not 100% sure. So any change should be tested... + inText = markDownFile.read() + inText = stripEmptyLines(inText) + inText = deleteJustTheDocsHeader(inText) + inText = parseHorizontalLines(inText) + inText = parseInlineItalicText(inText) + inText = parseInlineBoldText(inText) + inText = parseUnorderedList(inText) + inText = parseInlineImages(inText) + inText = parseInlineHTMLImages(inText) + inText = parseTableMd(inText) + inText = parseFigureImages(inText) + inText = parseHeaders(inText) + inText = parseLinks(inText) + +def deleteJustTheDocsHeader(inText): + return re.sub(r'\n*\s*---\s*\n(.*\n)*---\n','',inText) + +def parseInlineItalicText(inText): + return re.sub(r'(?<=\W)((?P\*)|_)(?P\w+)(?(star)\*|_)(?=\W)',r'\\textit{\g}', inText) + +def parseInlineBoldText(inText): + return re.sub(r'(?<=\W)((?P\*\*)|__)(?P[\w ]+)((?(dstar)\*\*)|__)(?=\W)',r'\\textbf{\g}', inText) + +def parseInlineImages(inText): + match = re.search(r'!\[(?P[^]]+)\]\((?P[^)]+)\)', inText) + if match: + imgPath = mne_cpp.core.noneIfEmpty(match.group('imgFilePath')) + imgAltText = mne_cpp.core.noneIfEmpty(match.group('alt_text')) + figText = '\n\\begin{wrapfigure}{r}{0.5\\textwidth}' + figText += '\n\t\\begin{center}' + figText += '\n\t\t\\includegraphics[width=0.4\\textwidth]{ ' + imgPath + '}' + figText += '\n\t\\end{center}' + figText += '\n\t\\caption{' + imgAltText.replace(' ','_') + '}' + figText += '\n\\end{wrapfigure}' + outText = inText[:match.start(0)] + figText + inText[match.end(0):] + return parseInlineImages(outText) + else: + return inText + +def parseInlineHTMLImages(inText): + match = re.search(r'<\s*img\s*src\s*=\s*"(?P[^"]+)".*>', inText) + if match: + imgPath = mne_cpp.core.noneIfEmpty(match.group('imgFilePath')) + figText = '\n\\begin{wrapfigure}{r}{0.5\\textwidth}' + figText += '\n\t\\begin{center}' + figText += '\n\t\t\\includegraphics[width=0.4\\textwidth]{ ' + imgPath + '}' + figText += '\n\t\\end{center}' + figText += '\n\t\\caption{' + imgAltText.replace(' ','_') + '}' + figText += '\n\\end{wrapfigure}' + outText = inText[:match.start(0)] + figText + inText[match.end(0):] + return parseInlineImages(outText) + else: + return inText + +def parseTableMd(inText): + match = re.search(r'(?<=\n)\|([^|\n]+\|)+', inText) + if match: + tableText = inText[match.start(0):match.end(0)] + firstRow = re.sub(r'^.*',r'\g<0>', tableText) + numCols = firstRow.count('|') - 1 + latexTableText = '\\begin{table}[h!]\n' + latexTableText += '\\centering\n' + latexTableText += '\\begin{tabular}{||' + 'c' * numCols + '||}\n' + latexTableText += '&'.join(firstRow.split('|')[1:-1]) + '\\\\[0.5ex]\n' + otherRows = re.findall(r'(?<=\n)\|.*', tableText) + for row in otherRows: + hColumnMatch = re.search('(?<=\n)\|[:\-|]+',row) + if hColumnMatch: + latexTableText += ' \\hline\n' + latexTableText += ' ' + '&'.join(row.split('|')[1:-1]) + '\\\\\n' + latexTableText += ' \\hline\n' + latexTableText += '\\end{tabular}\n' + latexTableText += '\\end{table}\n' + outText = inText[:match.start(0)] + latexTableText + inText[match.end(0):] + return parseInlineImages(outText) + else: + return inText + +def parseLinks(inText): + inText = inText.replace('{:target=\"_blank\" rel=\"noopener\"}','') + nameRe = '[^]]+' + urlRe = 'http[s]?://[^)]+' + markupRegex = '\[({0})]\(\s*({1})\s*\)'.format(nameRe, urlRe) + linkList = re.findall(markupRegex, inText) + if linkList: + link = linkList[0] + inTextPre = inText.split('[' + link[0] + ']')[0] + inTextPost = inText.split('(' + link[1] + ')')[1] + latexLink = '\\href{' + link[1] + '}{' + link[0] + '}\\footnote{' + link[1] + '}' + outText = inTextPre + latexLink + inTextPost + parseLinks(outText) + else: + return inText + +def parseHeaders(inText): + latexSectionKey = { + '#' : ('part','sec'), + '##' : ('section', 'sec'), + '###' : ('subsection', 'ssec'), + '####' : ('subsubsection', 'ssec') + } + match = re.search(r'(?<=\n)[ \t]*(?P#+)[ \t]*(?P.*)', inText) + if match: + outHeader = '\n\\' + latexSectionKey.get(match.group('pounds'),('subsection','ssec'))[0] + '{' + match.group('headerText') + '}' + outHeader += ' \n\\label{' + latexsectionKey.get(match.group('pounds'),('subsection','ssec'))[1] + ':' + match.group('headerText').replace(' ','_') + '}' + outText = inText[:match.start(0)] + outHeader + inText[match.end(0):] + return parseHeaders(outText) + else: + return inText + +def parseHorizontalLines(inText): + return re.sub(r'(?<=\n)\*\s\*\s\*(?=\n)','\\noindent\\rule{15cm}{0.5pt}', inText) + +def stripHorizontalLines(inText): + return re.sub(r'(?<=\n)\*\s\*\s\*(?=\n)','', inText) + +def stripEmptyLines(inText): + return re.sub(r'((?<=\n)\n)','',inText) + +# def parseUnorderedList(inText): +# match = re.search(r'(\n\s?\*\s?.+)(\n\s?\*\s?(.+))*', inText) +# if match: +# outList = '\n\\begin{itemize}\n' +# pattern2 = re.compile(r'\n*\s*\*\s*(?P.+)(?=\n)?') +# itemList = pattern2.finditer(match.group(0)) +# for item in itemList: +# outList += '\t\\item ' + item.group('item') + '\n' +# outList += '\\end{itemize}' +# outText = inText[:match.start(0)] + outList + inText[match.end(0):] +# return parseUnorderedList(outText) +# else: +# return inText +def parseUnorderedList(inText, i): + pattern = r'\n(( {0}[-*] *)(?P.*))' + lastMatch = len(re.findall(pattern, inListText)) + matches = re.finditer(pattern, inListText) + parsedText = '' + for numMatch, match in enumerate(matches, start = 1): + itemText = '\n\\begin{itemize}' if numMatch is 1 else '' + itemText += '\\item ' + match.group('itemText') + itemText += '\\end{itemize}' if numMatch is lastMatch + parsedText += inListText[:match.start()] + itemText + inListText[match.end():] + + +def parseOneList(inList): + outList = parseUnorderedList(inList) + + + +def parseLists(inText): + match = re.search(r'(\n(( *[-*] *)|( *\d+\. *))[^\-*\n ].+)+', inText) + if match: + parsedList = parseOneList(match.group()) + outText = inText[:match.start()] + parsedList + inText[match.end():] + return parseLists + else: + return inText + + + # for spaces in range(2:2:6): + # pattern = + +# matches4ord = re.finditer(r'(\n( {2}(\d+\.) *)([^-\n ].*))+', text[match.start(0):match.end(0)]) +# for match4ord in matches4ord: +# outText = '\n\\begin{enumerate}\n' + +# ((\n {2}\d+\. *)(?P.*)) + +# parse all lists with (\n((\s*[-*]\s*)|(\s*\d+\.\s*)).+)+ +# https://regex101.com/r/idzIo5/1/ +# https://regex101.com/r/Iu3hKt/1 + +# after this parse +# ordered lists of level 4 +# unordered lists of level 4 +# ordered lists of level 3 +# unordered lists of level 3 +# ordered lists of level 2 +# unordered lists of level 2 +# ordered lists of level 1 +# unordered lists of level 1 + +# parse task lists +# https://tex.stackexchange.com/questions/247681/how-to-create-checkbox-todo-list + + +# still missing: +# ordered and unordered lists parsing +# inbound links vs outbound links +# parse inline code +# preamble and ending file +# parse multiple terms description/definition +# header tags up to 6 #s + +def processImage(imageFile): + _, _, _, _, fileExt = mne_cpp.core.parseFilePathNameExt(imageFile) + if fileExt == "jpg" or fileExt == "jpeg": + jpg2png(imageFile) + if fileExt == "svg2": + svg2png(imageFile) + +def svg2png(file): + drawing = svg2rlg(file) + fPath, fName, _ = extractFilePathNameExt(file) + pngFile = path.join(fPath, fName + ".png") + renderPM.drawToFile(drawing, pngFile, fmt="PNG") + +def jpg2png(file): + print(file) + im1 = Image.open(file) + fPath, fName, _ = extractFilePathNameExt(file) + im1.save(path.join(fPath, fName + ".png")) + + +# imagesFolder = path.join("gh-pages", "images") +# svg2png(svgFile) +# jpg2png("gh-pages/images/1280px-EEGoSportsGUI.jpg") + +# instructions on how to install svglib correctly on ubuntu +# sudo apt-get install update +# sudo apt-get install python3 +# sudo apt-get install python3-pip +# python3 -m pip install svglib + +# then python3 pdfDocumentationGenerator.py + +# outFile = open(path.join(currentPath(),docFileName),"a+") + +# add wrapfigure to latex preamble + +