Git Product home page Git Product logo

jupyterlab-latex's Introduction

JupyterLab LaTeX

build stable latest
ci-badge binder-badge binder-badge

An extension for JupyterLab which allows for live-editing of LaTeX documents.

Usage

To use, right-click on an open .tex document within JupyterLab, and select Show LaTeX Preview: preview This will compile the .tex file and open the rendered PDF document. Subsequent saves of the file will automatically update the PDF. If the PDF fails to compile (possibly due to a syntax error), an error panel will open detailing the LaTeX error.

For more advanced usage documentation, see here.

Requirements

  • JupyterLab >= 4.0
    • older versions are supported in previous releases available on PyPI and npm, check releases
  • Python >= 3.8
  • An application that can compile .tex files to PDF (e.g., pdflatex, xelatex; use pdflatex.exe on Windows with MiKTeX). This application must be available as a command in the same environment as the notebook server.
  • An application that can process .bib files for producing bibliographies. As with the LaTeX command, this must be available in the same environment as the notebook server.

Installation

This extension includes both a notebook server extension (which interfaces with the LaTeX compiler) and a lab extension (which provides the UI for the LaTeX preview). The Python package named jupyterlab_latex provides both of them as a prebuilt extension.

To install the extension, run the following in your terminal:

pip install jupyterlab_latex

Check installation

To ensure that extension is properly installed, you could check server and lab extensions:

jupyter server extension list

and see the block like this in the output

jupyterlab_latex enabled
    - Validating jupyterlab_latex...
Package jupyterlab_latex took 0.0010s to import
      jupyterlab_latex 4.0.0 OK

then

jupyter labextension list

and see the block like this in the output

@jupyterlab/latex v3.1.0 enabled OK (python, jupyterlab-latex)

Customization

The extension defaults to running xelatex on the server. This command may be customized (e.g., to use pdflatex instead) by customizing your jupyter_notebook_config.py file:

c.LatexConfig.latex_command = 'pdflatex'

The extension defaults to running bibtex for generating a bibliography if a .bib file is found. You can also configure the bibliography command by setting

c.LatexConfig.bib_command = '<custom_bib_command>'

To render references (\ref{...}), such as equation or chapter numbers, you would need to compile in multiple passes by setting

c.LatexConfig.run_times = 2

Security and customizing shell escapes

LaTeX files have the ability to run arbitrary code by triggering external shell commands. This is a security risk, and so most LaTeX distributions restrict the commands that you can run in the shell.

You can customize the behavior by setting the LatexConfig.shell_escape value. It can take three values: "restricted" (default) to allow only commands considered safe to be executed, "allow" to allow all commands, and "disallow" to disallow all commands. For example, to force your LaTeX distribution to run any command, use:

c.LatexConfig.shell_escape = "allow"

Contributing

If you would like to contribute to the project, please read our contributor documentation.

JupyterLab follows the official Jupyter Code of Conduct.

Development install

Note: You will need NodeJS to build the extension package.

The jlpm command is JupyterLab's pinned version of yarn that is installed with JupyterLab. You may use yarn or npm in lieu of jlpm below.

To simplify the development setup, you can use the following Conda environment:

conda create -n jupyterlab-latex-env -c conda-forge python=3.10 jupyterlab=4.0.0 jupyter_packaging=0.12.3 nodejs=18
conda activate jupyterlab-latex-env
# Clone the repo to your local environment
git clone https://github.com/jupyterlab/jupyterlab-latex.git
# Change directory to the jupyterlab-latex directory
cd jupyterlab-latex
# Install package in development mode
pip install -e .

# Link your development version of the extension with JupyterLab
jupyter labextension develop . --overwrite
# Server extension must be manually installed in develop mode
jupyter server extension enable jupyterlab_latex
# Rebuild extension Typescript source after making changes
jlpm run build

You can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the extension.

# Watch the source directory in one terminal, automatically rebuilding when needed
jlpm run watch
# Run JupyterLab in another terminal
jupyter lab

With the watch command running, every saved change will immediately be built locally and available in your running JupyterLab. Refresh JupyterLab to load the change in your browser (you may need to wait several seconds for the extension to be rebuilt).

Changes

For information on the changes with different versions of the jupyterlab-latex library, see our changelog

jupyterlab-latex's People

Contributors

agoose77 avatar alberthilb avatar b-trav avatar blink1073 avatar bollwyvl avatar daniel-mietchen avatar dependabot[bot] avatar fcollonval avatar horstle avatar ian-r-rose avatar jan-janssen avatar joequant avatar jzf2101 avatar ktaletsk avatar mpacer avatar rrosio avatar ryanlovett avatar scottweitzner avatar syyee avatar toddrme2178 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jupyterlab-latex's Issues

Handle directories

The file path logic is broken for LaTeX projects in subdirectories. This is fixed client-side by #3, but it also needs to be fixed server side. We need to cd into the appropriate directory and make sure the paths for the .pdf, .tex, and .log files are all correct.

@mpacer , can you fix this?

Not found `.tex` file on jupyterhub+jupyterlab

Running jupyterlab from a jupyterhub multiuser server , I got the following log trying to build a latex file:

Request cannot be completed; no file at `/home/epinux/Work/Geoscience_250279/test.tex`.

the real path to the file is:

/home/epinux/notebooks/Work/Geoscience_250279/test.tex

Where:

/home/$USER/notebooks/

Is the /root/ Directory for each unix $USER on the server.

Use PDF.js

I have a somewhat clunky PDF renderer that uses PDF.js, which allows for us to programatically do things in with the rendered PDF (such as set the scroll position).

We should clean this up and include it.

pip install fails

I tried to install this package using the command

pip install jupyterlab_latex

but I get the following message

