Skip to content

Conversation

@Alex-Jordan
Copy link
Contributor

This pairs with openwebwork/pg#870.

This refactors how hardcopy themes work. Things to note:

  • This separates what tex packages and macros are to support PG, to support WeBWorK2 hardcopy production, and are to support a given theme.
  • The hardcopy production is now abstracted away from the exam class.
  • A hardcopy theme is now a single XML file. See examples in assets/hardcopyThemes.
  • It should be easy now to make a hardcopy theme. Follow the README in assets/hardcopyThemes, or just copy one of the existing theme files.
  • In light of this, IMHO it is not worth keeping the ability to granularly override parts of a theme that could previously be done with files in snippets. Those are gone. All of snippets is gone. The pg files that were there are now in assets/pg.
  • This uses XML::LibXML. I had trouble installing it with cpanm, but no trouble using yum (sudo yum install perl-XML-LibXML).
  • Several things in localOverrides.conf need updating with this PR.

I expect there will be things to tweak about the themes. But I left the \vfill in place. I think th issue I am seeing there with bad page breaks on long problems is not new to 2.18. But this PR will make it easy to adjust an existing theme or add a new one.

@Alex-Jordan
Copy link
Contributor Author

Here are three themes based on the tclorbox package. None of them are universally good for all hardcopy sets with long problems. But these are good for testing what can be done with themes. To try these, put them in /assets/hardcopyThemes/. And add the following to localOverrides.conf. Then they will be available for hardcopy production.

$hardcopyThemes = [
        {file => 'empty.xml',                     pretty => 'Empty'},
        {file => 'basic.xml',                     pretty => 'Basic'},
        {file => 'oneColumn.xml',                 pretty => 'One Column'},
        {file => 'twoColumn.xml',                 pretty => 'Two Columns'},
        {file => 'tcbraster.xml',                 pretty => 'TCBRaster'},
        {file => 'tcolorbox.xml',                 pretty => 'TColorBox'},
        {file => 'tcolorboxmulticol.xml',         pretty => 'TColorBoxMulticol'},
        #{file => 'XeLaTeX-oneColumn.xml',         pretty => "English\x{2014}one Column"},
        #{file => 'XeLaTeX-twoColumn.xml',         pretty => "English\x{2014}two Columns"},
        #{file => 'XeLaTeX-Hebrew-oneColumn.xml',  pretty => "Hebrew/English\x{2014}one Column"},
        #{file => 'XeLaTeX-Hebrew-twoColumn.xml',  pretty => "Hebrew/English\x{2014}two Columns"},
];

You will need to change the extension of these files to xml.

tcbraster.txt
tcolorbox.txt
tcolorboxmulticol.txt

@pstaabp
Copy link
Member

pstaabp commented Jul 6, 2023

Overall this looks great. However, if I add your custom files above, they are tracked. How about a custom directory inside assets/hardcopyThemes that is in .gitignore.

Also, is there a mechanism for instructors to do this for a particular course. If we update $hardcopyThemes in course.conf, then that generates the menu of options, but how about searching for the theme files inside the templates directory of a course?

@Alex-Jordan
Copy link
Contributor Author

I'm making some enhancements following today's meeting. So it may be best not to review this quite yet.

@Alex-Jordan
Copy link
Contributor Author

OK, I made some changes that do some of what @pstaabp suggested. Now you can get on this branch (and the corresponding pg branch) and in a course:

  • create a hardcopyThemes/ folder inside templates/ (this will be created as an empty folder in new courses).
  • put in the theme files I posted earlier. Change the extensions to .xml.
  • extend the list of available themes in course.conf with something like:
push (@{$hardcopyThemes}, 
   { id => 'myTheme1', file => "$courseDirs{hardcopyThemes}/tcolorbox.xml", pretty => "My Theme 1" },
   { id => 'myTheme2', file => "$courseDirs{hardcopyThemes}/tcolorboxmulticol.xml", pretty => "My Theme 2" },
   { id => 'myTheme3', file => "$courseDirs{hardcopyThemes}/tcbraster.xml", pretty => "My Theme 3" },
);

Copy link
Member

@drgrice1 drgrice1 left a comment

Choose a reason for hiding this comment

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

I haven't delved too deeply into this yet, but here are some things that I see already.

I don't like that when a hardcopy is generated in the PG problem editor via HardcopyRenderedProblem.pm, there is now a horizontal rule at the top of the page.

The \firstpageheader from the theme is now written after the set header. This means that it is impossible for the set header to override that. This is a show stopper for me. I don't want the default headers.

I am not entirely fond of having TeX in XML, but I can get over that I suppose.

