Class: IpynbDiff::Transformer

Inherits:
Object
  • Object
show all
Includes:
SymbolizedMarkdownHelper
Defined in:
lib/transformer.rb

Overview

Returns a markdown version of the Jupyter Notebook

Instance Method Summary collapse

Methods included from SymbolizedMarkdownHelper

#_, #array_if_not_array, #symbolize_array

Constructor Details

#initialize(include_frontmatter: true, hide_images: false) ⇒ Transformer

Returns a new instance of Transformer.



20
21
22
23
24
# File 'lib/transformer.rb', line 20

def initialize(include_frontmatter: true, hide_images: false)
  @include_frontmatter = include_frontmatter
  @hide_images = hide_images
  @output_transformer = OutputTransformer.new(hide_images: hide_images)
end

Instance Method Details

#decorate_cell(rows, cell, symbol) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/transformer.rb', line 57

def decorate_cell(rows, cell, symbol)
  tags = cell['metadata']&.fetch('tags', [])
  type = cell['cell_type'] || 'raw'

  [
    _(symbol, %(%% Cell type:#{type} id:#{cell['id']} tags:#{tags&.join(',')})),
    _,
    rows,
    _
  ]
end

#transform(notebook) ⇒ Object



36
37
38
39
40
41
42
43
44
# File 'lib/transformer.rb', line 36

def transform(notebook)
  return TransformedNotebook.new unless notebook

  notebook_json = validate_notebook(notebook)
  transformed = transform_document(notebook_json)
  symbol_map = IpynbSymbolMap.parse(notebook)

  TransformedNotebook.new(transformed, symbol_map)
end

#transform_cell(cell, notebook, symbol) ⇒ Object



69
70
71
# File 'lib/transformer.rb', line 69

def transform_cell(cell, notebook, symbol)
  cell['cell_type'] == 'code' ? transform_code_cell(cell, notebook, symbol) : transform_text_cell(cell, symbol)
end

#transform_code_cell(cell, notebook, symbol) ⇒ Object



73
74
75
76
77
78
79
80
81
82
# File 'lib/transformer.rb', line 73

def transform_code_cell(cell, notebook, symbol)
  [
    _(symbol / 'source', %(``` #{notebook.dig('metadata', 'kernelspec', 'language') || ''})),
    symbolize_array(symbol / 'source', cell['source'], &:rstrip),
    _(nil, '```'),
    cell['outputs'].map.with_index do |output, idx|
      @output_transformer.transform(output, symbol / ['outputs', idx])
    end
  ]
end

#transform_document(notebook) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/transformer.rb', line 46

def transform_document(notebook)
  symbol = JsonSymbol.new('.cells')

  transformed_blocks = notebook['cells'].map.with_index do |cell, idx|
    decorate_cell(transform_cell(cell, notebook, symbol / idx), cell, symbol / idx)
  end

  transformed_blocks.prepend((notebook)) if @include_frontmatter
  transformed_blocks.flatten
end

#transform_metadata(notebook_json) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/transformer.rb', line 88

def (notebook_json)
  as_yaml = {
    'jupyter' => {
      'kernelspec' => notebook_json['metadata']['kernelspec'],
      'language_info' => notebook_json['metadata']['language_info'],
      'nbformat' => notebook_json['nbformat'],
      'nbformat_minor' => notebook_json['nbformat_minor']
    }
  }.to_yaml

  as_yaml.split("\n").map { |l| _(nil, l) }.append(_(nil, '---'), _)
end

#transform_text_cell(cell, symbol) ⇒ Object



84
85
86
# File 'lib/transformer.rb', line 84

def transform_text_cell(cell, symbol)
  symbolize_array(symbol / 'source', cell['source'], &:rstrip)
end

#validate_notebook(notebook) ⇒ Object



26
27
28
29
30
31
32
33
34
# File 'lib/transformer.rb', line 26

def validate_notebook(notebook)
  notebook_json = JSON.parse(notebook)

  return notebook_json if notebook_json.key?('cells')

  raise InvalidNotebookError
rescue JSON::ParserError
  raise InvalidNotebookError
end