ipynbdiff-0.3.8/ 0000755 0001751 0001751 00000000000 14153336547 012535 5 ustar pravi pravi ipynbdiff-0.3.8/.gitignore 0000644 0001751 0001751 00000000040 14153336547 014517 0 ustar pravi pravi .tool-versions .bundle *.gem ipynbdiff-0.3.8/Gemfile.lock 0000644 0001751 0001751 00000001140 14153336547 014753 0 ustar pravi pravi GEM remote: https://rubygems.org/ specs: diff-lcs (1.4.4) diffy (3.3.0) json (2.5.1) rspec (3.10.0) rspec-core (~> 3.10.0) rspec-expectations (~> 3.10.0) rspec-mocks (~> 3.10.0) rspec-core (3.10.1) rspec-support (~> 3.10.0) rspec-expectations (3.10.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.10.0) rspec-mocks (3.10.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.10.0) rspec-support (3.10.2) PLATFORMS x86_64-darwin-20 DEPENDENCIES diffy (= 3.3.0) json (= 2.5.1) rspec (= 3.10.0) BUNDLED WITH 2.2.29 ipynbdiff-0.3.8/lib/ 0000755 0001751 0001751 00000000000 14153336547 013303 5 ustar pravi pravi ipynbdiff-0.3.8/lib/output_transformer.rb 0000644 0001751 0001751 00000003643 14153336547 017620 0 ustar pravi pravi # frozen_string_literal: true module IpynbDiff # Transforms Jupyter output data into markdown class OutputTransformer ORDERED_KEYS = { 'execute_result' => %w[image/png image/svg+xml image/jpeg text/markdown text/latex text/plain], 'display_data' => %w[image/png image/svg+xml image/jpeg text/markdown text/latex] }.freeze def transform(output) case (output_type = output['output_type']) when 'error' transform_error(output['traceback']) when 'execute_result', 'display_data' transform_non_error(ORDERED_KEYS[output_type], output['data']) end end def transform_error(traceback) traceback.map do |t| t.split("\n").map do |line| line.gsub(/\[[0-9][0-9;]*m/, '').sub("\u001B", ' ').gsub(/\u001B/, '').rstrip << "\n" end end end def transform_non_error(accepted_keys, elements) accepted_keys.map do |key| transform_element(key, elements[key]) if elements.key?(key) end.flatten end def transform_element(output_type, output_element) case output_type when 'image/png', 'image/jpeg' transform_image(output_type, output_element) when 'image/svg+xml' transform_svg(output_element) when 'text/markdown', 'text/latex', 'text/plain' transform_text(output_element) end end def transform_image(image_type, image_content) [" })", "\n"] end def transform_svg(image_content) lines = image_content.is_a?(Array) ? image_content : [image_content] single_line = lines.map(&:strip).join('').gsub(/\s+/, ' ') [" ", "\n"] end def transform_text(text_content) lines = text_content.is_a?(Array) ? text_content : [text_content] lines.map { |line| " #{line}" }.append("\n") end end end ipynbdiff-0.3.8/lib/ipynbdiff.rb 0000644 0001751 0001751 00000003004 14153336547 015577 0 ustar pravi pravi # frozen_string_literal: true # Human Readable Jupyter Diffs module IpynbDiff require 'transformer' require 'diffy' @default_transform_options = { include_metadata: false, cell_decorator: :html } @default_diff_options = { preprocess_input: true, write_output_to: nil, format: :text, sources_are_files: false, raise_if_invalid_notebook: false, transform_options: @default_transform_options, diff_opts: { include_diff_info: false } }.freeze def self.prepare_input(to_prepare, options) return '' unless to_prepare prep = to_prepare prep = File.read(prep) if options[:sources_are_files] prep = transform(prep, raise_errors: true, options: options[:transform_options]) if options[:preprocess_input] prep end def self.diff( from_notebook, to_notebook, options = @default_diff_options ) options = @default_diff_options.merge(options) from = prepare_input(from_notebook, options) to = prepare_input(to_notebook, options) d = Diffy::Diff.new(from, to, **options[:diff_opts]).to_s(options[:format]) File.write(options[:write_output_to], d) if options[:write_output_to] d rescue InvalidNotebookError raise if options[:raise_if_invalid_notebook] end def self.transform(notebook, raise_errors: false, options: @default_transform_options) options = @default_transform_options.merge(options) Transformer.new(**options).transform(notebook) rescue InvalidNotebookError raise if raise_errors end end ipynbdiff-0.3.8/lib/transformer.rb 0000644 0001751 0001751 00000005622 14153336547 016177 0 ustar pravi pravi # frozen_string_literal: true module IpynbDiff class InvalidNotebookError < StandardError end # Returns a markdown version of the Jupyter Notebook class Transformer require 'json' require 'yaml' require 'output_transformer' @cell_decorator = :html @include_metadata = true def initialize(include_metadata: true, cell_decorator: :html) @include_metadata = include_metadata @cell_decorator = cell_decorator @output_transformer = OutputTransformer.new end 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 def transform(notebook) notebook_json = validate_notebook(notebook) transformed_blocks = notebook_json['cells'].map do |cell| decorate_cell(transform_cell(cell, notebook_json), cell) end transformed_blocks.prepend(transform_metadata(notebook_json)) if @include_metadata transformed_blocks.join("\n") end def decorate_cell(rows, cell) tags = cell['metadata']&.fetch('tags', []) type = cell['cell_type'] || 'raw' case @cell_decorator when :html rows.prepend(%(