@Alex-Jordan Alex-Jordan force-pushed the hardcopy-themes branch 2 times, most recently from 9269ed0 to 5aedc26 Compare July 7, 2023 06:51
@Alex-Jordan
Copy link
Contributor Author

I changed the minor things.

I don't like that when a hardcopy is generated in the PG problem editor via HardcopyRenderedProblem.pm, there is now a horizontal rule at the top of the page.

That rule is part of the theme. It seems wrong to let certain things appear from the theme (like let the twoColumn theme use two columns and have a vertical line between them) but not let other things from the theme appear.

Could you render using the Basic theme or the Empty theme instead? Would it help to have a "Basic Two Columns" theme? Or a new theme that has the things you currently use, including a lack of a vertical rule? Would it help to allow for a different default theme for the PGEditor (eg Basic) than the default for full hardcopy production (eg oneColumn)?

The \firstpageheader from the theme is now written after the set header. This means that it is impossible for the set header to override that. This is a show stopper for me. I don't want the default headers.

So, the point of much of this is that you could easily have your own hardcopy theme that does not have a \firstpageheader, or has different content in the \firstpageheader. You are saying that you want to be able to use the PG header to manage alterations to the the theme's header. But you don't have to do that anymore. Your PG headers can now be purely about contextual, pedagogical, instructional information for the students, divorced from the styling of the PDF.

If you can send me a sample tex bundle for a homework set that is in a style you like, I could add that as a hardcopy theme that comes with the distribution. I don't even care to keep the current oneColumn and twoColumn exactly as they are. if yours is better, I'd change those to what you are using in production. Already this evening I realized that I need to change something about the \firstpageheader anyway, since I saw that is easier than I expected to have a long set name and a long user name and they butt into each other.

@drgrice1
Copy link
Member

drgrice1 commented Jul 7, 2023

I changed the minor things.

Thanks.

So, the point of much of this is that you could easily have your own hardcopy theme that does not have a \firstpageheader, or has different content in the \firstpageheader. You are saying that you want to be able to use the PG header to manage alterations to the the theme's header. But you don't have to do that anymore. Your PG headers can now be purely about contextual, pedagogical, instructional information for the students, divorced from the styling of the PDF.

This must not insist on an instructor writing a new theme to obtain this. I can not approve this pull request in this way. As I said, this is a show stopper.

Copy link
Member

@drgrice1 drgrice1 left a comment

Choose a reason for hiding this comment

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

There are some more issues that I see.

@drgrice1
Copy link
Member

drgrice1 commented Jul 7, 2023

On the issue of the \firstpageheader, the deal is that I see no reason that what could easily be obtained before with only the hardcopy set header should now require writing an entire custom theme.

@drgrice1
Copy link
Member

drgrice1 commented Jul 7, 2023

There is another issue that I just noticed. The problem number is now being displayed as "Problem1", "Problem2", ..., instead of "Problem 1", "Problem 2", ...

@Alex-Jordan
Copy link
Contributor Author

The problem number is now being displayed as "Problem1",

Which theme did you see this with? These should all be written with \webworkPageNumber which is defined in webwork2.sty using a ~ for the space. I looked through the themes except Hebrew and I only see it like Problem 1.

@drgrice1
Copy link
Member

drgrice1 commented Jul 7, 2023

I see it with both the one and two column theme.

@drgrice1
Copy link
Member

drgrice1 commented Jul 7, 2023

In both themes this is added as \webworkLocalizeProblem \thequestiontitle. I don't see a tilde between the word 'Problem' that comes from \webworkLocalizeProblem and the problem number that comes from \thequestiontitle.

@Alex-Jordan
Copy link
Contributor Author

Got it. My eyes/brain turned the "Problem 1" you wrote into "Page 1" and that is what I was looking at. Sorry!

@drgrice1
Copy link
Member

drgrice1 commented Jul 7, 2023

You also need to update the check_latex script for the changes in this pull request.

@Alex-Jordan
Copy link
Contributor Author

On the issue of the \firstpageheader, the deal is that I see no reason that what could easily be obtained before with only the hardcopy set header should now require writing an entire custom theme.

I accept that I haven't persuaded you yet on this principle, but the PG set header file can now be divorced from styling the PDF. And I feel that it should be divorced, and that will make some things better in the long run. But your method to override things in the theme using the PG header runs contrary to that principle. What happens when you override \firstpageheader in a PG header file, but then you (or someone downstream using your problem set) wants to switch to a different theme that is not based on the exam class? They probably can't, because your overrides will cause LaTeX errors with \firstpageheader not being defined.

