Vários modos principais em um buffer (por exemplo, modo python e modo LaTeX)

7

Usando o pacote LaTeX pythontex I, é possível inserir o código python no documento de látex que é executado (e impresso no seu arquivo de látex, se desejar), se você executar o látex. Eu uso o auctex para editar arquivos de látex, no entanto, editar o código python dentro do documento de látex é um pouco doloroso, pois o buffer está no modo látex e não no modo python, portanto, não há ajuda para a indentação adequada do código python e nenhum destaque de sintaxe .

Existe alguma maneira razoável de misturar o modo python com o modo látex? Por exemplo, o buffer passa automaticamente para o modo python se o ponto estiver dentro de um código python cortado? O que tenho que adicionar ao meu arquivo .emacs para que ele funcione? Alguma outra ideia?

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usepackage{pythontex}

\begin{document}

\begin{pycode}
print('test1')
def f( ):
    print('test2')

f()
\end{pycode}   

\pyc{f()}
\end{document}

Note que pythontextem vários ambientes e comandos que podem conter pythoncode, por exemplo pycode, ou pyverbatimcomo ambientes ou \pycou \pycomo comandos.

aluna
fonte
11
Isso é algo fácil de fazer com os org-modeblocos de origem (também gera TeX), mas isso adiciona outra camada de indireção sobre o LaTeX e às vezes dificulta a afetação do código TeX que está sendo gerado.
Wvxvw
2
O pacote polymode emacs pode fazer isso. Você provavelmente precisa escrever um novo back-end, mas isso deve ser fácil.
Ista 07/02
@ Ista: Como seriam as partes relevantes para o polimodo (assim como na resposta de JeanPierre para o modo mmm)?
estudante de
@ aluno: Eu não uso o pythontex e não tenho nenhum interesse em configurá-lo apenas para responder a essa pergunta, então o melhor que posso fazer é apontar a documentação do polimodo
Ista 09/02
Houve uma breve discussão nos comentários de outra pergunta, com o resultado de que essa pergunta deveria ter um título mais geral. Isso torna a excelente resposta aceita dessa pergunta mais acessível.
Tobias

Respostas:

9

MMM-mode(vários modos principais) parece exatamente o que você está procurando. É mencionado no wiki do emacs . Você precisa definir uma classe de submodo para combinar o LaTeX e o python, especificando que as partes do python são delimitadas pelas pycodetags LaTeX. Adicionar o seguinte ao seu arquivo init deve fazê-lo:

(require 'mmm-auto)
(mmm-add-classes
 '((latex-python
    :submode python-mode
    :face mmm-default-submode-face
    :front "\\\\begin{pycode}\n"
    :back "\\\\end{pycode}\n")))

(setq mmm-global-mode 'maybe)
(mmm-add-mode-ext-class 'latex-mode nil 'latex-python)

As palavras :front- :backchave e especificam expressões regulares para delimitadores. As duas últimas linhas solicitam que mmm-modea latex-pythonclasse seja ativada por padrão em todos os buffers cujo modo principal é latex-mode.

Consulte a documentação para outras opções (ativando-a manualmente, com base no nome do arquivo ou com variáveis ​​de arquivo).

Existem duas maneiras de especificar vários pares de delimitadores. Primeiro, várias classes podem ser ingressadas em um grupo . Abaixo, em vez de definir a latex-pythonclasse, definimos como um grupo que contém as duas classes latex-python-envse latex-python-cmds(ele próprio reconhece os comandos \pyc{…}e \py{…}LaTeX).

Segundo, cada classe pode especificar vários pares de delimitadores: a classe latex-python-envsabaixo reconhecerá os dois pycodee os pyverbatimenvs do LaTeX ( ~1in :backrefere-se ao valor correspondente no primeiro grupo entre parênteses em :front).

(mmm-add-group 'latex-python
 '((latex-python-envs
    :submode python-mode
    :face mmm-default-submode-face
    :front "\\\\begin{\\(pycode\\|pyverbatim\\)}\n"
    :back "\\\\end{~1}\n"
    :save-matches 1)

   (latex-python-cmds
    :submode python-mode
    :face mmm-default-submode-face
    :front "\\\\pyc?{"
    :back "}")))

Para que os delimitadores sejam reconhecidos, é necessário mmm-parse-buffer( C-c % C-b) (ou mmm-parse-region, ou mmm-parse-blockseja, algumas linhas ao redor do ponto). Se você está acostumado a inserir envs do LaTeX através de LaTeX-insert-environment( C-c C-e), pode ser conveniente aconselhá- lo a executar mmm-parse-blockquando terminar, para que o MMM reconheça imediatamente as tags inseridas recentemente:

(advice-add 'LaTeX-insert-environment ':after 
    '(lambda (env) (mmm-parse-block 2)))
Jean Pierre
fonte
Obrigado. Como posso adicionar outros ambientes e comandos que podem conter código python (por exemplo \pycou pyverbatim). Existe uma maneira de fazer o modo mmm detectar automaticamente se eu inserir um pycodeambiente?
student
Acabei de perceber que o TAB não funciona conforme o esperado. Por exemplo: \begin{pycode} + ENTER + e insira um forloop, por exemplo, for i in range(0,10):+ ENTER + print(i)+ ENTER + \end{pycode}. O ENTER após a forlinha recua essa instrução, mas isso print(i)não funciona para você?
student
O MMM do @student precisa ser solicitado a analisar novamente e ver os dois delimitadores para que o submodo entre em vigor. Consulte a resposta atualizada. Deixe-me saber se você ainda está com problemas.
JeanPierre
Obrigado pela adição. Em relação ao recuo, testei novamente usando suas dicas e o problema descrito foi corrigido. No entanto, existem problemas de recuo mais avançados: primeiro, se você inserir um pycodeambiente, o modo de látex o fará automaticamente e você precisará usar a TAB explicitamente para corrigir isso; outro problema ocorrerá se você usar o pycode em outro ambiente. Eu fiz um screencast para esclarecer o que quero dizer: expirebox.com/download/e348355feabb8bb5d8c8399b97bccdb8.html
student
O método que você sugeriu acima para incluir vários ambientes também funciona se você deseja corresponder também aos comandos \pyce \py?
estudante de