@@ -263,6 +263,10 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
263263 return sheet [ ref ] ?. v ;
264264 }
265265
266+ to_base64 ( ) {
267+ const buffer = XLSX . write ( this . wb , { type : 'array' , bookType : 'xlsx' } ) ;
268+ return encode_array ( buffer ) ;
269+ }
266270 }
267271
268272 const { TString, TList, TDict, THTML } = Numbas . jme . types ;
@@ -277,9 +281,6 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
277281 TSpreadsheet ,
278282 'spreadsheet' ,
279283 {
280- 'list' : function ( s ) {
281- // TODO
282- } ,
283284 'html' : function ( s ) {
284285 const e = document . createElement ( 'spread-sheet' ) ;
285286 e . setAttribute ( 'disabled' , true ) ;
@@ -301,8 +302,7 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
301302 return '\\text{Spreadsheet}' ;
302303 } ,
303304 jme : ( tree , tok , bits ) => {
304- // TODO
305- return 'spreadsheet()' ;
305+ return 'spreadsheet_from_base64_file("sheet.xlsx",safe("' + Numbas . jme . escape ( tok . value . to_base64 ( ) ) + '"))' ;
306306 }
307307 } ) ;
308308
@@ -315,7 +315,7 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
315315 } ;
316316 return new TSpreadsheet ( new Workbook ( workbook ) ) ;
317317 } ,
318- { unwrapValues : true }
318+ { unwrapValues : true , random : false }
319319 ) ) ;
320320
321321 sheets . scope . addFunction ( new jme . funcObj ( 'spreadsheet' , [ 'list of list' ] , TSpreadsheet ,
@@ -327,22 +327,22 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
327327 } ;
328328 return new TSpreadsheet ( new Workbook ( workbook ) ) ;
329329 } ,
330- { unwrapValues : true }
330+ { unwrapValues : true , random : false }
331331 ) ) ;
332332
333333 sheets . scope . addFunction ( new jme . funcObj ( 'spreadsheet_from_base64_file' , [ 'string' , 'string' ] , TSpreadsheet ,
334334 ( filename , base64 ) => {
335335 const data = decode_array ( base64 ) ;
336336 return new TSpreadsheet ( new Workbook ( XLSX . read ( data , { sheetStubs : true } ) ) ) ;
337337 } ,
338- { unwrapValues : true }
339- ) )
338+ { unwrapValues : true , random : false }
339+ ) ) ;
340340
341341 sheets . scope . addFunction ( new jme . funcObj ( 'update_range' , [ TSpreadsheet , TString , TDict ] , TSpreadsheet ,
342342 ( spreadsheet , range_string , changes ) => {
343343 return new TSpreadsheet ( spreadsheet . update_range ( range_string , changes ) ) ;
344344 } ,
345- { unwrapValues : true }
345+ { unwrapValues : true , random : false }
346346 ) ) ;
347347
348348 sheets . scope . addFunction ( new jme . funcObj ( 'update_range' , [ TSpreadsheet , 'list of string' , TDict ] , TSpreadsheet ,
@@ -353,7 +353,7 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
353353 }
354354 return new TSpreadsheet ( wb ) ;
355355 } ,
356- { unwrapValues : true }
356+ { unwrapValues : true , random : false }
357357 ) ) ;
358358
359359 sheets . scope . addFunction ( new jme . funcObj ( 'disable_cells' , [ TSpreadsheet , 'list of string' ] , TSpreadsheet ,
@@ -364,7 +364,7 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
364364 }
365365 return new TSpreadsheet ( wb ) ;
366366 } ,
367- { unwrapValues : true }
367+ { unwrapValues : true , random : false }
368368 ) ) ;
369369
370370 sheets . scope . addFunction ( new jme . funcObj ( 'fill_range' , [ TSpreadsheet , TString , 'list of (string or number)' ] , TSpreadsheet ,
@@ -379,13 +379,13 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
379379 }
380380 return new TSpreadsheet ( spreadsheet . fill_range ( range , values ) ) ;
381381 } ,
382- { unwrapValues : true }
382+ { unwrapValues : true , random : false }
383383 ) ) ;
384384 sheets . scope . addFunction ( new jme . funcObj ( 'fill_range' , [ TSpreadsheet , TString , 'list of list of (string or number)' ] , TSpreadsheet ,
385385 ( spreadsheet , range , values ) => {
386386 return new TSpreadsheet ( spreadsheet . fill_range ( range , values ) ) ;
387387 } ,
388- { unwrapValues : true }
388+ { unwrapValues : true , random : false }
389389 ) ) ;
390390
391391 /** Interpret a range string and return a list of the cells it contains.
@@ -400,12 +400,13 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
400400 }
401401 }
402402 return out ;
403- }
403+ } ,
404+ { random : false }
404405 ) ) ;
405406
406407 sheets . scope . addFunction ( new jme . funcObj ( 'slice' , [ TSpreadsheet , TString ] , TSpreadsheet , ( wb , range ) => {
407408 return wb . slice ( range ) ;
408- } ) ) ;
409+ } , { random : false } ) ) ;
409410
410411 sheets . scope . addFunction ( new jme . funcObj ( 'listval' , [ TSpreadsheet , TString ] , '?' , null , {
411412 evaluate : function ( args , scope ) {
@@ -446,12 +447,13 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
446447 } else {
447448 return new TString ( ( wb . get_cell_value ( sheet , ref ) || '' ) + '' ) ;
448449 }
449- }
450+ } ,
451+ random : false
450452 } ) ) ;
451453
452454 sheets . scope . addFunction ( new jme . funcObj ( 'encode_range' , [ 'integer' , 'integer' , 'integer' , 'integer' ] , TString , ( cs , rs , ce , re ) => {
453455 return XLSX . utils . encode_range ( { s :{ c :cs , r :rs } , e :{ c :ce , r :re } } ) ;
454- } ) ) ;
456+ } , { random : false } ) ) ;
455457
456458 /**
457459 * Create an ArrayBuffer containing the given string.
@@ -483,21 +485,21 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
483485 link . innerHTML = `Download <code>${ filename } </code>` ;
484486
485487 return link ;
486- } ) ) ;
488+ } , { random : false } ) ) ;
487489
488490 function add_style_function ( name , args , fn ) {
489491 args = args . slice ( ) ;
490492 sheets . scope . addFunction ( new jme . funcObj ( name , args , TDict , function ( ...args ) {
491493 var style = fn ( ...args ) ;
492494 return jme . wrapValue ( { style : style } ) ;
493- } , { unwrapValues : true } ) ) ;
495+ } , { unwrapValues : true , random : false } ) ) ;
494496
495497 var dargs = args . slice ( ) ;
496498 dargs . splice ( 0 , 0 , 'dict' ) ;
497499 sheets . scope . addFunction ( new jme . funcObj ( name , dargs , TDict , function ( pd , ...args ) {
498500 var style = fn ( ...args ) ;
499501 return jme . wrapValue ( Numbas . util . deep_extend_object ( pd , { style : style } ) ) ;
500- } , { unwrapValues : true } ) ) ;
502+ } , { unwrapValues : true , random : false } ) ) ;
501503 }
502504
503505 function css_color_to_rgba ( color ) {
@@ -555,7 +557,7 @@ Numbas.addExtension('sheets', ['display', 'util', 'jme','sheet-element', 'xlsx']
555557 'number' : 'n'
556558 } ;
557559 return jme . wrapValue ( { t : types_map [ type ] || type } ) ;
558- } , { unwrapValues : true } ) ) ;
560+ } , { unwrapValues : true , random : false } ) ) ;
559561
560562 if ( Numbas . editor ?. register_variable_template_type !== undefined ) {
561563 class SpreadsheetVariableTemplateWidget extends HTMLElement {
0 commit comments