Could not find a version that satisfies the requirement jupyterlab_latex (from versions: )
No matching distribution found for jupyterlab_latex

How to add Latex to luncher

Hello,
I've installed the extension and it works perfectly (Thanks for your beautiful work).
My question is How can I add Latex to the launcher in jupyterLab?
So that jupyterlab users inform that there is such an option available to use?

jupyter-config/jupyter_notebook_config.d is not included in editable installs

If you run pip install -e . it will not place jupyter-config/jupyter_notebook_config.d in any directory… furthermore it will overwrite any config that has been placed there.

For now, if you want to work on an editable install you still need to run

jupyter serverextension enable --sys-prefix jupyterlab_latex

Make LaTeX call configurable

We should allow the *latex called to be configurable, so that at the very least the user can call both pdflatex and xelatex

issue with document path

This issue seems similar to #59, but is happening on a fresh pip install.

This error is thrown such that no document is compiled:

Request cannot be completed; no file at `/Users/Laurentia/build/0000_Github/Laurentia_Paleogeography/manuscript.tex`.

The correct path is:
/Users/Laurentia/0000_Github/Laurentia_Paleogeography/manuscript.tex.
so it seems to be looking for a build folder that doesn't exist.

Error Panel only flashs across when the PDF fails to compile in the first time

Environment:

(jupyter_py3.6) ➜  jupyter jupyter --version          
4.4.0
(jupyter_py3.6) ➜  jupyter jupyter lab --version      
0.32.1
(jupyter_py3.6) ➜  jupyter jupyter labextension list  
JupyterLab v0.32.1
Known labextensions:
   app dir: /home/honhe/.pyenv/versions/3.6.5/envs/jupyter_py3.6/share/jupyter/lab
@jupyterlab/latex
        @jupyterlab/latex v0.3.1  enabled  OK

Tex files compiled independently in multi-file LaTeX project

Hello,
I just installed this extension so perhaps I'm missing something. I am trying to write a scientific paper involving multiple tex files. The main tex file is in the root folder of my project, and the other ones in a tex/ subfolder.
Now, every time I edit one of those other tex files and save, I get an error of the form:

