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

Prevent Environment subclass X appending to another X #341

Open
aapomalk opened this issue Nov 2, 2021 · 0 comments
Open

Prevent Environment subclass X appending to another X #341

aapomalk opened this issue Nov 2, 2021 · 0 comments

Comments

@aapomalk
Copy link

aapomalk commented Nov 2, 2021

Context

I'm using Beamer with PyLaTeX. I have created my own class Frame (from PyLaTeX Environment) and there I'm overriding append so that Frame cannot be appended to Frame (otherwise LaTeX gives an error).

    def append(self, content):
        super().append(content)
        self.check_content_type(content)
        
    def check_content_type(self, element):
        if (element is not None) and (type(element) is Frame):
            string = 'Frame cannot contain another Frame.'
            raise TypeError(string)

Problem

The problem here is that if one uses:

with doc.create(Frame()) as frame1:
    frame1.append('some text')
    with doc.create(Frame()) as frame2:
        frame2.append('some text')

Then the error comes when compiling LaTeX and it's difficult for user to see where the error has happened.

But if one uses:

with doc.create(Frame()) as frame1:
    frame1.append('some text')
    with frame1.create(Frame()) as frame2:
        frame2.append('some text')

Then the error comes when running Python and points to the user where the error has happened. But problem here is that this only comes if user doesn't know that frame cannot contain another frame.

When modifying script the indentation is easy to mess up but hard to debug without proper error messages from Python.

Correct code

The correct code would then be:

with doc.create(Frame()) as frame1:
    frame1.append('some text')
with doc.create(Frame()) as frame2:
    frame2.append('some text')

Because frames cannot be within each other.

Workaround

Currently I'm using following workaround in my document class:

    @contextmanager
    def create(self, child):

        if type(child) is Frame and self.within_frame:
            raise TypeError('Frame cannot contain another Frame.')

        if type(child) is Frame:
            self.within_frame = True
            
        # copy-paste from PyLaTeX
        prev_data = self.data
        self.data = child.data  # This way append works appends to the child
        
        yield child  # allows with ... as to be used as well
        
        self.data = prev_data
        self.append(child)
        # end of copy-paste

        self.within_frame = False

The problem is just that now I have to add the append rules to document and Frame and in long run this gets tedious as number of classes grow.

Expected behavior

I'd wish that overriding append in any class would be enough and that there would be no need to add any code for document class.

Or if I'm missing something and there would be already a solution where I only need to edit Frame without the document workaround then I'd be pleased.

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

No branches or pull requests

1 participant