-
Notifications
You must be signed in to change notification settings - Fork 259
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
Increase flexibility of TableBordersLayout #1005
base: master
Are you sure you want to change the base?
Conversation
* Change TableBordersLayout from an enum to a class with specifiable map from table location to cell border style * Retain old enum names as static class members to retain old functionality * Add control over color, thickness, and dash parameters * Add unit test covering new capabilities
@Lucas-C @gmischler I've created a draft pull request in response to Issue #957. If you agree with the direction I've gone, it should be fairly quick to fix up remaining issues. Obviously I'm open to different direction if you see things you don't like. |
An interesting concept! And a heads-up: I'm currently working on turning the table cells into text regions (see #339). To do that I'll have to rearrange quite a few parts of the table code, delegating tasks away from tha main |
I understand the desire for simplicity. To be fair, you only supply one lambda, and generally it would be quite simple (e.g. see the re-implementation of the existing styles). The demo was complicated to show all the things that could be done, but that could obviously be scaled back to provide a simple introduction, e.g. similar to MINIMAL but the line under headings is thick). The test needs to have every possible combination just in case a corner case breaks one of them. |
The specific number of lambdas is not the point. Using query functions that the table elements can use to learn about their formatting is a useful concept. But that is an internal implementation detail, and not necessarily a good aproach for a public API. Rather than in 5 abstract lambda arguments, users may rather think in terms like "outer left border", "border below last heading", "bottom row of cells" etc. If you allow them to define rules in those terms and build your lambda out of them internally, then that would be a lot more helpful in terms of useability. Forcing users to think in terms of internal implemention details is an issue I see with a lot of software on a daily basis. I really hope we can avoid falling into the same trap here. |
@gmischler weighing in here as I opened the original issue. I wanted to share an example of a table style I'm trying to replicate. It's toy data to illustrate, but hopefully it gets the point across: Because (as I currently understand it) there's no way to embed tables in tables, I'm constructing this as a single table even though there are three sub-tables. In this example I have:
This is very similar to a style of table that is very frequently used in academic publications (at least in biology and I believe other sciences too) where people are used to seeing tables generated by latex. I don't know the internals of the library nearly as well as you, but me sense is that if we only went with your suggestion (border styles settable for a specific categories of borders) I think either I wouldn't be able to do this or there would be a be-wildering array of categories. How would you feel if this was the underlying mechanism and the public API supported?:
|
Thanks for your input, @tfenne, that is a wonderful example to discuss the topic. layout = TableLayout()
layout.bottom_border(rows=[0], start=0, end=-1)
layout.bottom_border(rows=[1], start=0, end=-1, width=2)
layout.top_border(rows=[-1], start=0, end=-1, width=2, color=DeviceGray(0.5))
layout.right_border(columns=[2, 4], start=1, end=-1)
layout.row_format(rows=[0], style=bold_blue_font_face, align="CENTER")
layout.row_format(rows=[1], style=bold_font_face, align="CENTER") This is a rough idea very much off the cuff, so there are probably more refined ways to go about it. But I think you'd need an extemely weird table format to make the lambda solution easier to understand and handle than something along those lines. How to translate this kind of input into a request reply for each individual cell is left as an excercise for the reader... 😉 |
@gmischler I have been thinking about the best way to implement something along the lines of your suggestion. There are two issues that I see, and I see an easy work-around the first one, but I encountered some difficulties doing the second with a pure implementation.
The best way forward that I can see to provide the API you like and reimplement the old styles is a hybrid approach. I could write a
I think either approach would involve enough work that I'd like to get your thoughts before plowing ahead and coding. |
I'm sorry that your last, detailed comment was left unanswered for almost a year 😢 Thank you very much for the effort you put in this PR 👍 I volunteer to take over @gmischler in assisting you on this PR 🙂 But first, are you still willing to continue this work, almost a year later? I agree with the points you made in your last comment, about potential conflicting selectors, and the issue with reproducing the In release 2.7.9 of Another |
Hi @Lucas-C I think we are interested in seeing this to completion one way or another. I just got back from international travel, but I should have time today to review my old work, |
Hi @TedBrookings! 🙂 What are is the status on your side regarding this PR? Wish you a happy holiday season 🎄☃️ 𐂂 |
Hi, I'm sorry for dropping out for a bit, things got very hectic with urgent client commitments. I did look over the other work, and I think that unfortunately it's unlikely that we are going to agree on a path forward for this PR (and obviously this is your repo, so we respect your need to maintain your own coding standards!). The other PR added control over per-cell formatting, which my PR also did. So I would have to rebase my work to get back to the same place and use the new system. But that would still leave us at an impasse for how to define per-cell format. If your objection is really just to lambdas, and you would be fine if the lambdas were replaced with ordinary functions in The other suggestion involved explicitly passing lists of rows or columns for specific format effects, but in addition to being quite verbose, it then results in something that isn't a style, but a set of drawing instructions for each table (you have to know table dimensions exactly in advance). I also made a brief attempt at implementing them, but quickly found that coordinating between the different proposed format operations became much more complicated than simply specifying a per-cell format function. By contrast, e.g. TableCellFillMode uses very simple functions to determine if a cell should be filled. Our original issue suggested allowing the definition of a new style that could be consistently applied to a different tables, and would hopefully be very succinct. |
Actually I think methods are fine, as we already used this approach for I'm sorry for the inconsistent feedbacks we are giving you regarding this PR.
So if you are still willing to finish the work started in this PR, I would be happy to merge a new version of this PR based on Maybe something akin to this: class TableBordersLayout:
...
def border_style_for_cell(self, i, j, table):
... Does it make sense / seem practical to you? 🙂 |
I think that seems practical. Just to be sure we're on the same page, you're thinking an abstract base class / protocol, or something similar, and then the user defines a new class with an actual implementation of In that case, I think the bulk of the actual work would just be rebasing to use the already merged support for defining Cell styles. I am pretty slammed for the rest of December, but if you're willing to wait until January, I think I could finish it off then. |
A base class yes, not necesserily an abstract one 🙂
That's perfectly fine, take your time 👍 |
Add capability to precisely control thickness, color, and dash of table cell borders.
TableBordersLayout
is changed from an enum to a more complex class with helper style classes that allow more complex custom style setting. The old enum is maintained as static members of the new class, so the previous invocation style works the same, with the added option to specify cell border styles by passing a custom function.Fixes #957
Checklist:
The GitHub pipeline is OK (green),
meaning that both
pylint
(static code analyzer) andblack
(code formatter) are happy with the changes of this PR.A unit test is covering the code added / modified by this PR
This PR is ready to be merged
In case of a new feature, docstrings have been added, with also some documentation in the
docs/
folderA mention of the change is present in
CHANGELOG.md
I'm making a draft PR. There are many unit tests that fail. The reason is partly down to strategy, and rather than plowing ahead and changing all the reference PDFs for the tests, I wanted to first get agreement that the overall approach I've used is good.
The tests fail for one of two reasons
q [set thickness/color/dash] [draw element] Q
). The result is visually identical and generally more concise, but it (correctly) failsassert_pdf_equal
. My preferred solution would be to just update the test PDFs, but if this is not desired, it would be possible (if tedious) to adopt a set and reset approach that should yield identical outputs.It also occurred to me that you might not like the class structure I created, so again I'd rather fix that and deal with the implications now, rather than plow ahead.
By submitting this pull request, I confirm that my contribution is made under the terms of the GNU LGPL 3.0 license.