Liczba słów dla LaTeX-a w emacsie

19

Chcę policzyć, ile słów ma w nim mój dokument LaTeX. Mogę to zrobić, przechodząc na stronę internetową po pakiet texcount i używając tam interfejsu internetowego. ale to nie jest idealne.

Wolę mieć skrót w emacs, aby po prostu zwrócić liczbę słów w pliku (lub idealnie liczbę słów w pliku i we wszystkich plikach wywoływanych przez \inputlub \includew dokumencie). Pobrałem skrypt texcount, ale nie wiem co z nim zrobić. Oznacza to, że nie wiem, gdzie umieścić .plplik i jak go wywołać w emacsie.

To znaczy: chcę skrót klawiszowy do polecenia powłoki. Chcę, aby polecenie powłoki uruchomiło texcount na bieżącym aktywnym buforze i zwróciło wszystkie słowa w minibuforze.

Używam Ubuntu i emacs22, jeśli to pomaga ...

Seamus
źródło

Odpowiedzi:

15

(defun latex-word-count ()
  (interactive)
  (shell-command (concat "/usr/local/bin/texcount.pl "
                         ; "uncomment then options go here "
                         (buffer-file-name))))

Możesz zdecydować się na umieszczenie texcount.pl w innym miejscu niż / usr / local / bin, po prostu zmodyfikuj kod, jeśli to zrobisz. Spowoduje to utworzenie nowego polecenia „Mx latex-word-count”, które uruchomi texcount.pl na bieżącym pliku (da jednak zły wynik, jeśli plik nie został zapisany). Możesz usunąć średnik i zastąpić tekst wypełniający dowolnymi argumentami wiersza poleceń, jeśli chcesz. Możesz powiązać to z poleceniem klawiatury za pomocą czegoś takiego w swoim .emacs:

