@@ -156,17 +156,16 @@ Plugin.prototype.copyAssets = function(out, options) {
156156// Install a list of plugin
157157Plugin . install = function ( options ) {
158158 // Normalize list of plugins
159- var plugins = Plugin . normalizeNames ( options . plugins ) ;
159+ var plugins = Plugin . normalizeList ( options . plugins ) ;
160160
161- // Remove defaults plugins
162- plugins = _ . without . apply ( null , [ plugins ] . concat ( Plugin . defaults ) ) ;
163-
164- return _ . reduce ( plugins , function ( prev , name ) {
161+ // Install plugins one by one
162+ return _ . reduce ( plugins , function ( prev , plugin ) {
165163 return prev . then ( function ( ) {
166- var fullname = "gitbook-plugin-" + name ;
167- console . log ( "Install plugin" , name , "from npm (" + fullname + ")" ) ;
164+ var fullname = "gitbook-plugin-" + plugin . name ;
165+ console . log ( "Install plugin" , plugin . name , "from npm (" + fullname + ") with version" , ( plugin . version || "*" ) ) ;
168166 return Q . nfcall ( npmi , {
169167 'name' : fullname ,
168+ 'version' : plugin . version ,
170169 'path' : options . input ,
171170 'npmLoad' : {
172171 'loglevel' : 'silent' ,
@@ -178,33 +177,49 @@ Plugin.install = function(options) {
178177 } , Q ( ) ) ;
179178} ;
180179
181- // Normalize a list of plugin name to use
182- Plugin . normalizeNames = function ( names ) {
180+ // Normalize a list of plugins to use
181+ Plugin . normalizeList = function ( plugins ) {
183182 // Normalize list to an array
184- names = _ . isString ( names ) ? names . split ( "," ) : ( names || [ ] ) ;
183+ plugins = _ . isString ( plugins ) ? plugins . split ( "," ) : ( plugins || [ ] ) ;
184+
185+ // Divide as {name, version} to handle format like "[email protected] " 186+ plugins = _ . map ( plugins , function ( plugin ) {
187+ var parts = plugin . split ( "@" ) ;
188+ return {
189+ 'name' : parts [ 0 ] ,
190+ 'version' : parts [ 1 ] // optional
191+ }
192+ } ) ;
185193
186194 // List plugins to remove
187- var toremove = _ . chain ( names )
188- . filter ( function ( name ) {
189- return name . length > 0 && name [ 0 ] == "-" ;
195+ var toremove = _ . chain ( plugins )
196+ . filter ( function ( plugin ) {
197+ return plugin . name . length > 0 && plugin . name [ 0 ] == "-" ;
190198 } )
191- . map ( function ( name ) {
192- return name . slice ( 1 ) ;
199+ . map ( function ( plugin ) {
200+ return plugin . name . slice ( 1 ) ;
193201 } )
194202 . value ( ) ;
195203
196204 // Merge with defaults
197- names = _ . chain ( names )
198- . concat ( Plugin . defaults )
205+ plugins = _ . chain ( plugins )
206+ . concat ( _ . map ( Plugin . defaults , function ( plugin ) {
207+ return { 'name' : plugin }
208+ } ) )
199209 . uniq ( )
200210 . value ( ) ;
201211
202- // Remove plugins starting with
203- names = _ . filter ( names , function ( name ) {
204- return ! _ . contains ( toremove , name ) && ! ( name . length > 0 && name [ 0 ] == "-" ) ;
212+ // Build final list
213+ plugins = _ . filter ( plugins , function ( plugin ) {
214+ return ! _ . contains ( toremove , plugin . name ) && ! ( plugin . name . length > 0 && plugin . name [ 0 ] == "-" ) ;
205215 } ) ;
206216
207- return names ;
217+ return plugins ;
218+ } ;
219+
220+ // Normalize a list of plugin name to use
221+ Plugin . normalizeNames = function ( plugins ) {
222+ return _ . pluck ( Plugin . normalizeList ( plugins ) , "name" ) ;
208223} ;
209224
210225// Extract data from a list of plugin
@@ -302,7 +317,7 @@ Plugin.fromList = function(names, root, generator, options) {
302317 } ) ;
303318} ;
304319
305- // Default plugins
320+ // Default plugins added to each books
306321Plugin . defaults = [
307322 "mathjax"
308323] ;
0 commit comments