This is pdfTeX, Version [...] (TeX Live 2018) (preloaded format=pdflatex) restricted \write18 enabled.
entering extended mode
(./intro.tex
LaTeX2e <2018-04-01> patch level 2
Babel <3.18> and hyphenation patterns for 84 language(s) loaded.
./intro.tex:3: Undefined control sequence.
l.3 \section
{Introduction}
./intro.tex:3: ==> Fatal error occurred, no output PDF file produced!
Transcript written on intro.log.

The extension apparently tries to compile every saved file independently, so in order to compile my whole document I have to go back to the main tex file and save it as well, which does generate the correct pdf file with no error.

(Note that all of the tex files in the tex\ subfolder start with
%!TEX root = ../my_main_file.tex

Am I missing something?
Thanks a lot.

Synctex behaves inconsistently

With jupyter lab on ChromeBook/Ubuntu Xenial via crouton/crouton extension.

https://github.com/dnschneid/crouton/wiki/crouton-in-a-Chromium-OS-window-(xiwi)

Details of full config below.

-----------------Behavior--------------------

.tex compiles correctly and is displayed in preview

synctex fails (see trace below) when jupyter lab
is executed in a different directory from the .tex
source file.

synctex works correctly when jupyter lab
is executed in the same directory as the .tex.

-----------------Config ---------------------

python 3.6.6

Jupyter Lab Version 0.34.7 installed via pip install jupyterlab-latex

Ubuntu Xenial 16.04.5
Linux localhost 3.18.0-18121-g8c0cb17dd7e0 #1
SMP PREEMPT Wed Aug 29 14:14:24 PDT 2018 x86_64 x86_64 x86_64 GNU/Linux

installed via crouton on
Chrome OS Version 69.0.3497.73 (Official Build) beta (64-bit)

-----------------Trace of error --------------------

[E 14:24:14.578 LabApp] SyncTex command synctex edit -o 1:0:0:axes_mondal.pdf errored with code: 255
[E 14:24:14.582 LabApp] Uncaught exception GET /latex/synctex/AXES_FINAL/axes_mondal.pdf?page=1&x=0&y=0&1536755054548 (::1)
HTTPServerRequest(protocol='http', host='localhost:8888', method='GET', uri='/latex/synctex/AXES_FINAL/axes_mondal.pdf?page=1&x=0&y=0&1536755054548', version='HTTP/1.1', remote_ip='::1')
Traceback (most recent call last):
File "/usr/local/conda3/lib/python3.6/site-packages/tornado/web.py", line 1592, in _execute
result = yield result
File "/usr/local/conda3/lib/python3.6/site-packages/tornado/gen.py", line 1133, in run
value = future.result()
File "/usr/local/conda3/lib/python3.6/site-packages/tornado/gen.py", line 1147, in run
yielded = self.gen.send(value)
File "/usr/local/conda3/lib/python3.6/site-packages/jupyterlab_latex/synctex.py", line 191, in get
out = json.dumps(parse_synctex_response(out, pos))
File "/usr/local/conda3/lib/python3.6/site-packages/jupyterlab_latex/synctex.py", line 215, in parse_synctex_response
raise Exception(f'Unable to parse SyncTeX response: {response}')
Exception: Unable to parse SyncTeX response: This is SyncTeX command line utility, version 1.2

[W 14:24:14.591 LabApp] Unhandled error
[E 14:24:14.593 LabApp] {
"Host": "localhost:8888",
"Connection": "keep-alive",
"User-Agent": "Mozilla/5.0 (X11; CrOS x86_64 10895.40.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.73 Safari/537.36",
"Dnt": "1",
"Authorization": "token c7f3e4eb4b7d0773bf45f5504d2df3bbcdd9a35f5d6c40fe",
"Content-Type": "application/json",
"Accept": "/",
"Referer": "http://localhost:8888/lab",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-IE,en;q=0.9,fr-FR;q=0.8,fr;q=0.7,zh-CN;q=0.6,zh;q=0.5,en-US;q=0.4",
"Cookie": "_xsrf=2|3e27440f|156278aef6ff8417cdadfb97e6f88b1d|1536255268; username-localhost-8889="2|1:0|10:1536503672|23:username-localhost-8889|44:ZjNlMzJmMjFjMTI5NDNkMWEyNTg5ZDMyNzUxNzdjZjk=|694d1e500a20d151d7d9296d4b0a7087c8df17a09ef4c6f04e3d5a33a8669aa2"; username-localhost-8888="2|1:0|10:1536755051|23:username-localhost-8888|44:NzA1MjYzOWFmYWYxNGMzMDkzZmRjODllMDNlN2JiYTk=|5114e5f9e2fe8a4f31ff8e586bab9ef1cdbd5823bb80e43699a160dcf4614883""
}
[E 14:24:14.594 LabApp] 500 GET /latex/synctex/AXES_FINAL/axes_mondal.pdf?page=1&x=0&y=0&1536755054548 (::1) 39.96ms referer=http://localhost:8888/lab

Setting tectonic (LaTeX compiler) doesn't work

Setting tectonic to the LaTeX build compiler doesn't work. The extension automatically adds flags to the command it does not recognize and fails.

I also can't find the part of the extension responsible for setting these flags. Any ideas?

Enable resize/zoom on the PDF

In the standard PDF viewer in JupyterLab (at least in Chrome, my only available browser) one can easily zoom in and out on the PDF. This is helpful on smaller screens such as ultrabooks since one can zoom in enough to get rid of the margins and just be looking at the text area. Right now, this extension does not support the same, so one always sees the entire page of the PDF.

It would be tremendously useful if one could still zoom in and out of the PDF, either by using the standard PDF viewer (perhaps with modifications) or adding the feature directly into this packages existing PDF viewer.

No preview after fresh install

When i click latex preview i get an error
this one is in the console:

{"message": "Unhandled error", "reason": null, "traceback": "Traceback (most recent call last):\n  File \"/home/brett/anaconda3/lib/python3.7/site-packages/tornado/web.py\", line 1699, in _execute\n    result = await result\n  File \"/home/brett/anaconda3/lib/python3.7/site-packages/tornado/gen.py\", line 736, in run\n    yielded = self.gen.throw(*exc_info)  # type: ignore\n  File \"/home/brett/anaconda3/lib/python3.7/site-packages/jupyterlab_latex/build.py\", line 194, in get\n    out = yield self.run_latex(cmd_sequence)\n  File \"/home/brett/anaconda3/lib/python3.7/site-packages/tornado/gen.py\", line 729, in run\n    value = future.result()\n  File \"/home/brett/anaconda3/lib/python3.7/site-packages/tornado/gen.py\", line 736, in run\n    yielded = self.gen.throw(*exc_info)  # type: ignore\n  File \"/home/brett/anaconda3/lib/python3.7/site-packages/jupyterlab_latex/build.py\", line 158, in run_latex\n    code, output = yield run_command(cmd)\n  File \"/home/brett/anaconda3/lib/python3.7/site-packages/tornado/gen.py\", line 729, in run\n    value = future.result()\n  File \"/home/brett/anaconda3/lib/python3.7/site-packages/tornado/gen.py\", line 209, in wrapper\n    yielded = next(result)\n  File \"/home/brett/anaconda3/lib/python3.7/site-packages/jupyterlab_latex/util.py\", line 48, in run_command_async\n    stderr=Subprocess.STREAM)\n  File \"/home/brett/anaconda3/lib/python3.7/site-packages/tornado/process.py\", line 248, in __init__\n    self.proc = subprocess.Popen(*args, **kwargs)\n  File \"/home/brett/anaconda3/lib/python3.7/subprocess.py\", line 775, in __init__\n    restore_signals, start_new_session)\n  File \"/home/brett/anaconda3/lib/python3.7/subprocess.py\", line 1522, in _execute_child\n    raise child_exception_type(errno_num, err_msg, err_filename)\nFileNotFoundError: [Errno 2] No such file or directory: 'xelatex': 'xelatex'\n"}

this one is in terminal

{
      "Host": "localhost:8888",
      "Connection": "keep-alive",
      "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/73.0.3683.86 Chrome/73.0.3683.86 Safari/537.36",
      "Authorization": "token ac94a47fe54c37a002e45a585d9fd6805d12a9dbac24b305",
      "Content-Type": "application/json",
      "Accept": "*/*",
      "Referer": "http://localhost:8888/lab",
      "Accept-Encoding": "gzip, deflate, br",
      "Accept-Language": "en-US,en;q=0.9",
      "Cookie": "_xsrf=2|8d87f430|6916c753a69b835ef917aa860a353bbc|1553539238; username-localhost-8888=\"2|1:0|10:1555597900|23:username-localhost-8888|44:MTdhNDFhNWFhY2YzNGZhZTk1Mzc4NzE2M2QyZDY2NzQ=|e3b512f35f78761d688662e19d36d37d1a4cd420236254023186db7dc90c9ee7\""
    }
[E 09:31:40.580 LabApp] 500 GET /latex/build/Documents/Programming%20Classes/Modern%20Python%203%20BootCamp/sample.tex?synctex=1&1555597900571 (127.0.0.1) 4.87ms referer=http://localhost:8888/lab

I just installed and loaded it into jupyter with the commands in the readme. Not sure what I am missing

installing the extension in a default jupyter/scipy-notebook container does not work

I was trying to install this extension in a docker container created from the official jupyter/scipy-notebook image that is hosted on docker hub.
Apparently this image has jupyterlab version 0.30.6 installed.
I followed the install descriptions as a local user by doing
pip install . --user
and
jupyter labextension install .
which ends with the following warnings

warning " > [email protected]" has unmet peer dependency "webpack@^2.0.0 || ^3.0.0".
warning "pdfjs-dist > [email protected]" has unmet peer dependency "webpack@^2.0.0 || ^3.0.0".
[4/4] Building fresh packages...
success Saved lockfile.
Done in 11.66s.
> /opt/conda/bin/npm pack /home/jovyan/jupyterlab-latex
jupyterlab-latex-0.1.1.tgz
"/home/jovyan/jupyterlab-latex" is not a valid extension:
Missing extension module "lib/latex.js"
Missing mimeExtension module "lib/pdf.js"

after this doing
jupyter serverextension enable jupyterlab_latex
runs without warnings and produces the following normal looking output:

Enabling: jupyterlab_latex
- Writing config: /home/jovyan/.jupyter
    - Validating...
      jupyterlab_latex  OK

launching jupyterlab and right clicking on a .tex file the menu does not have the expected Show LaTeX Preview option.

are there some unmentioned dependencies that I am missing ?

Question: shell escape is disabled, so I can only detect \ifwindows.

Hi!

Pretty new new to the jupyterlab scene, but love the idea and this latex extension!

But I have run in to a problem where it wont build the pdf because:

"Package ifplatform Warning:
shell escape is disabled, so I can only detect \ifwindows."

"./main.tex:12: Package minted Error: You must invoke LaTeX with the -shell-esca
pe flag."

Is there a way to pass this command or change it in a config somewhere?

If its of importance I'm am running this jupyterlab with jupyterhub on Ubuntu 18.04

best regards

Synctex fails on windows

Jupyterlab 0.32.1
jupyterlab_latex 0.3.0
MikTex 2.9.6500

It appears that it is searching for files in the wrong location. (note the 'uri' in the traceback)

From the server console after clicking "scroll pdf to cursor" on the .tex fail:

Uncaught exception GET /latex/synctex/gryoscope.pdf?page=1&#35;x=0&y=0&1525389931568 (127.0.0.1)
    HTTPServerRequest(protocol='http', host='localhost:8888', method='GET', uri='/latex/synctex/gryoscope.pdf?page=1&x=0&y=0&1525389931568', version='HTTP/1.1', remote_ip='127.0.0.1')
    Traceback (most recent call last):
      File "E:\ProgramData\Anaconda3\lib\site-packages\tornado\web.py", line 1543, in _execute
        result = yield result
      File "E:\ProgramData\Anaconda3\lib\site-packages\tornado\gen.py", line 1099, in run
        value = future.result()
      File "E:\ProgramData\Anaconda3\lib\site-packages\tornado\gen.py", line 1107, in run
        yielded = self.gen.throw(*exc_info)
      File "E:\ProgramData\Anaconda3\lib\site-packages\jupyterlab_latex\synctex.py", line 189, in get
        out = yield self.run_synctex(cmd)
      File "E:\ProgramData\Anaconda3\lib\site-packages\tornado\gen.py", line 1099, in run
        value = future.result()
      File "E:\ProgramData\Anaconda3\lib\site-packages\tornado\gen.py", line 1107, in run
        yielded = self.gen.throw(*exc_info)
      File "E:\ProgramData\Anaconda3\lib\site-packages\jupyterlab_latex\synctex.py", line 143, in run_synctex
        code, output = yield run_command(cmd)
      File "E:\ProgramData\Anaconda3\lib\site-packages\tornado\gen.py", line 1099, in run
        value = future.result()
      File "E:\ProgramData\Anaconda3\lib\site-packages\tornado\gen.py", line 296, in wrapper
        result = func(*args, **kwargs)
      File "E:\ProgramData\Anaconda3\lib\types.py", line 248, in wrapped
        coro = func(*args, **kwargs)
      File "E:\ProgramData\Anaconda3\lib\site-packages\jupyterlab_latex\util.py", line 25, in run_command_sync
        process = subprocess.run(cmd, stdout=subprocess.PIPE)
      File "E:\ProgramData\Anaconda3\lib\subprocess.py", line 403, in run
        with Popen(*popenargs, **kwargs) as process:
      File "E:\ProgramData\Anaconda3\lib\subprocess.py", line 709, in __init__
        restore_signals, start_new_session)
      File "E:\ProgramData\Anaconda3\lib\subprocess.py", line 997, in _execute_child
        startupinfo)
    FileNotFoundError: [WinError 2] The system cannot find the file specified

