2011-09-26 9 views
5

Talvolta è preferibile iniziare ciascuna frase in un paragrafo su una riga separata. Ad esempio, questo semplifica la diffusione di documenti di grandi dimensioni, poiché una modifica di una frase non influisce sull'intero paragrafo. Alcuni sistemi di markup (ad es. * Roff) richiedono anche che ogni frase inizi su una nuova riga.C'è un modo per fermare il punto di riempimento alla fine di una frase?

C'è un modo, ad es. con una ragionevole ridefinizione di paragraph-separate e paragraph-start, per rendere lo stop fill-paragraph tra una frase e l'altra?

(nota: io uso Emacs 23.3.1)


Aggiornamento: campione mdoc (* roff) markup:

The 
.Nm 
utility makes a series of passes with increasing block sizes. 
In each pass, it either reads or writes (or both) a number of 
non-consecutive blocks at increasing offsets relative to the ideal 
alignment, which is assumed to be multiples of the block size. 
The results are presented in terms of time elapsed, transactions per 
second and kB per second. 

Questo è un singolo paragrafo con tre frasi, ognuna delle quali inizia su una linea separata anche se c'è spazio per la prima parola (s) sulla riga precedente. Attualmente, fill-paragraph sarà trasformare questo in

The 
.Nm 
utility makes a series of passes with increasing block sizes. In each 
pass, it either reads or writes (or both) a number of non-consecutive 
blocks at increasing offsets relative to the ideal alignment, which is 
assumed to be multiples of the block size. The results are presented 
in terms of time elapsed, transactions per second and kB per second. 

che è quello che voglio evitare.


Aggiornamento: nelle frasi re e paragrafi

vedo che la mia domanda è un po 'poco chiaro, perché ho usato il termine "paragrafo" per fare riferimento sia a quello che Emacs chiama un paragrafo e per ciò che finisce come un blocco di testo continuo nell'output di qualsiasi processore che utilizzo (groff, latex ecc.). Per chiarire,

  • Ho bisogno di tenere insieme le frasi senza righe vuote tra loro; groff non ama le righe vuote, mentre il latex le vede come separatori di paragrafi.
  • Ho bisogno di fill-paragraph per operare su singole frasi, cioè voglio ridefinire un paragrafo come qualcosa che inizia dopo una riga vuota o la fine del paragrafo precedente e termina con un periodo seguito da un carattere di nuova riga o almeno due caratteri bianchi.
  • Mi piacerebbe avere fill-paragraph spezzare un blocco di testo in singole frasi, ma non penso che possa essere fatto facilmente.

Ad esempio, se di tipo seguente:

The 
.Nm 
utility makes a series of passes with increasing block sizes. 
In each pass, it either reads or writes (or both) a number of non-consecutive blocks at increasing offsets relative to the ideal alignment, which is assumed to be multiples of the block size. 
The results are presented in terms of time elapsed, transactions per second and kB per second. 

quindi spostare il punto alla linea che inizia con "In ogni passaggio" e premere M-q, devo ottenere i seguenti:

The 
.Nm 
utility makes a series of passes with increasing block sizes. 
In each pass, it either reads or writes (or both) a number of 
non-consecutive blocks at increasing offsets relative to the ideal 
alignment, which is assumed to be multiples of the block size. 
The results are presented in terms of time elapsed, transactions per second and kB per second. 

Si noti che l'ultima frase non è stata toccata.

risposta

1

Come circa dire paragraph-start per cercare qualsiasi riga che inizia con una lettera maiuscola:

"\f\\|[  ]*$\\|^[A-Z]" 

Si noti che la parte nuova è \\^[A-Z]

che dovrebbe funzionare per la maggior parte dei casi, si avrebbe solo guardare per i rari casi in cui si dispone di un capitale di metà di una frase, e quella frase sembra essere abbastanza a lungo per rompere poco prima che la parola a metà frase.

EDIT: probabilmente si desidera tenere conto di rientro troppo:

"\f\\|[  ]*$\\|^[ ]*[A-Z]" 

Lo spazio tra le parentesi quadre contiene uno spazio e una scheda.

MODIFICA: è necessario disattivare case-fold-search affinché funzioni, altrimenti le lettere maiuscole e minuscole non si distinguono nella partita!

EDIT: se si desidera disattivare caso-fold-search per appena questa funzione, associare il seguente per M-q (che si può fare a livello locale o globale, come si vede in forma).