Up to now it has been more work to make a new theme than to make a new PG header file. With this PR, they are a lot closer. Something I can still improve on is to make the Editor capable of editing a theme file like how it can edit a few other non-PG files. I'll give that a go. And then writing/editing a theme really would be an equivalent amount of work to writing/editing a PG header file.

A thought: consider a new WW-using instructor with little to no prior PG experience. And this person wants to customize the hardcopy headers/footers. Which will be a steeper obstacle for them?

  1. Learning about MODES to edit a PG header file appropriately. You don't even get the luxury of disregarding the theme file(s), because you have to be familiar with what exactly you will override (\firstpageheader in this discussion).
  2. Editing some tex snippets in a theme xml file, where you can see the impact of the exam class (or whatever else is in use) all in one place.

I feel that option 2 is easier for people unfamiliar with PG.

Also as I wrote before, I'm more than happy to change the default headers and footers to a format you are already using. I don't have the impression anyone is tied to what is there now. But I don't know what your format is yet.

@drgrice1
Copy link
Member

drgrice1 commented Jul 7, 2023

Prior to all of your recent hardcopy changes all an instructor needed to do was edit the default set header file and change a few lines. That was even easier than any of the options you list. They don't need to learn about MODES and such. It was actually quite straightforward. There was no need to override headers set in the themes. The themes provided what was needed -- just layout, and there was no need to mess with themes at all unless you needed translations. Prior to the exam class change even that was rarely needed.

@drgrice1
Copy link
Member

drgrice1 commented Jul 8, 2023

In addition, to create a theme you need to know LaTeX. Most instructors know nothing about LaTeX. This makes it vastly more difficult than before to do what you are saying.

@Alex-Jordan
Copy link
Contributor Author

Alex-Jordan commented Jul 8, 2023 via email

@drgrice1
Copy link
Member

drgrice1 commented Jul 8, 2023

I am sorry. I don't mean to press you on this, and I don't mean to sound so harsh. I have not focused on the positive aspects of this pull requests. You have set up a versatile hardcopy theming system that looks very nice. For my purposes, I can set up my own themes that do what I want.

I just think that there are many instructors that will feel the same way about the default page headers as I do. Generally, I don't want much information in those headers, and use a more condensed format. Also, since I don't use sections and recitations the default header becomes rather unbalanced. There are three lines on the left, and only one ("student name (login id)") on the right.

I also don't like the links so much. For this it might help if hypersetup were used to override the default hyperref settings that I think are rather ugly. I always change those to make links look more like they do in the browser when I use the hyperref package.

In any case, an instructor that wants a simple way to change the header information with this system will find it much more challenging than before. Intuitively speaking the set header pg file is where one would expect to set the header for the set in the pdf. Until the recent changes was where that was done. You mention divorcing the PG set header file from PDF styling, but the header in the PDF result is more than just a style and is really a set header (it is shown for each set and user). It is part of the content.

@Alex-Jordan
Copy link
Contributor Author

Alex-Jordan commented Jul 8, 2023 via email

@Alex-Jordan
Copy link
Contributor Author

I have this close to ready to push and ask for more review, but there's something I want to check in about. (I'll be doing day job stuff through tomorrow and I can't make progress, but I hope to have it pushed by the end of tomorrow.)

There are now two snippets for set header, one before the PG header and one after, which will make it possible to still override things using the PG header. I've simplified things so that hardcopy them files can only be at webwork2/assets/hardcopyThemes or templates/hardcopyThemes. You can have theme files in both places and config will see them all, but you choose which ones are enabled. If two share a filename, the one from your course will be used (imagine making a slightly altered copy of twoColumn, for instance). You choose which one is the default for hardcopy production, and separately which one is the default for PGEditor hardcopy production.

You can edit an existing theme file with the editor, and it saves to templates/hardcopyThemes. Either directly editing what was already there or making a copy of one from webwork2/assets/hardcopyThemes. But now i get to my question. I was looking for the simplest mechanism to trigger editing an existing theme. What I came up with was, in the PG editor, go to the hardcopy tab. The button there triggers some javascript call for building the PDF instead of the usual form submit. So i thought to add a button that would do the regular form submit. It submits the chosen hardcopy theme and has text like "Edit selected theme". It directs back to the editor, but with a new hardcopy_theme file mode (and the selected theme via the form submission). The theme file is opened from whichever of the two source folders it lives in, and a target file in templates/hardcopyThemes (possibly the same as the source file) is what it writes to. The last thing I haven't completed is displaying the XML niceely in the right panel which I think uses instructor_rpc but I just haven't looked at that yet.