gyroscope.(tex/pdf/synctex.gz) are all in the same folder (at the base of the directories accessible given where I started the server)

Question about potential extensibility

If I were to hack up client-side LaTeX compiler support and run the plugin without the server extension, would I need to just replace latexRequest() function from index.ts?

conda package

Would you guys mind if I make a conda package? Couldn't find one ... or does it exist?

release package on pypi

@ian-r-rose do you think this is ready to be released as an early version on pypi so that others can more easily test it? I was thinking of bringing this up at today's jupyter dev meeting (2017_W50_2) and I realised I'd need to ask people listening to clone the repo to get it to work.

If it's not ready what should we work on to get it ready?

Binder version prompts "@jupyterlab/latex needs to be included in build"

Running on binderhub via the Binder button, I get the prompt:

Build Recommended
JupyterLab build is suggested:
@jupyterlab/latex needs to be included in build

accepting reloads the page and then just offers the same prompt again.

Selecting the .tex document and then right clicking on it only shows the Create Console for Editor and now the Show LaTeX Preview option.

Chrome 69.0.3497

Troubleshooting missing right click menu?

I've run all the steps in the readme, but I don't see the option on my .tex file to preview the file.

What are some steps I can do to troubleshoot?

Windows 7, fresh Jupyter Lab installation (0.31.4). pip install jupyterlab_latex, jupyter labextension install @jupyterlab/latex and I even tried jupyter serverextension enable --sys-prefix jupyterlab_latex