(defun my-fill-paragraph() 
    (interactive) 
    (let ((case-fold-search nil)) 
    (fill-paragraph))) 
+0

Hmm, se la sintassi regexp di Emacs supporta asserzioni look-behind a lunghezza variabile di larghezza zero, dovrebbe essere possibile costruire un'espressione regolare che corrisponda al Perl re '/\.(?:\n|\s{2, }) \ K \ S/s', che corrisponde al primo carattere non di spaziatura dopo un periodo seguito da un carattere di fine riga o almeno da due caratteri di spaziatura. – DES

+0

Mi hai perso. Quando fallisce il regexp che ho postato? Suppongo che tu colpisca manualmente il ritorno dopo ogni frase mentre li inserisci, in modo che Emacs non debba dividere i paragrafi per te, deve solo rispettare i limiti della frase durante il riempimento. – Tyler

+0

Non credo Emacs supporta affermazioni, sia. – Tyler

1

Questo DTRT?

(defun separate-sentences (&optional beg end) 
    "ensure each sentence ends with a new line. 
When no region specified, use current paragraph." 
    (interactive (when (use-region-p) 
        (list (region-beginning) (region-end)))) 
    (unless (and beg end) 
    (save-excursion 
     (forward-paragraph -1) 
     (setq beg (point)) 
     (forward-paragraph 1) 
     (setq end (point)))) 
    (setq end (if (markerp end) 
       end 
       (set-marker (make-marker) end))) 
    (save-excursion 
    (goto-char beg) 
    (while (re-search-forward (sentence-end) end t) 
     (unless (or (looking-at-p "[ \t]*$") 
        (looking-back "^[ \t]*")) 
     (insert "\n"))))) 

(defun fill-paragraph-sentence-groups (justify) 
    "Groups of sentences filled together. A sentence ending with newline marks end of group." 
    (save-excursion 
    (save-restriction 
     (narrow-to-region (progn (forward-paragraph -1) (point)) 
         (progn (forward-paragraph 1) (point))) 
     (goto-char (point-min)) 
     (skip-chars-forward " \t\n") 
     (while (not (or (looking-at-p paragraph-separate) 
         (eobp))) 
     (fill-region (point) 
        (progn 
         (loop do (forward-sentence 1) 
          until (looking-at "[ \t]*$")) 
         (point)) 
        justify) 
     (unless (looking-back "^[ \t]*") 
      (forward-line 1))) 
     t))) 

(defun fill-paragraph-sentence-individual (justify) 
    "Each sentence in paragraph is put on new line." 
    (save-excursion 
    (separate-sentences) 
    (fill-paragraph-sentence-groups justify))) 

;; deployment option 1: add to major-mode hook 

(add-hook 'text-mode-hook (lambda() 
          (set (make-local-variable fill-paragraph-function) 'fill-paragraph-sentence-individual))) 

;; deployment option 2: call my-fill-paragraph any where 

(defun my-fill-paragraph (arg) 
    (interactive "*P") 
    (let ((fill-paragraph-function 'fill-paragraph-sentence-individual)) 
    (fill-paragraph arg))) 

Le funzioni di riempimento di due paragrafi sono presentate sopra. Un raggruppamento di frasi che non finiscono sulla nuova linea insieme. Un altro rompendo ogni frase in una nuova riga.

mi mostra solo come distribuire quella individuale perché è quello che il PO vuole. Segui il modello per distribuire la versione dei gruppi, se lo desideri.

+0

La questione non era come separare un paragrafo in frasi, ma come impedire a 'fill-paragraph' di riunirle. – DES

+0

La domanda non è molto chiara. Puoi aggiungere alcuni esempi di ciò che vuoi? Vuoi anche mantenere l'attuale comportamento di movimento del paragrafo? –

+0

Aggiunto markup di esempio. – DES

0

È possibile utilizzare fill-region che, ovviamente, riempie solo la regione corrente. Sulla base di che si potrebbe definire una funzione fill-sentence. Credo che un modo semplicistico di rilevare tali frasi è dire:

  • Se la linea termina con un ., ? o !, è una linea di fine frase.

  • Una linea inizia una frase se linea predecessore è vuota o una linea fine della frase.

È piuttosto complicato farlo funzionare correttamente in tutti i casi.

+0

Speravo in una combinazione di parametri che avrebbe reso DTRT 'fill-paragraph'. – DES

Problemi correlati