From c326b61f78a15825443c31f9b88b6eca00e78a17 Mon Sep 17 00:00:00 2001 From: Romain Michon Date: Mon, 29 May 2017 13:24:04 +0200 Subject: [PATCH] Documenting dx7.lib --- README.md | 25 ++--- dx7.lib | 277 ++++++++++++++++++++++++++++++++++++++++++++++------ generateDoc | 12 +-- 3 files changed, 266 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 62c19f64..74e00cf9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ NOTE: this documentation was automatically generated. -This page provides information on how to use the Faust libraries. +This page provides information on how to use the Faust libraries. The `/libraries` folder contains the different Faust libraries. If you wish to add your own functions to this library collection, you can refer to the "Contributing" section providing a set of coding conventions. @@ -24,6 +24,7 @@ This will give you access to all the Faust libraries through a series of environ * `co`: `compressors.lib` * `de`: `delays.lib` * `dm`: `demos.lib` +* `dx`: `dx7.lib` * `en`: `envelopes.lib` * `fi`: `filters.lib` * `ho`: `hoa.lib` @@ -81,9 +82,9 @@ If you wish to add a function to any of these libraries or if you plan to add a ``` //-----------------functionName-------------------- // Description -// +// // #### Usage -// +// // ``` // Usage Example // ``` @@ -104,13 +105,13 @@ If you wish to add a function to any of these libraries or if you plan to add a * Any new "standard" library should be declared in `stdfaust.lib` with its own environment (2 letters - see `stdfaust.lib`). * Any new "standard" library must be added to `generateDoc`. * Functions must be organized by sections. -* Any new library should at least `declare` a `name` and a `version`. +* Any new library should at least `declare` a `name` and a `version`. * The comment based markdown documentation of each library must respect the following format (open the source code of any of the libraries for an example): ``` //############### libraryName ################## // Description -// +// // * Section Name 1 // * Section Name 2 // * ... @@ -141,11 +142,12 @@ If you wish to add a function to any of these libraries or if you plan to add a Only the libraries that are considered to be "standard" are documented: -* `analyzers.lib` -* `basics.lib` +* `analyzers.lib` +* `basics.lib` * `compressors.lib` * `delays.lib` * `demos.lib` +* `dx7.lib` * `envelopes.lib` * `filters.lib` * `hoa.lib` @@ -164,11 +166,11 @@ Only the libraries that are considered to be "standard" are documented: * `tubes.lib` (not documented but example in `/examples/misc`) * `vaeffects.lib` -Other deprecated libraries such as `music.lib`, etc. are present but are not documented to not confuse new users. +Other deprecated libraries such as `music.lib`, etc. are present but are not documented to not confuse new users. The doumentation of each library can be found in `/documentation/library.html` or in `/documentation/library.pdf`. -The `/examples` directory contains all the examples from the `/examples` folder of the Faust distribution as well as new ones. Most of them were updated to reflect the coding conventions described in the next section. Examples are organized by types in different folders. The `/old` folder contains examples that are fully deprecated, probably because they were integrated to the libraries and fully rewritten (see `freeverb.dsp` for example). Examples using deprecated libraries were integrated to the general tree but a warning comment was added at their beginning to point readers to the right library and function. +The `/examples` directory contains all the examples from the `/examples` folder of the Faust distribution as well as new ones. Most of them were updated to reflect the coding conventions described in the next section. Examples are organized by types in different folders. The `/old` folder contains examples that are fully deprecated, probably because they were integrated to the libraries and fully rewritten (see `freeverb.dsp` for example). Examples using deprecated libraries were integrated to the general tree but a warning comment was added at their beginning to point readers to the right library and function. ## Coding Conventions @@ -179,7 +181,7 @@ In order to have a uniformized library system, we established the following conv * All the functions that we want to be "public" are documented. * We used the `faust2md` "standards" for each library: `//###` for main title (library name - equivalent to `#` in markdown), `//===` for section declarations (equivalent to `##` in markdown) and `//---` for function declarations (equivalent to `####` in markdown - see `basics.lib` for an example). * Sections in function documentation should be declared as `####` markdown title. -* Each function documentation provides a "Usage" section (see `basics.lib`). +* Each function documentation provides a "Usage" section (see `basics.lib`). ### Library Import @@ -191,6 +193,7 @@ ba = library("basics.lib"); co = library("compressors.lib"); de = library("delays.lib"); dm = library("demos.lib"); +dx = library("dx7.lib"); en = library("envelopes.lib"); fi = library("filters.lib"); ho = library("hoa.lib"); @@ -220,7 +223,7 @@ This standard is only used within the libraries: nothing prevents coders to stil ### "Demo" Functions -"Demo" functions are placed in `demos.lib` and have a built-in user interface (UI). Their name ends with the `_demo` suffix. Each of these function have a `.dsp` file associated to them in the `/examples` folder. +"Demo" functions are placed in `demos.lib` and have a built-in user interface (UI). Their name ends with the `_demo` suffix. Each of these function have a `.dsp` file associated to them in the `/examples` folder. Any function containing UI elements should be placed in this library and respect these standards. diff --git a/dx7.lib b/dx7.lib index 6d6de7a5..db54fbff 100644 --- a/dx7.lib +++ b/dx7.lib @@ -1,10 +1,51 @@ //##################################### dx7.lib ################################ -// DX7 emulation library. This library is under development. +// Yamaha DX7 emulation library. The various functions available in this library +// are used by the libraries generated from `.syx` DX7 preset files. This +// toolkit was greatly inspired by the CSOUND DX7 emulation package: +// . +// +// This library and its related tools are under development. Use it at your +// own risk! //############################################################################## + +/************************************************************************ +************************************************************************ +FAUST library file, GRAME section + +Except where noted otherwise, Copyright (C) 2003-2017 by GRAME, +Centre National de Creation Musicale. +---------------------------------------------------------------------- +GRAME LICENSE + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as +published by the Free Software Foundation; either version 2.1 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with the GNU C Library; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +EXCEPTION TO THE LGPL LICENSE : As a special exception, you may create a +larger FAUST program which directly or indirectly imports this library +file and still distribute the compiled code generated by the FAUST +compiler, or a modified version of this compiled code, under your own +copyright and license. This EXCEPTION TO THE LGPL LICENSE explicitly +grants you the right to freely choose the license for the resulting +compiled code. In particular the resulting compiled code has no obligation +to be LGPL or GPL. For example you are free to choose a commercial or +closed source license or any other license if you decide so. +************************************************************************ +************************************************************************/ + /* TODO: - * Talk about inspiration from CSOUND - * Put links to the CSOUND project * LFO not implemented yet * The whole system needs some tuning */ @@ -15,7 +56,22 @@ ma = library("maths.lib"); os = library("oscillators.lib"); //----------------------`dx7_ampf`-------------------------- -// TODO +// DX7 amplitude conversion function. 3 versions of this function +// are available: +// +// * `dx7_amp_bpf`: BPF version (same as in the CSOUND toolkit) +// * `dx7_amp_func`: estimated mathematical equivalent of `dx7_amp_bpf` +// * `dx7_ampf`: default (sugar for `dx7_amp_func`) +// +// #### Usage: +// +// ``` +// dx7AmpPreset : dx7_ampf_bpf : _ +// ``` +// +// Where: +// +// * `dx7AmpPreset`: DX7 amplitude value (0-99) //---------------------------------------------------------- // CSOUND function implemented as a BPF // Corresponds to F2 in the CSOUND implementation. @@ -29,8 +85,23 @@ dx7_amp_func = min(98)/98 : pow(_,8); dx7_ampf = dx7_amp_func; //----------------------`dx7_egraterisef`-------------------------- -// TODO -//----------------------------------------------------------------- +// DX7 envelope generator rise conversion function. 3 versions of this function +// are available: +// +// * `dx7_egraterise_bpf`: BPF version (same as in the CSOUND toolkit) +// * `dx7_egraterise_func`: estimated mathematical equivalent of `dx7_egraterise_bpf` +// * `dx7_egraterisef`: default (sugar for `dx7_egraterise_func`) +// +// #### Usage: +// +// ``` +// dx7envelopeRise : dx7_egraterisef : _ +// ``` +// +// Where: +// +// * `dx7envelopeRise`: DX7 envelope rise value (0-99) +//---------------------------------------------------------- // CSOUND function implemented as a BPF // Corresponds to F4 in the CSOUND implementation. dx7_egraterise_bpf = ba.bpf.start(0,38) : seq(i,24,ba.bpf.point(xPoints(i)+1,yPoints(i))) : ba.bpf.end(127,0.003) @@ -45,9 +116,24 @@ with{ dx7_egraterise_func = 38*pow((127-_)/127,12) : max(0.003); dx7_egraterisef = dx7_egraterise_func; -//---------------------`dx7_egraterisepercf`----------------------- -// TODO -//----------------------------------------------------------------- +//----------------------`dx7_egraterisepercf`-------------------------- +// DX7 envelope generator percussive rise conversion function. 3 versions of +// this function are available: +// +// * `dx7_egrateriseperc_bpf`: BPF version (same as in the CSOUND toolkit) +// * `dx7_egrateriseperc_func`: estimated mathematical equivalent of `dx7_egrateriseperc_bpf` +// * `dx7_egraterisepercf`: default (sugar for `dx7_egrateriseperc_func`) +// +// #### Usage: +// +// ``` +// dx7envelopePercRise : dx7_egraterisepercf : _ +// ``` +// +// Where: +// +// * `dx7envelopePercRise`: DX7 envelope percussive rise value (0-99) +//---------------------------------------------------------- // CSOUND function implemented as a BPF // Corresponds to F5 in the CSOUND implementation. dx7_egrateriseperc_bpf = ba.bpf.start(0,0.00001) : seq(i,10,ba.bpf.point(xPoints(i)+1,yPoints(i))) : ba.bpf.end(127,1) @@ -59,9 +145,24 @@ with{ dx7_egrateriseperc_func = >=(30)*min(_-30,68)/68 : pow(_,1.8); dx7_egraterisepercf = dx7_egrateriseperc_func; -//------------------------`dx7_egratedecayf`----------------------- -// TODO -//----------------------------------------------------------------- +//----------------------`dx7_egratedecayf`-------------------------- +// DX7 envelope generator decay conversion function. 3 versions of +// this function are available: +// +// * `dx7_egratedecay_bpf`: BPF version (same as in the CSOUND toolkit) +// * `dx7_egratedecay_func`: estimated mathematical equivalent of `dx7_egratedecay_bpf` +// * `dx7_egratedecayf`: default (sugar for `dx7_egratedecay_func`) +// +// #### Usage: +// +// ``` +// dx7envelopeDecay : dx7_egratedecayf : _ +// ``` +// +// Where: +// +// * `dx7envelopeDecay`: DX7 envelope decay value (0-99) +//---------------------------------------------------------- // CSOUND function implemented as a BPF // Corresponds to F6 in the CSOUND implementation. dx7_egratedecay_bpf = ba.bpf.start(0,318) : seq(i,23,ba.bpf.point(xPoints(i)+1,yPoints(i))) : ba.bpf.end(127,.008) @@ -75,9 +176,24 @@ with{ dx7_egratedecay_func = 318*pow((127-_)/127,12.6) : max(0.008); dx7_egratedecayf = dx7_egratedecay_func; -//------------------------`dx7_egratedecaypercf`------------------- -// TODO -//----------------------------------------------------------------- +//----------------------`dx7_egratedecaypercf`-------------------------- +// DX7 envelope generator percussive decay conversion function. 3 versions of +// this function are available: +// +// * `dx7_egratedecayperc_bpf`: BPF version (same as in the CSOUND toolkit) +// * `dx7_egratedecayperc_func`: estimated mathematical equivalent of `dx7_egratedecayperc_bpf` +// * `dx7_egratedecaypercf`: default (sugar for `dx7_egratedecayperc_func`) +// +// #### Usage: +// +// ``` +// dx7envelopePercDecay : dx7_egratedecaypercf : _ +// ``` +// +// Where: +// +// * `dx7envelopePercDecay`: DX7 envelope decay value (0-99) +//---------------------------------------------------------- // CSOUND function implemented as a BPF // Corresponds to F7 in the CSOUND implementation. dx7_egratedecayperc_bpf = ba.bpf.start(0,0.00001) : seq(i,10,ba.bpf.point(xPoints(i),yPoints(i))) : ba.bpf.end(127,1) @@ -89,9 +205,24 @@ with{ dx7_egratedecayperc_func = min(99)/99 : pow(_,0.7); dx7_egratedecaypercf = dx7_egratedecayperc_func; -//--------------------------`dx7_eglv2peakf`----------------------- -// TODO -//----------------------------------------------------------------- +//----------------------`dx7_eglv2peakf`-------------------------- +// DX7 envelope level to peak conversion function. 3 versions of +// this function are available: +// +// * `dx7_eglv2peak_bpf`: BPF version (same as in the CSOUND toolkit) +// * `dx7_eglv2peak_func`: estimated mathematical equivalent of `dx7_eglv2peak_bpf` +// * `dx7_eglv2peakf`: default (sugar for `dx7_eglv2peak_func`) +// +// #### Usage: +// +// ``` +// dx7Level : dx7_eglv2peakf : _ +// ``` +// +// Where: +// +// * `dx7Level`: DX7 level value (0-99) +//----------------------------------------------------------- // CSOUND function implemented as a BPF // Corresponds to F8 in the CSOUND implementation. dx7_eglv2peak_bpf = ba.bpf.start(0,0) : seq(i,14,ba.bpf.point(xPoints(i)+1,yPoints(i))) : ba.bpf.end(127,2.08795) @@ -103,21 +234,66 @@ with{ dx7_eglv2peak_func = min(98)/98 : pow(_,8) : *(2.08795); dx7_eglv2peakf = dx7_eglv2peak_func; -//----------------------------`dx7_velsensf`----------------------- -// TODO -//----------------------------------------------------------------- +//----------------------`dx7_velsensf`-------------------------- +// DX7 velocity sensitivity conversion function. +// +// #### Usage: +// +// ``` +// dx7Velocity : dx7_velsensf : _ +// ``` +// +// Where: +// +// * `dx7Velocity`: DX7 level value (0-8) +//----------------------------------------------------------- // Corresponds to F10 in the CSOUND implementation dx7_velsensf = /(8); -//--------------------------`dx7_fdbkscalef`----------------------- -// TODO -//----------------------------------------------------------------- +//----------------------`dx7_fdbkscalef`-------------------------- +// DX7 feedback scaling conversion function. +// +// #### Usage: +// +// ``` +// dx7Feedback : dx7_fdbkscalef : _ +// ``` +// +// Where: +// +// * `dx7Feedback`: DX7 feedback value +//----------------------------------------------------------- // Corresponds to F11 in the CSOUND implementation dx7_fdbkscalef = *(0.875); //------------------------------`dx7_op`--------------------------- -// DX7 Operator. -// TODO: more +// DX7 Operator. Implements a phase-modulable sine wave oscillator connected +// to a DX7 envelope generator. +// +// #### Usage: +// +// ``` +// dx7_op(freq,phaseMod,outLev,R1,R2,R3,R4,L1,L2,L3,L4,keyVel,rateScale,type,gain,gate) : _ +// ``` +// +// Where: +// +// * `freq`: frequency of the oscillator +// * `phaseMod`: phase deviation (-1 - 1) +// * `outLev`: preset output level (0-99) +// * `R1`: preset envelope rate 1 (0-99) +// * `R2`: preset envelope rate 2 (0-99) +// * `R3`: preset envelope rate 3 (0-99) +// * `R4`: preset envelope rate 4 (0-99) +// * `L1`: preset envelope level 1 (0-99) +// * `L2`: preset envelope level 2 (0-99) +// * `L3`: preset envelope level 3 (0-99) +// * `L4`: preset envelope level 4 (0-99) +// * `keyVel`: preset key velocity sensitivity (0-99) +// * `rateScale`: preset envelope rate scale +// * `type`: preset operator type +// * `gain`: general gain +// * `gate`: trigger signal //----------------------------------------------------------------- dx7_op(freq,phaseMod,outLev,R1,R2,R3,R4,L1,L2,L3,L4,keyVel,rateScale,type,gain,gate) = (en.dx7envelope(egr1,egr2,egr3,egr4,egl1,egl2,egl3,egl4,gate) : envTable)*sineWave @@ -158,8 +334,40 @@ with{ }; //------------------------------`dx7_algo`--------------------------- -// DX7 Algorithms -// TODO: more +// DX7 algorithms. Implements the 32 DX7 algorithms (a quick Google search +// should give your more details on this). Each algorithm uses 6 operators +// +// #### Usage: +// +// ``` +// dx7_algo(algN,egR1,egR2,egR3,egR4,egL1,egL2,egL3,egL4,outLevel,keyVelSens,ampModSens,opMode,opFreq,opDetune,opRateScale,feedback,lfoDelay,lfoDepth,lfoSpeed,freq,gain,gate) : _ +// ``` +// +// Where: +// +// * `algN`: algorithm number (0-31, should be an int...) +// * `egR1`: preset envelope rates 1 (a list of 6 values between 0-99) +// * `egR2`: preset envelope rates 2 (a list of 6 values between 0-99) +// * `egR3`: preset envelope rates 3 (a list of 6 values between 0-99) +// * `egR4`: preset envelope rates 4 (a list of 6 values between 0-99) +// * `egL1`: preset envelope levels 1 (a list of 6 values between 0-99) +// * `egL2`: preset envelope levels 2 (a list of 6 values between 0-99) +// * `egL3`: preset envelope levels 3 (a list of 6 values between 0-99) +// * `egL4`: preset envelope levels 4 (a list of 6 values between 0-99) +// * `outLev`: preset output levels (a list of 6 values between 0-99) +// * `keyVel`: preset key velocity sensitivities (a list of 6 values between 0-99) +// * `ampModSens`: preset amplitude sensitivities (a list of 6 values between 0-99) +// * `opMode`: preset operator mode (a list of 6 values between 0-1) +// * `opFreq`: preset operator frequencies (a list of 6 values between 0-99) +// * `opDetune`: preset operator detuning (a list of 6 values between 0-99) +// * `opRateScale`: preset operator rate scale (a list of 6 values between 0-99) +// * `feedback`: preset operator feedback (a list of 6 values between 0-99) +// * `lfoDelay`: preset LFO delay (a list of 6 values between 0-99) +// * `lfoDepth`: preset LFO depth (a list of 6 values between 0-99) +// * `lfoSpeed`: preset LFO speed (a list of 6 values between 0-99) +// * `freq`: fundamental frequency +// * `gain`: general gain +// * `gate`: trigger signal //----------------------------------------------------------------- // Alg 1 @@ -767,10 +975,17 @@ with{ }; //------------------------------`dx7_ui`--------------------------- -// DX7 with parameters controllable by a UI. -// TODO: more. +// Generic DX7 function where all parameters are controllable using UI elements. +// The `master-with-mute` branch must be used for this function to work... +// This function is MIDI-compatible. +// +// #### Usage +// +// ``` +// dx7_ui : _ +// ``` //----------------------------------------------------------------- -dx7_ui(freq,gain,gate) = +dx7_ui = par(i,32,dx7_algo(i,egR1,egR2,egR3,egR4,egL1,egL2,egL3,egL4,outLevel,keyVelSens,ampModSens,opMode,opFreq,opDetune,opRateScale,feedback,lfoDelay,lfoDepth,lfoSpeed,freq,gain,gate) : control(algorithm == i)) :> _ with{ algorithm = nentry("h:dx7/v:global/[0]algorithm",0,0,31,1) : int; diff --git a/generateDoc b/generateDoc index 2aaa156b..7014c9dd 100755 --- a/generateDoc +++ b/generateDoc @@ -11,7 +11,7 @@ for p in $@; do fi done -FILES="analyzers.lib basics.lib compressors.lib delays.lib demos.lib envelopes.lib filters.lib hoa.lib maths.lib misceffects.lib oscillators.lib noises.lib phaflangers.lib physmodels.lib reverbs.lib routes.lib signals.lib spats.lib synths.lib vaeffects.lib" +FILES="analyzers.lib basics.lib compressors.lib delays.lib demos.lib dx7.lib envelopes.lib filters.lib hoa.lib maths.lib misceffects.lib oscillators.lib noises.lib phaflangers.lib physmodels.lib reverbs.lib routes.lib signals.lib spats.lib synths.lib vaeffects.lib" mkdir tmp mkdir tmp/title @@ -31,18 +31,18 @@ done # Reformatting the html file with the right template if [ $PLATFORM = "Darwin" ]; then (sed -i "" "s//<title>Faust Libraries Documentation/g" "$DOCFOLDER/library.html") || exit - (sed -i "" "s/<style type=\"text\/css\">code{white-space: pre;}<\/style>/<\/style><link rel=\"stylesheet\" href=\"http:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.7\/css\/bootstrap.min.css\"><script src=\"https:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/1.12.4\/jquery.min.js\">\n<\/script><script src=\"http:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.7\/js\/bootstrap.min.js\"><\/script>/g" "$DOCFOLDER/library.html") || exit - (sed -i "" "s/<body>/<div class=\"container\"><div class=\"row\" style=\"height: 100vh;\">/g" "$DOCFOLDER/library.html") || exit + (sed -i "" "s/<style type=\"text\/css\">code{white-space: pre;}<\/style>/<\/style><link rel=\"stylesheet\" href=\"http:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.7\/css\/bootstrap.min.css\"><script src=\"https:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/1.12.4\/jquery.min.js\">\n<\/script><script src=\"http:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.7\/js\/bootstrap.min.js\"><\/script>/g" "$DOCFOLDER/library.html") || exit + (sed -i "" "s/<body>/<div class=\"container\"><div class=\"row\" style=\"height: 100vh;\">/g" "$DOCFOLDER/library.html") || exit (sed -i "" "s/<\/body>/<\/div><\/div><\/body>/g" "$DOCFOLDER/library.html") || exit (sed -i "" "s/<div id=\"TOC\">/<div class=\"col-sm-4\" id=\"TOC\" style=\"height: 100%;overflow: scroll;\">/g" "$DOCFOLDER/library.html") || exit (sed -i "" "s/<h1 id=\"faust-libraries\">Faust Libraries<\/h1>/<div class=\"col-sm-8\" style=\"height: 100%;overflow-y: scroll\"><h1 id=\"faust-libraries\">Faust Libraries<\/h1>/g" "$DOCFOLDER/library.html") || exit else (sed -i 's/<title>/<title>Faust Libraries Documentation/g' "$DOCFOLDER/library.html") || exit - (sed -i 's/<style type=\"text\/css\">code{white-space: pre;}<\/style>/<\/style><link rel=\"stylesheet\" href=\"http:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.7\/css\/bootstrap.min.css\"><script src=\"https:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/1.12.4\/jquery.min.js\">\n<\/script><script src=\"http:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.7\/js\/bootstrap.min.js\"><\/script>/g' "$DOCFOLDER/library.html") || exit - (sed -i 's/<body>/<div class=\"container\"><div class=\"row\" style=\"height: 100vh;\">/g' "$DOCFOLDER/library.html") || exit + (sed -i 's/<style type=\"text\/css\">code{white-space: pre;}<\/style>/<\/style><link rel=\"stylesheet\" href=\"http:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.7\/css\/bootstrap.min.css\"><script src=\"https:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/1.12.4\/jquery.min.js\">\n<\/script><script src=\"http:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.7\/js\/bootstrap.min.js\"><\/script>/g' "$DOCFOLDER/library.html") || exit + (sed -i 's/<body>/<div class=\"container\"><div class=\"row\" style=\"height: 100vh;\">/g' "$DOCFOLDER/library.html") || exit (sed -i 's/<\/body>/<\/div><\/div><\/body>/g' "$DOCFOLDER/library.html") || exit (sed -i 's/<div id=\"TOC\">/<div class=\"col-sm-4\" id=\"TOC\" style=\"height: 100%;overflow: scroll;\">/g' "$DOCFOLDER/library.html") || exit (sed -i 's/<h1 id=\"faust-libraries\">Faust Libraries<\/h1>/<div class=\"col-sm-8\" style=\"height: 100%;overflow-y: scroll\"><h1 id=\"faust-libraries\">Faust Libraries<\/h1>/g' "$DOCFOLDER/library.html") || exit fi - + rm -r tmp