EDIT: MikTeX installed on my system, can successfully save notebooks to PDF which renders fine.

ContextManager for LaTeX files to handle cleanup in place

It would be nice to have a context manager that would clean up any and only the accessory files created by running LaTeX.

This can likely be accomplished by

  1. creating a representation of the local directory structure prior to running LaTeX
  2. creating a representation of the local directory structure after running LaTeX
  3. excluding the new pdf, removing all of the discrepancies between the states at 1. and 2.

If anyone knows of a likely issue related to that I'd be interested to know more about it.

Using pythontex

Hi,
is it possible to use the pythontex package? The only thing to change would be the latex command:
run pdflatex -> run pythontex -> run pdflatex
That would be really cool, because jupyterlab allows to connect the editor to an ipython konsole. That means the python code can be checked directly in the tex-file.
Thanks

To remove the error information

Hi,
I didn't notice the requirement of the python version to install the jupyterlab_latex on my python3.5. Failed, even though, some file were changed. Once I start the jupyter, the error jumpts out:

[W 03:04:58.268 NotebookApp] Error loading server extension jupyterlab_latex
    Traceback (most recent call last):
      File "/usr/local/lib/python3.5/dist-packages/notebook/notebookapp.py", line 1546, in init_server_extensions
        mod = importlib.import_module(modulename)
      File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
        return _bootstrap._gcd_import(name[level:], package, level)
      File "<frozen importlib._bootstrap>", line 986, in _gcd_import
      File "<frozen importlib._bootstrap>", line 969, in _find_and_load
      File "<frozen importlib._bootstrap>", line 956, in _find_and_load_unlocked
    ImportError: No module named 'jupyterlab_latex'

anything can be done to remove this info?
Thanks.

Make LaTeX calls non-blocking

As @mpacer can attest, LaTeX can take time to run. We should make the subprocess calls to *latex non-blocking. I believe that tornado has asynchronous wrappers for subprocess.

Menu item "File→New→Latex File" with customizeable template.

For most of Latex newbie is very difficult to create new correct LaTeX file without copy-pasting
all that stuff about \documentclass, set of packages, etc.

So, it will be great, if:

  • Jupyter-Latex will have setting like
    c.LatexConfig.latex_template_file = 'simple_article_for_our_institute.tex'
  • New menu "File→New→Latex File" will be added.
  • Calling "File→New→Latex File" we create new latex file from simple_article_for_our_institute.tex

Very simple but useful usecase.

Ideas for further improvements

  • May be with some template interpolation, but template processing looks not so important.
  • May be have set of templates ("article", "corporative report", "lab work", "book") and corresponding set of submenus under "File→New→Latex File"

Allow install to use node in PATH

I'm getting an error when installing because it's trying to use the node executable in my conda directory instead of the one on my PATH. I didn't install node from Conda, so I'm assuming that's a dependency of some other program.

The node from Conda is a lower version:

> ~/local/anaconda3/bin/node --version
v6.11.2

The node on my PATH is a higher version:

> node --version
v10.13.0

Especially when the error message says that node can be downloaded manually, I think the install should check if the node on the PATH is of a sufficiently high version.

Full install traceback:

> jupyter labextension install @jupyterlab/latex --debug
Searching ['/disk/agedisk3/medicare.work/doyle-DUA51929/barronk-dua51929/medicare-modernization/harmonization/code', '/disk/homedirs/barronk-dua51929/.jupyter', '/homes/nber/barronk-dua51929/local/anaconda3/etc/jupyter', '/usr/local/etc/jupyter', '/etc/jupyter'] for config files
Looking for jupyter_config in /etc/jupyter
Looking for jupyter_config in /usr/local/etc/jupyter
Looking for jupyter_config in /homes/nber/barronk-dua51929/local/anaconda3/etc/jupyter
Looking for jupyter_config in /disk/homedirs/barronk-dua51929/.jupyter
Looking for jupyter_config in /disk/agedisk3/medicare.work/doyle-DUA51929/barronk-dua51929/medicare-modernization/harmonization/code
Traceback (most recent call last):

  File "/homes/nber/barronk-dua51929/local/anaconda3/lib/python3.6/site-packages/jupyterlab/commands.py", line 1483, in _node_check
    output = subprocess.check_output([node, 'node-version-check.js'], cwd=HERE)

  File "/homes/nber/barronk-dua51929/local/anaconda3/lib/python3.6/subprocess.py", line 336, in check_output
    **kwargs).stdout

  File "/homes/nber/barronk-dua51929/local/anaconda3/lib/python3.6/subprocess.py", line 418, in run
    output=stdout, stderr=stderr)

subprocess.CalledProcessError: Command '['/homes/nber/barronk-dua51929/local/anaconda3/bin/node', 'node-version-check.js']' returned non-zero exit status 1.


During handling of the above exception, another exception occurred:


Traceback (most recent call last):

  File "/homes/nber/barronk-dua51929/local/anaconda3/lib/python3.6/site-packages/jupyterlab/labextensions.py", line 77, in start
    ans = self.run_task()

  File "/homes/nber/barronk-dua51929/local/anaconda3/lib/python3.6/site-packages/jupyterlab/labextensions.py", line 106, in run_task
    for arg in self.extra_args

  File "/homes/nber/barronk-dua51929/local/anaconda3/lib/python3.6/site-packages/jupyterlab/labextensions.py", line 106, in <listcomp>
    for arg in self.extra_args

  File "/homes/nber/barronk-dua51929/local/anaconda3/lib/python3.6/site-packages/jupyterlab/commands.py", line 217, in install_extension
    _node_check(logger)

  File "/homes/nber/barronk-dua51929/local/anaconda3/lib/python3.6/site-packages/jupyterlab/commands.py", line 1489, in _node_check
    raise ValueError(msg)

