@@ -238,6 +238,7 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
238
238
frame : element . attr ( 'data-frame' ) ,
239
239
result_for : element . attr ( 'data-result-for' ) ,
240
240
options : element . attr ( 'data-options' ) ,
241
+ target : element . attr ( 'data-target' ) ,
241
242
element : element . name ,
242
243
line : element . line ,
243
244
warn : warn ,
@@ -273,6 +274,8 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
273
274
examples . values . sort_by { |ex | ex [ :number ] } . each do |ex |
274
275
next if number && number != ex [ :number ]
275
276
277
+ xpath = '//script[@type="application/ld+json"]'
278
+ xpath += %([@id="#{ ex [ :target ] [ 1 ..-1 ] } "]) if ex [ :target ]
276
279
args = [ ]
277
280
content = ex [ :content ]
278
281
@@ -316,6 +319,16 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
316
319
$stdout. write "F" . colorize ( :red )
317
320
next
318
321
end
322
+ script_content = doc . at_xpath ( xpath )
323
+ if script_content
324
+ # Remove (faked) XML comments and unescape sequences
325
+ content = script_content
326
+ . inner_html
327
+ . sub ( /^\s *< !--/ , '' )
328
+ . sub ( /-- >\s *$/ , '' )
329
+ . gsub ( /</ , '<' )
330
+ end
331
+
319
332
rescue Nokogiri ::XML ::SyntaxError => exception
320
333
errors << "Example #{ ex [ :number ] } at line #{ ex [ :line ] } parse error: #{ exception . message } "
321
334
$stdout. write "F" . colorize ( :red )
@@ -359,13 +372,13 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
359
372
360
373
# Set API to use
361
374
method = case
362
- when ex [ :compact ] then :compact
363
- when ex [ :flatten ] then :flatten
364
- when ex [ :fromRdf ] then :fromRdf
365
- when ex [ :toRdf ] then :toRdf
366
- when ex [ :ext ] == 'table' then :fromTable
367
- when ex [ :ext ] == 'json' then nil
368
- else :expand
375
+ when ex [ :compact ] then :compact
376
+ when ex [ :flatten ] then :flatten
377
+ when ex [ :fromRdf ] then :fromRdf
378
+ when ex [ :toRdf ] then :toRdf
379
+ when ex [ :ext ] == 'table' then :toRdf
380
+ when ex [ :ext ] == 'json' then nil
381
+ else :expand
369
382
end
370
383
371
384
# Set args to parse example content
@@ -395,7 +408,7 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
395
408
options [ :base ] = ex [ :base ] if ex [ :base ]
396
409
args = [ StringIO . new ( examples [ ex [ :context_for ] ] [ :content ] ) , StringIO . new ( content ) , options ]
397
410
end
398
- elsif ex [ :ext ] == 'jsonld'
411
+ elsif %w( jsonld html ) . include? ( ex [ :ext ] )
399
412
# Either exapand with this external context, or compact using it
400
413
case method
401
414
when :expand , :toRdf , :fromRdf
@@ -418,7 +431,40 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
418
431
next
419
432
end
420
433
421
- args [ 0 ] = StringIO . new ( examples [ ex [ :result_for ] ] [ :content ] )
434
+ # Set argument to referenced content to be parsed
435
+ args [ 0 ] = if examples [ ex [ :result_for ] ] [ :ext ] == 'html' && method == :expand
436
+ # If we are expanding, and the reference is HTML, find the first script element.
437
+ doc = Nokogiri ::HTML . parse ( examples [ ex [ :result_for ] ] [ :content ] )
438
+ script_content = doc . at_xpath ( xpath )
439
+ unless script_content
440
+ errors << "Example #{ ex [ :number ] } at line #{ ex [ :line ] } references example #{ ex [ :result_for ] . inspect } with no JSON-LD script element"
441
+ $stdout. write "F" . colorize ( :red )
442
+ next
443
+ end
444
+ StringIO . new ( script_content
445
+ . inner_html
446
+ . sub ( /^\s *< !--/ , '' )
447
+ . sub ( /-- >\s *$/ , '' )
448
+ . gsub ( /</ , '<' ) )
449
+ elsif examples [ ex [ :result_for ] ] [ :ext ] == 'html' && ex [ :target ]
450
+ # Only use the targeted script
451
+ doc = Nokogiri ::HTML . parse ( examples [ ex [ :result_for ] ] [ :content ] )
452
+ script_content = doc . at_xpath ( xpath )
453
+ unless script_content
454
+ errors << "Example #{ ex [ :number ] } at line #{ ex [ :line ] } references example #{ ex [ :result_for ] . inspect } with no JSON-LD script element"
455
+ $stdout. write "F" . colorize ( :red )
456
+ next
457
+ end
458
+ StringIO . new ( script_content
459
+ . to_html
460
+ . sub ( /^\s *< !--/ , '' )
461
+ . sub ( /-- >\s *$/ , '' )
462
+ . gsub ( /</ , '<' ) )
463
+ else
464
+ StringIO . new ( examples [ ex [ :result_for ] ] [ :content ] )
465
+ end
466
+
467
+ # :frame option indicates the frame to use on the referenced content
422
468
if ex [ :frame ] && !examples [ ex [ :frame ] ]
423
469
errors << "Example #{ ex [ :number ] } at line #{ ex [ :line ] } references unknown frame #{ ex [ :frame ] . inspect } "
424
470
$stdout. write "F" . colorize ( :red )
@@ -428,6 +474,7 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
428
474
args = [ args [ 0 ] , StringIO . new ( examples [ ex [ :frame ] ] [ :content ] ) , options ]
429
475
end
430
476
477
+ # :context option indicates the context to use on the referenced content
431
478
if ex [ :context ] && !examples [ ex [ :context ] ]
432
479
errors << "Example #{ ex [ :number ] } at line #{ ex [ :line ] } references unknown context #{ ex [ :context ] . inspect } "
433
480
$stdout. write "F" . colorize ( :red )
@@ -458,21 +505,22 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
458
505
end
459
506
460
507
# Generate result
508
+ # * If result_for is set, this is for the referenced example
509
+ # * otherwise, this is for this example
461
510
begin
511
+ ext = ex [ :result_for ] ? examples [ ex [ :result_for ] ] [ :ext ] : ex [ :ext ]
462
512
result = case method
463
513
when nil then nil
464
514
when :fromRdf
465
- ext = ex [ :result_for ] ? examples [ ex [ :result_for ] ] [ :ext ] : ex [ :ext ]
466
515
args [ 0 ] = RDF ::Reader . for ( file_extension : ext ) . new ( args [ 0 ] )
467
516
JSON ::LD ::API . fromRdf ( *args )
468
517
when :toRdf
469
- RDF ::Dataset . new statements : JSON ::LD ::API . toRdf ( *args )
470
- when :fromTable
471
- begin
472
- table_to_dataset ( content )
473
- rescue
474
- errors << "Example #{ ex [ :number ] } at line #{ ex [ :line ] } raised error reading table: #{ $!} "
475
- RDF ::Dataset . new
518
+ if ext == 'html'
519
+ # If the referenced example is HTML, read it using the RDFa reader
520
+ # FIXME: the API may be updated to provide a native mechanism for this
521
+ RDF ::Dataset . new statements : RDF ::RDFa ::Reader . new ( *args )
522
+ else
523
+ RDF ::Dataset . new statements : JSON ::LD ::API . toRdf ( *args )
476
524
end
477
525
else
478
526
JSON ::LD ::API . method ( method ) . call ( *args )
@@ -500,8 +548,12 @@ def save_example(examples:, element:, title:, example_number:, error:, warn:)
500
548
expected = RDF ::Dataset . new ( statements : reader )
501
549
$stderr. puts "expected:\n " + expected . to_trig if verbose
502
550
when 'table'
503
- reader = RDF ::Reader . for ( file_extension : examples [ ex [ :result_for ] ] [ :ext ] ) . new ( args [ 0 ] )
504
- expected = RDF ::Dataset . new ( statements : reader )
551
+ expected = begin
552
+ table_to_dataset ( content )
553
+ rescue
554
+ errors << "Example #{ ex [ :number ] } at line #{ ex [ :line ] } raised error reading table: #{ $!} "
555
+ RDF ::Dataset . new
556
+ end
505
557
506
558
if verbose
507
559
$stderr. puts "expected:\n " + expected . to_trig
0 commit comments