My question now is if I've overlooked something and made a mistake by adding this form submission button to that form. Maybe it's hard to say without looking at the code in the updated PR. But does anything occur to you as making this a bad idea?

@drgrice1
Copy link
Member

Something sounds a bit off with that structure. I can't say for certain though without seeing exactly what you have.

I was thinking about the issue with overriding the pdf page headers from the pg set header. It seems that if there were TeX commands that were defined that provide the headers, say \firstPageHeaderLeft, \firstPageHeaderCenter, and \firstPageHeaderRight, and the hardcopy generation code would then define those to be the default headers that you are currently using, then the pg file could override those commands and thus change the headers. Then any theme would just set the headers to the value of those commands. Then it wouldn't matter if the them is using the exam class and its header mechanism, or using the fancyhdr package, and the pg set header could reliably override the default values. I haven't done any real testing as to the feasibility of this idea, but it seems like it should work.

@Alex-Jordan
Copy link
Contributor Author

Yeah, I'm not sure about it either. The thing is, if you are going to edit a theme, you need to be at a place where you can select the theme you are about to edit. There are three existing places where that happens: (a) course config page (b) regular hardcopy production page (c) PG Editor hardcopy tab. Or else create something new.

Option (c) is nice in that you are already in the editor with a form that is not already using its submit button for something else.

Comment on lines 22 to 23
\ifthenelse{\equal{\webworkPrettySetId}{}}{}{\fancyhead[L]{\ifthenelse{\thepage=1}{\large\scshape\webworkLocalizeSet: \webworkPrettySetId}{}}}
\ifthenelse{\equal{\webworkUserId}{}}{}{\fancyhead[R]{\ifthenelse{\thepage=1}{\bfseries\webworkLocalizeUsername: \webworkUserId}{}}}
Copy link
Member

@drgrice1 drgrice1 Jul 14, 2023

Choose a reason for hiding this comment

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

To follow up on #2099 (comment), if this were

Suggested change
\ifthenelse{\equal{\webworkPrettySetId}{}}{}{\fancyhead[L]{\ifthenelse{\thepage=1}{\large\scshape\webworkLocalizeSet: \webworkPrettySetId}{}}}
\ifthenelse{\equal{\webworkUserId}{}}{}{\fancyhead[R]{\ifthenelse{\thepage=1}{\bfseries\webworkLocalizeUsername: \webworkUserId}{}}}
\fancyhead[L]{\webworkAssignmentCourseInfo}
\fancyhead[R]{\webworkUserInfo}

and all of the themes consistently used \webworkAssignmentCourseInfo and webworkUserInfo like this, then in the hardcopy set header file one could do

\renewcommand{\webworkAssignmentCourseInfo}{My custom left header content}
\renewcommand{\webworkUserInfo}{My custom right header content}

and reliably modify the headers for all themes without concern of if the exam class or fancyhdr package were used by the theme.

Copy link
Member

Choose a reason for hiding this comment

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

Note the theme itself could also use \renewcommand to change the default headers for the theme. The basic.xml theme could do this to get the different headers you currently have set for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll do something like this and update the branch. The purpose of the \ifthenelse is, in part, so that if you use the theme from the Editor (where there is no set ID or user ID), it gives no header content at all. But maybe it would be better to still show whatever the skeleton of the header would be. It's also messier with the ones relying on fanccyhdr where I don't think there is anything special to single out doing the first page headers differently than running headers.

Copy link
Member

Choose a reason for hiding this comment

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

So the theme could do

\renewcommand{\webworkAssignmentCourseInfo}{%
	\ifthenelse{\equal{\webworkPrettySetId}{}}{}%
	{\ifthenelse{\thepage=1}{\large\scshape\webworkLocalizeSet: \webworkPrettySetId}{}}%
}
\renewcommand{\webworkUserInfo}{%
	\ifthenelse{\equal{\webworkUserId}{}}{}%
	{\ifthenelse{\thepage=1}{\bfseries\webworkLocalizeUsername: \webworkUserId}{}}%
}
\fancyhead[L]{\webworkAssignmentCourseInfo}
\fancyhead[R]{\webworkUserInfo}

That should do the same thing in any case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I will change \webworkAssignmentCourseInfo and \webworkAssignmentCourseInfo to have generic names like \webworkLeftHeader and \webworkRightHeader and add commentary in the right places about customizing them. Probably add \webworkCenterHeader too. And as I've noted, I'll change the default content of these to make it less possible for a left and right header overstrike.

Fix some issues that have cropped up if a user attempts to access the editor without sufficient permissions.
my $setID = $c->stash('setID');
my $problemID = $c->stash('problemID');

