Michael-F-Bryan / latex-rs

An ergonomic library for programatically generating LaTeX documents and reports.
MIT License
54 stars 16 forks source link

Provide an escape function and probably escape stuff by default #13

Open JelteF opened 6 years ago

JelteF commented 6 years ago

Not sure if this is still somewhat actively developed. But I wanted to give some advise, because I created the Python equivalent of this: https://github.com/JelteF/PyLaTeX. Something really important when generating latex from user input is to escape the user input. Otherwise the user can possibly execute arbitrary shell commands. This is the character replace list I use in my library: https://github.com/JelteF/PyLaTeX/blob/master/pylatex/utils.py#L14-L31

I decided in my library that because of the risks escaping should be done by default. I recommend you do the same in some future version of this library. But at least provide a way of escaping user input.

Michael-F-Bryan commented 6 years ago

This sounds like a really good idea. Is it essentially just a string.replace(), or did you need a more sophisticated escaping algorithm (e.g. to prevent this bug)?

Unfortunately I've been working on other projects recently, but I'm working on alternate backends for mdbook at the moment and this crate will play a big part in the PDF backend.

How did you structure PyLaTeX? I've been using enums to represent each type of element you can add to a document, but I'm questioning whether that's the best way to do things.

JelteF commented 6 years ago

Yeah it's just a string replace for characters that have special meaning in LaTeX (in some contexts).

I've made my fair share of bad design decisions in PyLaTeX, especially some insane inheritance stuff.

But what I would say turned out great is the extensibility of the library. There's so many latex features that it's impossible to include all of them in the library. What I would probably would do in Rust (not sure what you already have):

If you need any inspiration check my base_classes.py, containers.py and commands.py

BTW, this crate already implements some latex escaping: https://github.com/lise-henry/crowbook-text-processing/ I did make an issue there as well, because it missed some of the characters that were in my escape function.

On Mon, Dec 25, 2017, 02:55 Michael Bryan notifications@github.com wrote:

This sounds like a really good idea. Is it essentially just a string.replace(), or did you need a more sophisticated escaping algorithm (e.g. to prevent this https://what.thedailywtf.com/topic/17354/http-a-30-30-crashes-chrome bug)?

Unfortunately I've been working on other projects recently, but I'm working on alternate backends for mdbook at the moment and this crate will play a big part in the PDF backend.

How did you structure PyLaTeX? I've been using enums https://docs.rs/latex/0.2.0/latex/enum.Element.html to represent each type of element you can add to a document, but I'm questioning whether that's the best way to do things.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Michael-F-Bryan/latex-rs/issues/13#issuecomment-353814417, or mute the thread https://github.com/notifications/unsubscribe-auth/ABG8JrgiV4XfTXLEZhoU45hbtWZelYpgks5tDwB5gaJpZM4RLx5T .

Michael-F-Bryan commented 6 years ago

I was thinking about using a trait where each item has a render method, but adding in a dependency information method is pretty smart.

Using traits also gives you a chance to do some pretty cool things with generics. For example, having generic a NoEscape<T> struct or being able to wrap any arbitrary element in an environment or whatever.

Michael-F-Bryan commented 6 years ago

Another thing I was wondering about is compiling the documents. Originally I was planning on shelling out to whatever is installed on the system, but that's not overly portable (not guaranteed to be using the same latex distribution) or cross platform (I'd hate to tell windows users to install latex)... How did you approach that with PyLaTeX?

JelteF commented 6 years ago

Regarding dependency information, I used a sorted set to deduplicate packages while keeping order. That had worked quite well, but I'm not sure if such a container already exists in Rust.

In pylatex I shell out to latexmk if available and otherwise pdflatex as fallback. Latexmk handles multiple latex compilations correctly for stuff as bibtex and cross references. So every time someone asks about problems because of that I also just tell them to install latexmk and then it always just works.

I also support passing in your own compiler strings or args, because some people want to use luatex or xetex.

I haven't had problems from people on Windows because of this, but I have had other windows bug reports so Windows people are using it. It seems like pdflatex gets installed on Windows when installing the miktex distribution. So this approach has worked fine for me.

I also don't know of any other solution that would work other than reimplementing latex. But that was clearly out of scope of my project.

Regarding the traits, I think you can do some cool stuff indeed with some of Rusts features. So some design decisions I made in pylatex might have better alternatives here.

On Mon, Dec 25, 2017, 13:34 Michael Bryan notifications@github.com wrote:

Another thing I was wondering about is compiling the documents. Originally I was planning on shelling out to whatever is installed on the system, but that's not overly portable (not guaranteed to be using the same latex distribution) or cross platform (I'd hate to tell windows users to install latex)... How did you approach that with PyLaTeX?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Michael-F-Bryan/latex-rs/issues/13#issuecomment-353866573, or mute the thread https://github.com/notifications/unsubscribe-auth/ABG8Jq4CDfJN_3NuSSLmq3D8S2aXfqOoks5tD5ZDgaJpZM4RLx5T .