ValueError: Please install nodejs >=6.11.5 before continuing. nodejs may be installed using conda or directly from the nodejs website.


Errored, use --debug for full output:
ValueError: Please install nodejs >=6.11.5 before continuing. nodejs may be installed using conda or directly from the nodejs website

Install hangs at webpack

When installing from either the egg or source, install is stuck at the yarn run command of webpack --config webpack.prod.config.js forever.

When attempting to manually run the command in the build script, the following error is thrown:

node /home/ritwik/.pyenv/versions/3.6.4/lib/python3.6/site-packages/jupyterlab/staging/yarn.js run webpack --config webpack.prod.config.js
yarn run v1.3.2
$ /mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/.bin/webpack --config webpack.prod.config.js
/mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/webpack-cli/bin/webpack.js:237
                                throw err;
                                ^

Error: Cannot find module '/mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/webpack.prod.config.js'
    at Function.Module._resolveFilename (module.js:538:15)
    at Function.Module._load (module.js:468:25)
    at Module.require (module.js:587:17)
    at require (/mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/v8-compile-cache/v8-compile-cache.js:159:20)
    at WEBPACK_OPTIONS (/mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/webpack-cli/bin/convert-argv.js:133:13)
    at requireConfig (/mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/webpack-cli/bin/convert-argv.js:135:6)
    at /mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/webpack-cli/bin/convert-argv.js:142:17
    at Array.forEach (<anonymous>)
    at module.exports (/mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/webpack-cli/bin/convert-argv.js:140:15)
    at yargs.parse (/mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/webpack-cli/bin/webpack.js:234:39)
    at Object.parse (/mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/yargs/yargs.js:539:18)
    at /mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/webpack-cli/bin/webpack.js:212:8
    at Object.<anonymous> (/mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/webpack-cli/bin/webpack.js:504:3)
    at Module._compile (module.js:643:30)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)
    at Module.require (module.js:587:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/mnt/c/Users/Ritwik/Documents/GitHub/jupyterlab-latex/node_modules/webpack/bin/webpack.js:12:2)
    at Module._compile (module.js:643:30)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)
    at Function.Module.runMain (module.js:684:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Of note, I had to manually install webpack and webpack-cli because those were not installed with npm or yarn.

Jupyterlab-latex installed but error says it's not

Hi, I'm running a jupyterlab 0.32.1 on Ubuntu 16.04, Anaconda 4.5.8

Output of jupyter labextension list

JupyterLab v0.32.1
Known labextensions:
   app dir: /opt/anaconda3/share/jupyter/lab
@jupyter-widgets/jupyterlab-manager
        @jupyter-widgets/jupyterlab-manager v0.35.0  enabled  OK
@jupyterlab/hub-extension
        @jupyterlab/hub-extension v0.9.0  enabled  OK
@jupyterlab/latex
        @jupyterlab/latex v0.3.1  enabled  OK
@oriolmirosa/jupyterlab_materialdarker
        @oriolmirosa/jupyterlab_materialdarker v0.3.1  enabled  OK
jupyterlab-drawio
        jupyterlab-drawio v0.2.0  enabled  OK

But when I try to preview a .tex file, I got the error:

Server Extension Error
You probably do not have jupyterlab_latex installed or enabled. Please, run "pip install -U jupyterlab_latex." If that does not work, try "jupyter serverextension enable --sys-prefix jupyterlab_latex".

I have xetex installed in the same conda environment by

conda install -c conda-forge texlive-core 

Any insights where I did wrong? When I tried

sudo jupyter serverextension enable --sys-prefix jupyterlab_latex

I got

Enabling: jupyterlab_latex
- Writing config: /opt/anaconda3/etc/jupyter
    - Validating...
Error loading server extension jupyterlab_latex
      X is jupyterlab_latex importable?

Latex file path is not correct

It happens when Jupyter is executed outside of $HOME.

The error I got is Request cannot be completed; no file at /home/hadim/my_latex.tex. My file is located at /home/hadim/Documents/my_latex.tex.

pdf build fails with BibTeX error

Attempting to buld a simple latex file :

\documentclass{article}
\usepackage{graphicx}

\begin{document}

\title{Introduction to \LaTeX{}}
\author{Author's Name}

\maketitle

\begin{abstract}
The abstract text goes here.
\end{abstract}

\section{Introduction}
Here is the text of your introduction.

\begin{equation}
    \label{simple_equation}
    \alpha = \sqrt{ \beta }
\end{equation}

\subsection{Subsection Heading Here}
Write your subsection text here.

\begin{figure}
    \centering
    \includegraphics[width=3.0in]{f1.png}
    \caption{Simulation Results}
    \label{simulationfigure}
\end{figure}

\section{Conclusion}
Write your conclusion here.

\end{document}

I got this log in the jupyterlab LaTex error page:

This is BibTeX, Version 0.99d (TeX Live 2015/Debian)
The top-level auxiliary file: test.aux
I found no \citation commands---while reading file test.aux
I found no \bibdata command---while reading file test.aux
I found no \bibstyle command---while reading file test.aux
(There were 3 error messages)

On the server side I had this printed in the shell logs:

[E 22:11:08.462 LabApp] 500 GET /latex/Geoscience_250279/test.tex?1517346661474 (24.60.210.45) 6748.27ms referer=http://localhost.com:8888/lab?
[E 22:11:15.299 LabApp] LaTeX command `bibtex test` errored with code: 2
[E 22:11:15.300 LabApp] {
      "Host": "localhost:8888",
      "Connection": "keep-alive",
      "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
      "Authorization": "token 61a9550d5582b66719ad3d0182eff3f073044bcbc98e175b",
      "Content-Type": "application/json",
      "Accept": "*/*",
      "Referer": "http://localhost.com:8888/lab?",
      "Accept-Encoding": "gzip, deflate",
      "Accept-Language": "en-US,en;q=0.9,it;q=0.8",
      "Cookie": "_xsrf=2|0b5c6cb6|ca94c1b60c2d87a63763bb86543ebd5e|1515963402; username-epinux-com-7777=\"2|1:0|10:1515986637|24:username-epinux-com-7777|44:ZGNmZThiZWRkMTk1NDM1OWEzYmEwZTc1NzU4YmFhYTM=|063e5c9ce720c0d41be769861981f393a24732b7b2fa0bb6b090f05303eeee48\"; G_ENABLED_IDPS=google; username-epinux-com-8888=\"2|1:0|10:1517346668|24:username-epinux-com-8888|44:M2U0NzhhMjBhYjFkNGQ5N2FkYmI0NGU4NjcyNWRmZmQ=|c1016701feba63f47a89022f5470618fec41aede7153c1c731457aae9bea778e\""
    }
[E 22:11:15.300 LabApp] 500 GET /latex/Geoscience_250279/test.tex?1517346668437 (24.60.210.45) 6787.85ms referer=http://localhost:8888/lab?

ErrorPanel does not reopen if manually closed

Currently we do not open a new ErrorPanel if the panel has been opened once before and it has since been manually closed.

I'm not sure how to handle this. I came across in when working on #13 but I just checked and this also happens on master.

"real" live preview.

I was showing of this extension yesterday, with the "surprise" that PDF would refresh only on save.
So IFAICT you have foo.tex you need to save ti to see the updated PDF.

Potential proposal after earlier discussions, add options to do the following:

  • autosave after N second of inactivity.
  • use a temp-file that save more often and show its pdf.

Also figure out a quicker way of knowing whether syntax is correct.

Nick pointed to https://github.com/yitzchak/latex-language-server

Did we say other things ?

Setting shell_escape in config dose not work

I'm reporting this as a bug, as I cant seem to pass the command from jupyter config.

Seems like the only way to make it work, is manually modifying the source code and building the extension with:

shell_escape = CaselessStrEnum(['restricted', 'allow', 'disallow'],
default_value='allow', config=True,

in jupyterlab-latex/jupyterlab_latex/config.py

synctex fails on ubuntu

I have a similar issue as #78, however, I am on Ubuntu

jupyterlab v0.33.7
jupyterlab/latex v0.4.0

when I try to perform synctex from the editor to the pdf, i get the following error message:

[E 11:36:18.394 LabApp] Uncaught exception GET /latex/synctex/LATEX/icrc/main.tex?line=36&column=105&1533634578374 (127.0.0.1)
    HTTPServerRequest(protocol='http', host='localhost:8888', method='GET', uri='/latex/synctex/LATEX/icrc/main.tex?line=36&column=105&1533634578374', version='HTTP/1.1', remote_ip='127.0.0.1')
    Traceback (most recent call last):
      File "/home/flori/anaconda/lib/python3.6/site-packages/tornado/web.py", line 1543, in _execute
        result = yield result
      File "/home/flori/anaconda/lib/python3.6/site-packages/tornado/gen.py", line 1099, in run
        value = future.result()
      File "/home/flori/anaconda/lib/python3.6/site-packages/tornado/gen.py", line 1113, in run
        yielded = self.gen.send(value)
      File "/home/flori/anaconda/lib/python3.6/site-packages/jupyterlab_latex/synctex.py", line 190, in get
        out = json.dumps(parse_synctex_response(out, pos))
      File "/home/flori/anaconda/lib/python3.6/site-packages/jupyterlab_latex/synctex.py", line 214, in parse_synctex_response
        raise Exception('Unable to parse SyncTeX response')
    Exception: Unable to parse SyncTeX response
[W 11:36:18.394 LabApp] Unhandled error
[E 11:36:18.395 LabApp] {
      "Host": "localhost:8888",
      "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0",
      "Accept": "*/*",
      "Accept-Language": "en-GB,en;q=0.5",
      "Accept-Encoding": "gzip, deflate",
      "Referer": "http://localhost:8888/lab",
      "Authorization": "token afef98a9e4bef8006e1a029c51aee570fd7cbcaf09da7289",
      "Content-Type": "application/json",
      "Origin": "http://localhost:8888",
      "Cookie": "username-localhost-8888=\"2|1:0|10:1533634576|23:username-localhost-8888|44:ZDI3NDE3MTFhNTc1NDc3NWIxMjc5NDQ4ZDBmOTMwZWE=|c429fb2c2e3ad02e422b6f80bd5d247cbffcdbf9a05852376f39fa420cf17abf\"; _xsrf=2|9e21a47e|a267c52c66d22154bd876061f5360638|1533561997",
      "Connection": "keep-alive",
      "Pragma": "no-cache",
      "Cache-Control": "no-cache"
    }
[E 11:36:18.395 LabApp] 500 GET /latex/synctex/LATEX/icrc/main.tex?line=36&column=105&1533634578374 (127.0.0.1) 4.63ms referer=http://localhost:8888/lab

And similarly from pdf to latex:

[E 11:37:15.488 LabApp] SyncTex command `synctex edit -o 2:0:0:main.pdf` errored with code: 255
[E 11:37:15.488 LabApp] Uncaught exception GET /latex/synctex/LATEX/icrc/main.pdf?page=2&x=0&y=0&1533634635471 (127.0.0.1)
    HTTPServerRequest(protocol='http', host='localhost:8888', method='GET', uri='/latex/synctex/LATEX/icrc/main.pdf?page=2&x=0&y=0&1533634635471', version='HTTP/1.1', remote_ip='127.0.0.1')
    Traceback (most recent call last):
      File "/home/flori/anaconda/lib/python3.6/site-packages/tornado/web.py", line 1543, in _execute
        result = yield result
      File "/home/flori/anaconda/lib/python3.6/site-packages/tornado/gen.py", line 1099, in run
        value = future.result()
      File "/home/flori/anaconda/lib/python3.6/site-packages/tornado/gen.py", line 1113, in run
        yielded = self.gen.send(value)
      File "/home/flori/anaconda/lib/python3.6/site-packages/jupyterlab_latex/synctex.py", line 190, in get
        out = json.dumps(parse_synctex_response(out, pos))
      File "/home/flori/anaconda/lib/python3.6/site-packages/jupyterlab_latex/synctex.py", line 214, in parse_synctex_response
        raise Exception('Unable to parse SyncTeX response')
    Exception: Unable to parse SyncTeX response
[W 11:37:15.489 LabApp] Unhandled error
[E 11:37:15.489 LabApp] {
      "Host": "localhost:8888",
      "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0",
      "Accept": "*/*",
      "Accept-Language": "en-GB,en;q=0.5",
      "Accept-Encoding": "gzip, deflate",
      "Referer": "http://localhost:8888/lab",
      "Authorization": "token afef98a9e4bef8006e1a029c51aee570fd7cbcaf09da7289",
      "Content-Type": "application/json",
      "Origin": "http://localhost:8888",
      "Cookie": "username-localhost-8888=\"2|1:0|10:1533634631|23:username-localhost-8888|44:NWJmNjJhODNlOWViNDJiZGI3N2RlYzIzNGIwMDFkODE=|e8ad8751d6e3c2ddb8211b2840eabb5dd0c28c08ee2d13338c7624ce5543daed\"; _xsrf=2|9e21a47e|a267c52c66d22154bd876061f5360638|1533561997",
      "Connection": "keep-alive",
      "Pragma": "no-cache",
      "Cache-Control": "no-cache"
    }
[E 11:37:15.489 LabApp] 500 GET /latex/synctex/LATEX/icrc/main.pdf?page=2&x=0&y=0&1533634635471 (127.0.0.1) 4.93ms referer=http://localhost:8888/lab

My .tex files are compiled with pdflatex and I use bibtex for the bibliography. Also synctex is available in my path.

As a sidenote, synctex also works perfectly with the Latex Workshop extension of vscode.

Any ideas to solve this problem?

Use react for structured component rendering

Wanted to use react for rendering new components. The only way I could figure out how to get it to work was to have a component that rendered contents into the existing ErrorPanel widget, PR enroute.

Troubles with verison of jupyter lab

Hi, I'm trying to install your package, but got some issues with versions.

It is mentioned in the readme that we need Jupyter lab version 1.0, so I went ahead and got jupyterlab==1.0.0.a1 because it seems to be the latest !

However, when I run :
jupyter labextension install @jupyterlab/latex

I get :
Errored, use --debug for full output:
ValueError: This extension does not yet support the current version of JupyterLab.

Conflicting Dependencies:
JupyterLab Extension Package
>=1.0.0-alpha.3 <2.0.0 >=0.19.1 <0.20.0 @jupyterlab/application
>=1.0.0-alpha.3 <2.0.0 >=0.19.1 <0.20.0 @jupyterlab/apputils
>=1.0.0-alpha.3 <2.0.0 >=0.19.1 <0.20.0 @jupyterlab/docmanager
>=1.0.0-alpha.3 <2.0.0 >=0.19.1 <0.20.0 @jupyterlab/fileeditor

Any insight as to how I should deal with this ?
Thank you and I hope I will be able to try you package !

Plugin not showing up in lab

I hope it's not a stupid mistake from me but following the instructions, I only have the standard editor when I try to open a .tex file.

 $ conda list jupyter
# packages in environment at /home/hadim/local/conda:
#
jupyter                   1.0.0                    py36_0    conda-forge
jupyter_client            5.2.2                    py36_0    conda-forge
jupyter_console           5.2.0                    py36_0    conda-forge
jupyter_core              4.4.0                      py_0    conda-forge
jupyterlab                0.31.8                   py36_1    conda-forge
jupyterlab-latex          0.2.0                     <pip>
jupyterlab_launcher       0.10.5                   py36_0    conda-forge
$ jupyter labextension list
JupyterLab v0.31.8
Known labextensions:
   app dir: /home/hadim/local/conda/share/jupyter/lab
@jupyterlab/google-drive
        @jupyterlab/google-drive v0.11.1  enabled  OK
@jupyterlab/latex
        @jupyterlab/latex v0.2.0  enabled  OK
@jupyterlab/plotly-extension
        @jupyterlab/plotly-extension v0.14.4  enabled  OK
jupyterlab-drawio
        jupyterlab-drawio v0.1.2  enabled  OK

synctex

Feature request. Compiling latex with the -synctex=1 flag allows TeXStudio (and others) to link the source code and pdf so one can right click on the pdf and "go to source". This is the main thing I miss when using this extension compared to TeXStudio. I'd switch over completely if this extension had synctex support.

Lazily load PDF.js

PDF.js is a multi-megabyte library. We should lazily load it so as to keep the main JupyterLab repository smaller.

Not supported on windows

Specifically because tornado support for windows is not official/experimental.

from tornado.process import Subprocess

Going down this rabbit hole, I found that it relies on a package called "fcntl" which is not available on windows. A shame as I'd really like to start using this extension.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.