return 'Editor' unless $c->{file_type};
Copy link
Member

Choose a reason for hiding this comment

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

I just realized this should be return $c->maketext('Editor') unless $c->{file_type};. My bad. Can you make that change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I'll update it.

@Alex-Jordan
Copy link
Contributor Author

I changed the default webwork2.sty headers and footers that apply to several of the themes. See what you think?

There's an issue with using the footer to insert a copyright claim. It can happen that the footer is redefined to be a copyright claim, but then the set extends to one more page because of some unresolved content at that point in the processing. I tried many things to delay the resetting of the footer content, but it was always either not enough of a delay, or delayed it so much that the last page ended up without the copyright claim. So as things stand, occasionally the last two pages get a copyright claim. I can live with this (after wasting too much time battling it). But if anyone would like to try some other approach, you might have more success than I did.

Aside from a footer, there are other ways to claim copyright. It could just be written as the last piece of content like it was before. Or it could be done with some kind of watermark or with thee eso-pic package (although these may have the same issues that I've had with footers.)

@Alex-Jordan
Copy link
Contributor Author

It could just be written as the last piece of content

This comes with the risk of the copyright claim moving to a new page though.

@drgrice1
Copy link
Member

I think the new LaTeX commands for the headers and footers make this quite versatile. Thanks for making that change.

I was unable to reproduce the footer issue, but that probably takes just the right (or rather wrong) problem lengths.

@Alex-Jordan
Copy link
Contributor Author

Thanks for the suggestions. The sty and theme files looks a lot cleaner now.

Yeah, I happen to be testing with a set where the last problem is just a bit too long and gets pushed to a new page with all of the two-column themes.

@drgrice1
Copy link
Member

Oh wait. I found a set that gave the issue with the copyright. That is not to serious.

@Alex-Jordan
Copy link
Contributor Author

I can think of one way to handle the copyright issue (that is too much work that I do not plan to do). That would be to change how hardcopies are made, so that each set is its own PDF. Then merge the PDFs at the end. There are several problems with this though, given how we do things now. But it would help address this issue because there are several tools for dealing the actual last page of a PDF, and those tools could make sure it only lands on the last page of each set.

@drgrice1
Copy link
Member

For now, this should work. I think that trying to rework hardcopy generation to generate separate PDF's and merge them is a bit ambitious at this point. I plan to release 2.18 next Thursday.

@Alex-Jordan
Copy link
Contributor Author

It's not only ambitious, I think I would not want the side effect of effectively forcing a newpage between sets.

@Alex-Jordan
Copy link
Contributor Author

I plan to release 2.18 next Thursday.

OK, I'll clean up my hardcopy-themes-editor branch and open a PR then to hurry that up. I still haven't figured out why I can't get the save handler to work the way it should, but more eyes on it will probably see what I haven't been able to.

@pstaabp
Copy link
Member

pstaabp commented Jul 20, 2023

Looking at this with fresh eyes.

Noticed that if I have a long problem (extends the the length of the page), the boxed-rows themes, cuts off the end of the problem. I tried to add 'breakable' to the tcolorbox, but broke the two columns. I don't think this is a deal breaker--hopefully if someone selects this theme, they check.

@drgrice1
Copy link
Member

There is something that I just noticed that needs to be changed. Previously the multicol LaTeX package was always available even when the two column theme was not used. That still needs to be the case. The pg DragNDrop.pm package (used by the draggableProof.pl and draggableSubsets.pl macros) uses this in hardcopy. So that package will need to be added to webwork2.sty (or pg.sty if that is more appropriate).

@Alex-Jordan
Copy link
Contributor Author

Yeah, boxedRows.xml uses a tcbraster. Inside a tcbraster, the tcolorbox blocks are not breakable and there is a note about this in the description element in the theme. Currently nothing is done with the descriptions, but maybe in the future they can be exposed to some sort of help tool.

@Alex-Jordan
Copy link
Contributor Author

I'll add multicol to pg.sty, since it supports a PG thing. But then also need to update some comments here on the webwork2 side.

Copy link
Member

@pstaabp pstaabp left a comment

Choose a reason for hiding this comment

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

I think this is ready to go after multicols is added in.

@Alex-Jordan
Copy link
Contributor Author

I made the multicol move both here and the pg side. Btw I'm suree the meeting is underway, but I will be late/absent. Have a student meeting.

@drgrice1 drgrice1 merged commit a35be80 into openwebwork:WeBWorK-2.18 Jul 20, 2023
@Alex-Jordan Alex-Jordan deleted the hardcopy-themes branch August 18, 2024 20:38
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.

3 participants