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

Generates algorithmic environment #57

Closed
odashi opened this issue Oct 21, 2022 · 15 comments
Closed

Generates algorithmic environment #57

odashi opened this issue Oct 21, 2022 · 15 comments
Assignees
Labels
Milestone

Comments

@odashi
Copy link
Collaborator

odashi commented Oct 21, 2022

I have worked recently to investigate if we could generate the LaTeX algorithm environment from the function.
Actually it can work like this:

FfJj0MyVEAAe01M

I think this feature is really useful for almost arbitrary functions.

@odashi odashi added the feature label Oct 21, 2022
@odashi
Copy link
Collaborator Author

odashi commented Oct 21, 2022

There are several caveats.

Specifically, IPython supports only MathJax, meaning that it accepts only a single expression. To output more complicated LaTeX document, we need to complie the source directly, and convert the generated file to an image that IPython accepts.

In the work above, I used pdflatex and pdf2image. They requires to install external libraries, e.g., texlive with the algorithmicx package (for pdflatex) and Poppler (for pdf2image).

@odashi
Copy link
Collaborator Author

odashi commented Oct 21, 2022

An option to implement it for IPython is to use immediate newline in the single expression with appropriate manual spacing, but it requires some hacks. I think it would be better to apply external commands to generate the compiled image.

@luisarandas
Copy link

Can this, if implemented, be added to the ipynb example?

@odashi
Copy link
Collaborator Author

odashi commented Oct 27, 2022

@luisarandas Yes, the poc works on Jupyter and/or Colab and we can add examples.

@odashi odashi self-assigned this Oct 30, 2022
@odashi odashi added this to the v0.3 milestone Nov 1, 2022
@odashi
Copy link
Collaborator Author

odashi commented Nov 7, 2022

I guess composing everything into array would be another option to show the result on Jupyter. Maybe we can introduce multiple codegen (one for algorithmic, one for jupyter).

FgdCA52aMAA5ZQX

@ZibingZhang
Copy link
Contributor

ZibingZhang commented Nov 21, 2022

I'd agree with multiple code gen, targeting either Jupyter or algorithmic. I'd be interested in taking a look into algorithmic at some point.

@odashi
Copy link
Collaborator Author

odashi commented Nov 21, 2022

I have some ideas about this.

  • First, we can provide the ExpressionCodegen, which converts ast.expr to LaTeX. I think ast.expr is the minimal fragment of AST that we can share the same behavior among different output styles.
  • Then, we provide several codegens, such as FunctionCodegen, AlgorithmCodegen, IPythonAlgorithmCodegen, or something else, to process the whole syntax. They invokes ExpressionCodegen internally to obtain the underlying expressions, and organize all results along with the style that the codegen finally produces.

This design has also an advantage about programmatic use of this library. We can define a function latexify.compile_expression("...expr..."), which directly invokes ExpressionCodegen and returns the LaTeX. (also discussed in #108)

@ZibingZhang
Copy link
Contributor

ZibingZhang commented Nov 22, 2022

I would think that ExpressionCodegen(ast.NodeVisitor) would be the parent class to FunctionCodegen, AlgorithmCodegen, etc., since I think the visiting of nodes for expressions should be shared among them?

Would you happen to have the LaTeX code for the example MAX_IN_ARRAY function in the image above? Not super familiar with using Latex in this way, and it would be nice for an example to get a sense of what the end result would be here.

@odashi
Copy link
Collaborator Author

odashi commented Nov 22, 2022

ExpressionCodegen(ast.NodeVisitor) would be the parent class to FunctionCodegen, AlgorithmCodegen, etc

We don't need inheritance (and shouldn't adopt inheritance here IMO) because there's basically no advantage over composition in this case. We could define ExpressionCodegen as just a kind of function.

For the first example, I tried to synthesize the following LaTeX environment:
https://www.overleaf.com/learn/latex/Algorithms
(note that there are many options/variants of this environment)

@ZibingZhang
Copy link
Contributor

Maybe an required keyword argument to specify the argument to target?

@odashi
Copy link
Collaborator Author

odashi commented Nov 25, 2022

I guess you meant some argument to specify the output style. Yes we need to have one for it (and maybe it'd be better to integrate the current function and expression behaviors into "style")

@ZibingZhang
Copy link
Contributor

ZibingZhang commented Nov 27, 2022

Maybe adding a sytle=StyleEnum field in the config, and instead of latexify.expression being a wrapper around latexify.function with use_signature=False. Instead it would be a wrapper with config.style = Style.EXPRESSION?

That way we could have things like

@latexify.function(style=Style.EXPRESSION)
def fact(n):
    return 1 if n == 0 else n * fact(n - 1)

and we could have

Style(str, enum.Enum):
    EXPRESSION = "expression"
    FUNCTION = "function"
    ALGPSEUDOCODE = "algpseudocode"

@odashi
Copy link
Collaborator Author

odashi commented Nov 27, 2022

Yes. And we should have functions for every choice of style. As this is an essential config, users shouldn't write the style parameter every time.

@ZibingZhang
Copy link
Contributor

An option to implement it for IPython is to use immediate newline in the single expression with appropriate manual spacing, but it requires some hacks. I think it would be better to apply external commands to generate the compiled image.

I think it might be nice to try to do this using said hacks so that we don't add unnecessary dependancies.

image

I don't think it would actually be that difficult. Do you mind if I try to accomplish this, or did you prefer to go the image approach?

@odashi
Copy link
Collaborator Author

odashi commented Dec 11, 2022

I don't like the image approach actually, so going with two codegens is fine.

~~~~

Better to use \hspace{width} rather than whitespace characters, because indentation does not mean anything about the expression itself. (it also allows us to control the amount of the depth afterwards)

\mathrm{\textbf{foo}}

Better to use \mathbf{foo}.

See also my previous example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants