Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: truncate long lines in PDF conversion #439

Merged
merged 21 commits into from
May 25, 2024

Conversation

ublefo
Copy link
Contributor

@ublefo ublefo commented Apr 27, 2024

This fixes the PDF processing issue when there are super long lines in the submitted code files by using cut and fold from coreutils to wrap lines. Additionally, introduce https://github.com/ruby/shellwords for proper shell escape.

There are two limits configured, the hard limit is 1000 characters, and the soft limit is 160 characters. Any lines over 1000 characters will be truncated, and then line breaks will be applied for any lines over 160 characters long. If the rendered file has been modified, a warning will be added into the PDF document to indicate the rendered file differs from the original submission. Unit tests and test files have been added for these changes.

Inkscape has been replaced with librsvg for SVG to PDF conversion in jupynotex. Inkscape pulls in a lot of unnecessary dependencies (dbus, gtk, etc.), and it emits annoying irrelevant errors that has to be redirected to /dev/null. rsvg-convert is much more lightweight in comparison, performs equally well and has none of the downsides of Inkscape: https://gitlab.gnome.org/GNOME/librsvg

Generated result (excluding Jupyter Notebook):
image

Jupyter Notebook:
image

PDF processing will fail with "! Dimension too large." if a line of text
is way too long. Implement a simple processing helper method to call
fold (from coreutils) to fold long lines for all code files.
We shouldn't modify student submissions, instead we use the
temp file when rendering them to PDF. Cleanup will be performed
after rendering is complete.
Run fold on provided files and compare the output with diff. If the file
doesn't contain any lines that are over the configured threshold, it
will be identical to the original. In this case we replace the temp file
with a symlink for easy identification in the template.
Redirect stdout to /dev/null since we don't need the diff output
Set a hard limit of 1000 characters, and truncate everything in the same
line after the limit is reached. Otherwise we could get PDF files with
hundreds of pages which is completely unreadable.
Copy link
Member

@macite macite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you see if we can do this with re-writing the original rather than creating the tempfile?

app/models/task.rb Outdated Show resolved Hide resolved
app/helpers/file_helper.rb Show resolved Hide resolved
app/models/task.rb Outdated Show resolved Hide resolved
app/views/task/task_pdf.pdf.erb Outdated Show resolved Hide resolved
@ublefo ublefo requested a review from macite May 2, 2024 21:42
@macite macite merged commit 2425997 into doubtfire-lms:development May 25, 2024
2 of 3 checks passed
@ublefo ublefo deleted the pdf-long-lines branch June 2, 2024 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants