From 0c5f90f225f11d74a39d53cbce613d8e5cac0f8c Mon Sep 17 00:00:00 2001 From: Rebecca Phuonghanh Dang Date: Fri, 21 Jun 2024 21:00:35 -0700 Subject: [PATCH 01/11] Specify jekyll >= 4.0.0 as dependency To ensure the `link` liquid tag works --- Gemfile | 1 + Gemfile.lock | 1 + 2 files changed, 2 insertions(+) diff --git a/Gemfile b/Gemfile index 40b4f75..9734143 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,7 @@ # frozen_string_literal: true source 'https://rubygems.org' +gem 'jekyll', '>= 4.0.0' gem 'jekyll-sitemap' gem 'just-the-docs' gem 'kramdown-parser-gfm' diff --git a/Gemfile.lock b/Gemfile.lock index 861e869..f54184f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -200,6 +200,7 @@ DEPENDENCIES axe-core-capybara axe-core-rspec capybara + jekyll (>= 4.0.0) jekyll-sitemap just-the-docs kramdown-parser-gfm From 2ab282b3cc4526242a7f96d957d321034954e5c9 Mon Sep 17 00:00:00 2001 From: Rebecca Phuonghanh Dang Date: Fri, 21 Jun 2024 21:01:40 -0700 Subject: [PATCH 02/11] [WIP] Create custom python liquid tag to include python files with/without solutions --- _includes/test.py | 14 +++++++++ _plugins/python_tag.rb | 67 ++++++++++++++++++++++++++++++++++++++++++ home.md | 4 +++ 3 files changed, 85 insertions(+) create mode 100644 _includes/test.py create mode 100644 _plugins/python_tag.rb diff --git a/_includes/test.py b/_includes/test.py new file mode 100644 index 0000000..3238d19 --- /dev/null +++ b/_includes/test.py @@ -0,0 +1,14 @@ +def testing(): + """ + doctests woohoo + """ + print('this is displayed') + print('this is also displayed') + # BEGIN SOLUTION + print('solution is only displayed if enabled') + # END SOLUTION + + print('this is also displayed') + # BEGIN SOLUTION + print('solution 2 is only displayed if enabled') + # END SOLUTION diff --git a/_plugins/python_tag.rb b/_plugins/python_tag.rb new file mode 100644 index 0000000..0f4216c --- /dev/null +++ b/_plugins/python_tag.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +module Jekyll + BEGIN_SOLUTION = '# BEGIN SOLUTION' + END_SOLUTION = '# END SOLUTION' + + # Custom Liquid tag for including Python files in _includes/ + # so that the solutions appear only when specified. + # Example format of .py file: _includes/test.py + # + # Inherits from Jekyll's built-in include tag: + # https://github.com/jekyll/jekyll/blob/master/lib/jekyll/tags/include.rb + # TODO: create superclass and specify comment character(s) to generalize behavior to other languages + class PythonTag < Jekyll::Tags::IncludeTag + def initialize(tag_name, params, tokens) + parse_params(params) + super(tag_name, @file_name, tokens) + end + + def parse_params(params) + file_name, show_solution = params.strip.split + + raise ArgumentError, "File name '#{file_name}' must end in .py" if file_name[-3..] != '.py' + + unless %w[true false].include?(show_solution) + raise ArgumentError, "Second argument to python tag must be a boolean, not '#{show_solution}'" + end + + show_solution = show_solution == 'true' + + @file_name = file_name + @show_solution = show_solution + end + + def render(context) + raw_lines = super.split("\n") + saw_begin = false + saw_end = false + parsed_lines = [] + + raw_lines.each_with_index do |line, index| + if line.include?(BEGIN_SOLUTION) + raise PythonTagError, "Duplicate '#{BEGIN_SOLUTION}' at _includes/#{@file_name}:#{index + 1}" if saw_begin + + saw_begin = true + saw_end = false + elsif line.include?(END_SOLUTION) + raise PythonTagError, "'#{END_SOLUTION}' without preceding '#{BEGIN_SOLUTION}' at _includes/#{@file_name}:#{index + 1}" unless saw_begin + + saw_begin = false + saw_end = true + elsif !saw_begin || (saw_begin && @show_solution) + parsed_lines.push(line) + end + end + + raise PythonTagError, "'#{BEGIN_SOLUTION}' without matching '#{END_SOLUTION}'" if saw_begin && !saw_end + + parsed_lines.join("\n") + end + end + + class PythonTagError < StandardError + end +end + +Liquid::Template.register_tag('python', Jekyll::PythonTag) diff --git a/home.md b/home.md index b47561c..ffbfe1f 100644 --- a/home.md +++ b/home.md @@ -37,3 +37,7 @@ Just the Class has been used by instructors at Stanford University ([CS 161](htt ### Local development environment Just the Class requires no special Jekyll plugins and can run on GitHub Pages' standard Jekyll compiler. To setup a local development environment, clone your template repository and follow the GitHub Docs on [Testing your GitHub Pages site locally with Jekyll](https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/testing-your-github-pages-site-locally-with-jekyll). + +{% highlight python %} +{% python test.py true %} +{% endhighlight %} From a7ee69eea0a17a8a70e0d47455f735b0dd1659a2 Mon Sep 17 00:00:00 2001 From: Rebecca Phuonghanh Dang Date: Fri, 21 Jun 2024 21:02:06 -0700 Subject: [PATCH 03/11] Run rubocop autocorrect --- _plugins/python_tag.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/_plugins/python_tag.rb b/_plugins/python_tag.rb index 0f4216c..836c6a3 100644 --- a/_plugins/python_tag.rb +++ b/_plugins/python_tag.rb @@ -45,8 +45,11 @@ def render(context) saw_begin = true saw_end = false elsif line.include?(END_SOLUTION) - raise PythonTagError, "'#{END_SOLUTION}' without preceding '#{BEGIN_SOLUTION}' at _includes/#{@file_name}:#{index + 1}" unless saw_begin - + unless saw_begin + raise PythonTagError, + "'#{END_SOLUTION}' without preceding '#{BEGIN_SOLUTION}' at _includes/#{@file_name}:#{index + 1}" + end + saw_begin = false saw_end = true elsif !saw_begin || (saw_begin && @show_solution) From ed74525d1c0bebc741bad07518cfacf6bd4bb07a Mon Sep 17 00:00:00 2001 From: Rebecca Phuonghanh Dang Date: Fri, 21 Jun 2024 21:07:34 -0700 Subject: [PATCH 04/11] Update .rubocop.yml --- .rubocop.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 20b35af..64a3842 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,3 +3,15 @@ require: AllCops: NewCops: enable + +Metrics/AbcSize: + Enabled: false + +Metrics/CyclomaticComplexity: + Enabled: false + +Metrics/MethodLength: + Max: 100 + +Metrics/PerceivedComplexity: + Enabled: false From 49bcfeff6f235b58236e0e3aa2d21ed29db38299 Mon Sep 17 00:00:00 2001 From: Rebecca Dang <35876322+phrdang@users.noreply.github.com> Date: Fri, 21 Jun 2024 21:13:49 -0700 Subject: [PATCH 05/11] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- _includes/test.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/_includes/test.py b/_includes/test.py index 3238d19..e2a3c05 100644 --- a/_includes/test.py +++ b/_includes/test.py @@ -2,13 +2,13 @@ def testing(): """ doctests woohoo """ - print('this is displayed') - print('this is also displayed') + print("this is displayed") + print("this is also displayed") # BEGIN SOLUTION - print('solution is only displayed if enabled') + print("solution is only displayed if enabled") # END SOLUTION - - print('this is also displayed') + + print("this is also displayed") # BEGIN SOLUTION - print('solution 2 is only displayed if enabled') + print("solution 2 is only displayed if enabled") # END SOLUTION From 71e2b0cd330f4b65e1a13336763523c4a1e55f7a Mon Sep 17 00:00:00 2001 From: Rebecca Phuonghanh Dang Date: Fri, 21 Jun 2024 21:14:23 -0700 Subject: [PATCH 06/11] Remove trailing whitespace --- _includes/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/test.py b/_includes/test.py index 3238d19..1f8c19a 100644 --- a/_includes/test.py +++ b/_includes/test.py @@ -7,7 +7,7 @@ def testing(): # BEGIN SOLUTION print('solution is only displayed if enabled') # END SOLUTION - + print('this is also displayed') # BEGIN SOLUTION print('solution 2 is only displayed if enabled') From a82e52d827ba793c31ced5c467eb6bcd1c7ca19a Mon Sep 17 00:00:00 2001 From: Rebecca Phuonghanh Dang Date: Mon, 24 Jun 2024 20:34:49 -0700 Subject: [PATCH 07/11] Support passing jekyll variables into tag --- _plugins/python_tag.rb | 53 +++++++++++++++++++++++++++++++++++------- home.md | 2 +- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/_plugins/python_tag.rb b/_plugins/python_tag.rb index 836c6a3..ba4bdcf 100644 --- a/_plugins/python_tag.rb +++ b/_plugins/python_tag.rb @@ -6,12 +6,21 @@ module Jekyll # Custom Liquid tag for including Python files in _includes/ # so that the solutions appear only when specified. - # Example format of .py file: _includes/test.py # # Inherits from Jekyll's built-in include tag: # https://github.com/jekyll/jekyll/blob/master/lib/jekyll/tags/include.rb # TODO: create superclass and specify comment character(s) to generalize behavior to other languages class PythonTag < Jekyll::Tags::IncludeTag + # Expected format of this tag: + # {% python file_name.py true %} + # + # tag_name is "python" + # params is " file_name.py show_solution_boolean " + # + # Example: {% python test.py true %} + # Example: {% python test.py page.show_solutions %} + # + # NOTE: the file name is the path relative to the _includes/ directory def initialize(tag_name, params, tokens) parse_params(params) super(tag_name, @file_name, tokens) @@ -22,18 +31,27 @@ def parse_params(params) raise ArgumentError, "File name '#{file_name}' must end in .py" if file_name[-3..] != '.py' - unless %w[true false].include?(show_solution) - raise ArgumentError, "Second argument to python tag must be a boolean, not '#{show_solution}'" - end - - show_solution = show_solution == 'true' - @file_name = file_name @show_solution = show_solution end - def render(context) - raw_lines = super.split("\n") + def string_boolean?(value) + %w[true false].include?(value) + end + + def boolean?(value) + [true, false].include?(value) + end + + def to_boolean(value) + raise ArgumentError, "value must be 'true' or 'false' not '#{value}' (type #{value.class})" unless string_boolean?(value) + + value == 'true' + end + + # Parse the lines read from the .py file by IncludeTag + # to strip/keep solutions + def parse_file_lines(raw_lines) saw_begin = false saw_end = false parsed_lines = [] @@ -61,6 +79,23 @@ def render(context) parsed_lines.join("\n") end + + def render(context) + # If the 2nd argument to the tag is a jekyll variable/front matter + # (rather than boolean), attempt to retrieve it + if string_boolean?(@show_solution) + @show_solution = to_boolean(@show_solution) + else + jekyll_variable_value = context[@show_solution] + + raise ArgumentError, "Second argument to python tag must be a boolean, not '#{jekyll_variable_value}' (type #{jekyll_variable_value.class})" unless boolean?(jekyll_variable_value) + + @show_solution = jekyll_variable_value + end + + raw_lines = super.split("\n") + parse_file_lines(raw_lines) + end end class PythonTagError < StandardError diff --git a/home.md b/home.md index ffbfe1f..7294e47 100644 --- a/home.md +++ b/home.md @@ -39,5 +39,5 @@ Just the Class has been used by instructors at Stanford University ([CS 161](htt Just the Class requires no special Jekyll plugins and can run on GitHub Pages' standard Jekyll compiler. To setup a local development environment, clone your template repository and follow the GitHub Docs on [Testing your GitHub Pages site locally with Jekyll](https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/testing-your-github-pages-site-locally-with-jekyll). {% highlight python %} -{% python test.py true %} +{% python test.py page.nav_exclude %} {% endhighlight %} From e7e70c13c856ccad9949845169071f90850d7bcb Mon Sep 17 00:00:00 2001 From: Rebecca Phuonghanh Dang Date: Mon, 24 Jun 2024 21:51:08 -0700 Subject: [PATCH 08/11] Generalize PythonTag to CodeTag - Undo changes to home.md - Use code tag in sample question and another question --- _includes/questions/AnotherQuestion.java | 9 ++ _includes/questions/another_question.md | 6 +- _includes/questions/another_question.py | 12 -- _includes/questions/sample_question.md | 2 +- _includes/test.py | 14 --- _plugins/code_tag.rb | 137 +++++++++++++++++++++++ _plugins/python_tag.rb | 105 ----------------- home.md | 4 - 8 files changed, 149 insertions(+), 140 deletions(-) create mode 100644 _includes/questions/AnotherQuestion.java delete mode 100644 _includes/questions/another_question.py delete mode 100644 _includes/test.py create mode 100644 _plugins/code_tag.rb delete mode 100644 _plugins/python_tag.rb diff --git a/_includes/questions/AnotherQuestion.java b/_includes/questions/AnotherQuestion.java new file mode 100644 index 0000000..1a27b18 --- /dev/null +++ b/_includes/questions/AnotherQuestion.java @@ -0,0 +1,9 @@ +public class AnotherQuestion { + public static void main(String[] args) { + System.out.println("Hello world!"); + // BEGIN SOLUTION + System.out.println("solution here"); + // END SOLUTION + System.out.println("Outside solution"); + } +} diff --git a/_includes/questions/another_question.md b/_includes/questions/another_question.md index 58cc1a0..867aa7c 100644 --- a/_includes/questions/another_question.md +++ b/_includes/questions/another_question.md @@ -1,7 +1,5 @@ This is another sample question description. -{% highlight python %} -{% include questions/another_question.py %} +{% highlight java %} +{% code questions/AnotherQuestion.java false %} {% endhighlight %} - -{% include okpy.md question="another_question" %} diff --git a/_includes/questions/another_question.py b/_includes/questions/another_question.py deleted file mode 100644 index 10176de..0000000 --- a/_includes/questions/another_question.py +++ /dev/null @@ -1,12 +0,0 @@ -def another_question(a, b, c): - """ - >>> another_question(1, 2, 3) - 6 - >>> another_question(0, 0, 0) - 0 - >>> another_question(3, 0, 0) - 3 - """ - # BEGIN SOLUTION - return a + b + c - # END SOLUTION diff --git a/_includes/questions/sample_question.md b/_includes/questions/sample_question.md index bdfd88c..a8d402a 100644 --- a/_includes/questions/sample_question.md +++ b/_includes/questions/sample_question.md @@ -1,7 +1,7 @@ This is a sample question description. {% highlight python %} -{% include questions/sample_question.py %} +{% code questions/sample_question.py true %} {% endhighlight %} {% include okpy.md question="sample_question" %} diff --git a/_includes/test.py b/_includes/test.py deleted file mode 100644 index e2a3c05..0000000 --- a/_includes/test.py +++ /dev/null @@ -1,14 +0,0 @@ -def testing(): - """ - doctests woohoo - """ - print("this is displayed") - print("this is also displayed") - # BEGIN SOLUTION - print("solution is only displayed if enabled") - # END SOLUTION - - print("this is also displayed") - # BEGIN SOLUTION - print("solution 2 is only displayed if enabled") - # END SOLUTION diff --git a/_plugins/code_tag.rb b/_plugins/code_tag.rb new file mode 100644 index 0000000..23192f1 --- /dev/null +++ b/_plugins/code_tag.rb @@ -0,0 +1,137 @@ +# frozen_string_literal: true + +module Jekyll + # Custom Liquid tag for including code files in _includes/ + # so that the solutions appear only when specified. + # + # Inherits from Jekyll's built-in include tag which does the heavy lifting + # of reading the file: + # https://github.com/jekyll/jekyll/blob/master/lib/jekyll/tags/include.rb + # + # TODO: figure out how to write tests for this + # TODO: automatically wrap code tags inside a highlight/endhighlight block + class CodeTag < Jekyll::Tags::IncludeTag + BEGIN_SOLUTION = 'BEGIN SOLUTION' + END_SOLUTION = 'END SOLUTION' + SUPPORTED_LANGUAGES = { + '.py': '#', + '.java': '//', + '.c': '//', + '.rb': '#', + '.go': '//', + '.sql': '--' + }.freeze + + class CodeTagError < StandardError + end + + # Expected format of this tag: + # {% code file_name.ext show_solution_boolean %} + # + # tag_name is "code" + # params is " file_name.ext show_solution_boolean " + # + # Examples: + # {% code questions/sample_question.py true %} + # {% code questions/AnotherQuestion.java page.show_solution %} + # + # NOTE: the file name must be the path relative to the _includes/ directory + def initialize(tag_name, params, tokens) + parse_params(params) + super(tag_name, @file_name, tokens) + end + + def get_extension_and_comment_chars(file_name) + SUPPORTED_LANGUAGES.each do |extension, comment_chars| + if file_name.end_with?(extension.to_s) + @file_extension = extension + @comment_chars = comment_chars + return + end + end + + raise ArgumentError, "File extension not supported: #{file_name}. Supported extensions: #{SUPPORTED_LANGUAGES.join(', ')}" + end + + def parse_params(params) + file_name, show_solution = params.strip.split + + raise ArgumentError, "Missing first argument to code tag, which must be a file path relative to _includes directory" if file_name.nil? + raise ArgumentError, "Missing second argument to code tag, which must be a boolean representing whether solutions are displayed" if show_solution.nil? + + get_extension_and_comment_chars(file_name) + + @file_name = file_name + @show_solution = show_solution + end + + def string_boolean?(value) + %w[true false].include?(value) + end + + def boolean?(value) + [true, false].include?(value) + end + + def to_boolean(value) + raise ArgumentError, "value must be 'true' or 'false' not '#{value}' (type #{value.class})" unless string_boolean?(value) + + value == 'true' + end + + # Parse the lines read from the file by IncludeTag, removing or keeping solutions. + # Expect that solutions, if there are any, are within a BEGIN SOLUTION and END SOLUTION + # block. For example, if @comment_chars is '//', then the solution(s) should be placed within + # // BEGIN SOLUTION and // END SOLUTION + def parse_file_lines(raw_lines) + saw_begin = false + saw_end = false + parsed_lines = [] + full_begin_solution = "#{@comment_chars} #{BEGIN_SOLUTION}" + full_end_solution = "#{@comment_chars} #{END_SOLUTION}" + + raw_lines.each_with_index do |line, index| + if line.strip == full_begin_solution + raise CodeTagError, "Duplicate '#{full_begin_solution}' at _includes/#{@file_name}:#{index + 1}" if saw_begin + + saw_begin = true + saw_end = false + elsif line.strip == full_end_solution + unless saw_begin + raise CodeTagError, + "'#{full_end_solution}' without preceding '#{full_begin_solution}' at _includes/#{@file_name}:#{index + 1}" + end + + saw_begin = false + saw_end = true + elsif !saw_begin || (saw_begin && @show_solution) + parsed_lines.push(line) + end + end + + raise CodeTagError, "'#{full_begin_solution}' without matching '#{full_end_solution}'" if saw_begin && !saw_end + + parsed_lines.join("\n") + end + + # TODO: render placeholder code like "*** YOUR CODE HERE ***" if @show_solution is false? + def render(context) + # If the 2nd argument to the tag is a jekyll variable/front matter + # (rather than boolean), attempt to retrieve it + if string_boolean?(@show_solution) + @show_solution = to_boolean(@show_solution) + elsif !boolean?(@show_solution) + jekyll_variable_value = context[@show_solution] + + raise ArgumentError, "Second argument to code tag must be a boolean, not '#{jekyll_variable_value}' (type #{jekyll_variable_value.class})" unless boolean?(jekyll_variable_value) + + @show_solution = jekyll_variable_value + end + + raw_lines = super.split("\n") + parse_file_lines(raw_lines) + end + end +end + +Liquid::Template.register_tag('code', Jekyll::CodeTag) diff --git a/_plugins/python_tag.rb b/_plugins/python_tag.rb deleted file mode 100644 index ba4bdcf..0000000 --- a/_plugins/python_tag.rb +++ /dev/null @@ -1,105 +0,0 @@ -# frozen_string_literal: true - -module Jekyll - BEGIN_SOLUTION = '# BEGIN SOLUTION' - END_SOLUTION = '# END SOLUTION' - - # Custom Liquid tag for including Python files in _includes/ - # so that the solutions appear only when specified. - # - # Inherits from Jekyll's built-in include tag: - # https://github.com/jekyll/jekyll/blob/master/lib/jekyll/tags/include.rb - # TODO: create superclass and specify comment character(s) to generalize behavior to other languages - class PythonTag < Jekyll::Tags::IncludeTag - # Expected format of this tag: - # {% python file_name.py true %} - # - # tag_name is "python" - # params is " file_name.py show_solution_boolean " - # - # Example: {% python test.py true %} - # Example: {% python test.py page.show_solutions %} - # - # NOTE: the file name is the path relative to the _includes/ directory - def initialize(tag_name, params, tokens) - parse_params(params) - super(tag_name, @file_name, tokens) - end - - def parse_params(params) - file_name, show_solution = params.strip.split - - raise ArgumentError, "File name '#{file_name}' must end in .py" if file_name[-3..] != '.py' - - @file_name = file_name - @show_solution = show_solution - end - - def string_boolean?(value) - %w[true false].include?(value) - end - - def boolean?(value) - [true, false].include?(value) - end - - def to_boolean(value) - raise ArgumentError, "value must be 'true' or 'false' not '#{value}' (type #{value.class})" unless string_boolean?(value) - - value == 'true' - end - - # Parse the lines read from the .py file by IncludeTag - # to strip/keep solutions - def parse_file_lines(raw_lines) - saw_begin = false - saw_end = false - parsed_lines = [] - - raw_lines.each_with_index do |line, index| - if line.include?(BEGIN_SOLUTION) - raise PythonTagError, "Duplicate '#{BEGIN_SOLUTION}' at _includes/#{@file_name}:#{index + 1}" if saw_begin - - saw_begin = true - saw_end = false - elsif line.include?(END_SOLUTION) - unless saw_begin - raise PythonTagError, - "'#{END_SOLUTION}' without preceding '#{BEGIN_SOLUTION}' at _includes/#{@file_name}:#{index + 1}" - end - - saw_begin = false - saw_end = true - elsif !saw_begin || (saw_begin && @show_solution) - parsed_lines.push(line) - end - end - - raise PythonTagError, "'#{BEGIN_SOLUTION}' without matching '#{END_SOLUTION}'" if saw_begin && !saw_end - - parsed_lines.join("\n") - end - - def render(context) - # If the 2nd argument to the tag is a jekyll variable/front matter - # (rather than boolean), attempt to retrieve it - if string_boolean?(@show_solution) - @show_solution = to_boolean(@show_solution) - else - jekyll_variable_value = context[@show_solution] - - raise ArgumentError, "Second argument to python tag must be a boolean, not '#{jekyll_variable_value}' (type #{jekyll_variable_value.class})" unless boolean?(jekyll_variable_value) - - @show_solution = jekyll_variable_value - end - - raw_lines = super.split("\n") - parse_file_lines(raw_lines) - end - end - - class PythonTagError < StandardError - end -end - -Liquid::Template.register_tag('python', Jekyll::PythonTag) diff --git a/home.md b/home.md index 7294e47..b47561c 100644 --- a/home.md +++ b/home.md @@ -37,7 +37,3 @@ Just the Class has been used by instructors at Stanford University ([CS 161](htt ### Local development environment Just the Class requires no special Jekyll plugins and can run on GitHub Pages' standard Jekyll compiler. To setup a local development environment, clone your template repository and follow the GitHub Docs on [Testing your GitHub Pages site locally with Jekyll](https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/testing-your-github-pages-site-locally-with-jekyll). - -{% highlight python %} -{% python test.py page.nav_exclude %} -{% endhighlight %} From 6db5707432b38eb11e1d7414d9e501fb6c86434f Mon Sep 17 00:00:00 2001 From: Rebecca Phuonghanh Dang Date: Mon, 24 Jun 2024 21:52:14 -0700 Subject: [PATCH 09/11] Run rubocop autocorrect --- _plugins/code_tag.rb | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/_plugins/code_tag.rb b/_plugins/code_tag.rb index 23192f1..b60887b 100644 --- a/_plugins/code_tag.rb +++ b/_plugins/code_tag.rb @@ -43,21 +43,28 @@ def initialize(tag_name, params, tokens) def get_extension_and_comment_chars(file_name) SUPPORTED_LANGUAGES.each do |extension, comment_chars| - if file_name.end_with?(extension.to_s) - @file_extension = extension - @comment_chars = comment_chars - return - end + next unless file_name.end_with?(extension.to_s) + + @file_extension = extension + @comment_chars = comment_chars + return end - raise ArgumentError, "File extension not supported: #{file_name}. Supported extensions: #{SUPPORTED_LANGUAGES.join(', ')}" + raise ArgumentError, + "File extension not supported: #{file_name}. Supported extensions: #{SUPPORTED_LANGUAGES.join(', ')}" end def parse_params(params) file_name, show_solution = params.strip.split - raise ArgumentError, "Missing first argument to code tag, which must be a file path relative to _includes directory" if file_name.nil? - raise ArgumentError, "Missing second argument to code tag, which must be a boolean representing whether solutions are displayed" if show_solution.nil? + if file_name.nil? + raise ArgumentError, + 'Missing first argument to code tag, which must be a file path relative to _includes directory' + end + if show_solution.nil? + raise ArgumentError, + 'Missing second argument to code tag, which must be a boolean representing whether solutions are displayed' + end get_extension_and_comment_chars(file_name) @@ -74,7 +81,10 @@ def boolean?(value) end def to_boolean(value) - raise ArgumentError, "value must be 'true' or 'false' not '#{value}' (type #{value.class})" unless string_boolean?(value) + unless string_boolean?(value) + raise ArgumentError, + "value must be 'true' or 'false' not '#{value}' (type #{value.class})" + end value == 'true' end @@ -123,7 +133,10 @@ def render(context) elsif !boolean?(@show_solution) jekyll_variable_value = context[@show_solution] - raise ArgumentError, "Second argument to code tag must be a boolean, not '#{jekyll_variable_value}' (type #{jekyll_variable_value.class})" unless boolean?(jekyll_variable_value) + unless boolean?(jekyll_variable_value) + raise ArgumentError, + "Second argument to code tag must be a boolean, not '#{jekyll_variable_value}' (type #{jekyll_variable_value.class})" + end @show_solution = jekyll_variable_value end From b9a62a1d7f8a35095a9662fab86bc8ae253c2a3b Mon Sep 17 00:00:00 2001 From: Rebecca Phuonghanh Dang Date: Mon, 24 Jun 2024 21:54:56 -0700 Subject: [PATCH 10/11] Fix rubocop offenses --- _plugins/code_tag.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/_plugins/code_tag.rb b/_plugins/code_tag.rb index b60887b..6f303b3 100644 --- a/_plugins/code_tag.rb +++ b/_plugins/code_tag.rb @@ -47,7 +47,9 @@ def get_extension_and_comment_chars(file_name) @file_extension = extension @comment_chars = comment_chars + # rubocop:disable Lint/NonLocalExitFromIterator return + # rubocop:enable Lint/NonLocalExitFromIterator end raise ArgumentError, @@ -61,9 +63,11 @@ def parse_params(params) raise ArgumentError, 'Missing first argument to code tag, which must be a file path relative to _includes directory' end + if show_solution.nil? raise ArgumentError, - 'Missing second argument to code tag, which must be a boolean representing whether solutions are displayed' + 'Missing second argument to code tag, which must be a boolean \ + representing whether solutions are displayed' end get_extension_and_comment_chars(file_name) @@ -109,7 +113,8 @@ def parse_file_lines(raw_lines) elsif line.strip == full_end_solution unless saw_begin raise CodeTagError, - "'#{full_end_solution}' without preceding '#{full_begin_solution}' at _includes/#{@file_name}:#{index + 1}" + "'#{full_end_solution}' without preceding '#{full_begin_solution}' at \ + _includes/#{@file_name}:#{index + 1}" end saw_begin = false @@ -135,7 +140,8 @@ def render(context) unless boolean?(jekyll_variable_value) raise ArgumentError, - "Second argument to code tag must be a boolean, not '#{jekyll_variable_value}' (type #{jekyll_variable_value.class})" + "Second argument to code tag must be a boolean, not \ + '#{jekyll_variable_value}' (type #{jekyll_variable_value.class})" end @show_solution = jekyll_variable_value From aad21087577402a1969e3cd95d32a539ecc5dfcd Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Fri, 16 Aug 2024 15:36:21 -0700 Subject: [PATCH 11/11] Delint --- spec/support/spec_summary.rb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/spec/support/spec_summary.rb b/spec/support/spec_summary.rb index 0db4413..4afb42f 100644 --- a/spec/support/spec_summary.rb +++ b/spec/support/spec_summary.rb @@ -20,8 +20,6 @@ def summarize_results(results) end.flatten.tally end -# rubocop:disable Metrics/AbcSize -# rubocop:disable Metrics/MethodLength def group_results(results) all_cases_list = failing_specs(results).map do |ex| msg = ex['exception']['message'] @@ -43,9 +41,8 @@ def group_results(results) end results end -# rubocop:enable Metrics/AbcSize -# rubocop:enable Metrics/MethodLength +# rubocop:enable Metrics/AbcSize def test_failures_with_pages(summary_group) summary_group.transform_values { |list| list.map { |h| h[:page] } } end