(define-key latex-mode-map "\C-cw" 'latex-word-count)

Strona opisująca sposób instalacji texcount znajduje się tutaj: texcount faq . Krótka wersja:

sudo cp texcount.pl /usr/local/bin/texcount.pl
lub alternatywnie możesz zrobić to, co zalecają, po prostu nazwij go texcount i odpowiednio zaktualizuj kod.

Justin Smith
źródło
Jeśli chcesz uwzględnić pliki \ input i \ include w sumie, dodaj „-inc” do swoich opcji.
Seamus
11

Oto nieco ładniejsza wersja powyższego skryptu (obsługuje spacje w nazwach plików, generuje wyjście w jednym wierszu itp.). LaTeXHaki są dla AuCTeX.

(defun my-latex-setup ()
  (defun latex-word-count ()
    (interactive)
    (let* ((this-file (buffer-file-name))
           (word-count
            (with-output-to-string
              (with-current-buffer standard-output
                (call-process "texcount" nil t nil "-brief" this-file)))))
      (string-match "\n$" word-count)
      (message (replace-match "" nil nil word-count))))
    (define-key LaTeX-mode-map "\C-cw" 'latex-word-count))
(add-hook 'LaTeX-mode-hook 'my-latex-setup t)
Nicholas Riley
źródło
2

Krótka wersja: M-! texcount <file.tex> RET

Chciałbym po prostu użyć dołączonego emacsa, shell-commandktóry jest

M-! <cmd> RET

wraz z texcount(texcount.pl), który jest instalowany z większością dystrybucji lateksowych. Podczas edycji dokumentu po prostu naciśnij M-!Enter texcount <tex-file>i naciśnij Return.

Pływ
źródło
1
To był również najszybszy sposób, aby przejść dla mnie. Dzięki!
Jimi Oke
2

Łatwą kombinacją innych opublikowanych tutaj rozwiązań byłoby:

(defun latex-word-count ()
   (interactive)
   (shell-command (concat "texcount " ; my latex installation includes texcount.pl
                       ; "uncomment then options go here, such as "
                       "-unicode "
                       "-inc "
                       (buffer-file-name))) ; better than typing path to current file
)

(define-key LaTeX-mode-map "\C-cw" 'latex-word-count)
plgx
źródło
2

Na przyszłość, kilka z tych odpowiedzi można by poprawić, używając funkcji shell-quote-argument, aby upewnić się, że spacje i inne zabawne formatowanie w nazwie pliku będą obsługiwane poprawnie. Na przykład, aby poprawić odpowiedź plgx:

(defun latex-word-count ()
   (interactive)
   (shell-command (concat "texcount "
                       ; "uncomment then options go here, such as "
                       "-unicode "
                       "-inc "
                       (shell-quote-argument buffer-file-name))) 
;Now the buffer file name is sent correctly to the shell, 
;regardless of platform
)

(define-key LaTeX-mode-map "\C-cw" 'latex-word-count)
Eric Greenwood
źródło
1

Możesz także użyć wbudowanego M-x tex-count-words. Aby utworzyć skrót klawiaturowy, dodaj do.emacs

(add-hook 'latex-mode-hook
          (lambda () (local-set-key (kbd "C-c C-w") 'tex-count-words)))
fgregg
źródło
0

Nie wiem, czy to pomogłoby komukolwiek, ale kiedy pisałem pracę magisterską, chciałem zrobić dwie rzeczy; (1) policz liczbę słów dla całej pracy magisterskiej (zamiast jednego rozdziału) i (2) użyj niestandardowego skryptu licznika. Chodziło o to, że omijałoby to takie sekcje jak streszczenia, deklaracje itp. I wybierało tylko odpowiednie rozdziały.

Policz słowa z pliku głównego

Rozwiązanie tutaj było proste; dowiedz się, czy plik, w którym się znajdujemy, jest plikiem głównym, w przeciwnym razie wyślij go na adres texcount.

(defun latex-word-count-master ()
  (interactive)
  (if (eq TeX-master t)
      (setq master (buffer-file-name))
    (setq master (concat (expand-file-name TeX-master) ".tex")))
  (shell-command (concat "texcount "
                         "-dir "
                         "-unicode "
                         "-inc "
                         master)))

Użyj skryptu niestandardowego

Zrobiłem to, dodając custom-tex-counterzmienną lokalną do dołączonego pliku, wskazując skrypt bash, który był odpowiedzialny za liczenie słów.

  • Zadeklaruj zmienną niestandardową

    (defvar custom-tex-counter nil)
    (make-variable-buffer-local 'custom-tex-counter)
    (put 'custom-tex-counter 'safe-local-variable #'stringp)
    
  • Dodaj ścieżkę do zmiennych lokalnych (koniec .texpliku)

    %%% Local Variables:
    %%% mode: latex
    %%% TeX-master: "../thesis"
    %%% custom-tex-counter: "../count_words -t"
    %%% End:
    
  • Łącząc to z powyższym

    (defun latex-word-count-alt ()
      (interactive)
      (if (eq TeX-master t)
          (setq master (buffer-file-name))
        (setq master (concat (expand-file-name TeX-master) ".tex")))
      (if (not (eq custom-tex-counter nil))
          (shell-command (concat custom-tex-counter
                                 " "
                                 master))
        (shell-command (concat "texcount "
                               "-dir "
                               "-unicode "
                               "-inc "
                               master))))
    

Dla odniesienia oto, jak wyglądał mój własny skrypt (nie zapomnij, aby był wykonywalny):

#!/usr/bin/bash

total='false'

while getopts 't' flag; do
  case "${flag}" in
    t) total='true' ;;
    ?) printf '\nUsage: %s: [-t] \n' $0; exit 2 ;;
  esac
done

shift $(($OPTIND - 1))

TOPATH=$(dirname "${1}")

CHAPTERS=$(while read -r chapter; do
               printf "%s%s.tex\n" "$TOPATH" "/$chapter";
           done < <(grep -Po "^[^%]\s?\\include{\K(Chapter|Appendix)[[:digit:]]+/(chapter|appendix)[[:digit:]]+" "${1}") \
           | paste -sd' ')

if [ "$total" == "false" ]; then
    texcount -unicode -inc $CHAPTERS
else
    texcount -unicode -total -inc $CHAPTERS
fi

Zasadniczo jedyne, co robi, to grepnieskomentowane rozdziały i dodatki z pliku głównego i policz tam słowa.

Możesz zmienić regex dla każdego projektu, aby pasował do struktury, której używasz, ale jeśli konsekwentnie używasz tej samej struktury, możesz umieścić skrypt bash gdzieś na swojej ścieżce i uczynić go zmienną globalną w emacs zamiast lokalnej.

dalikan
źródło