package provide stead 2.0


## te:sys_fmt -- effectue un fill systeme applique a la selection
# 
# modif 
#  26/10/98 (diam) : 
#       si pas de selection : on sélectionne la ligne courante
# 
# 12/09/00 diam : A FAIRE
#   - à refondre (avec wrap_line ci-dessous) est à integrer à xtext !
#   - gerer proprement le texte "multi-paragraphe"
#   - (gerer le rafraichissement des couleurs ? ou plutot prévoir une procédure 
#     hook pour rester indépendant de stead)
#   - rendre de plus en plus intelligent :
#       - festion des prefix de commentaire
#       - gestion d'une premiere ligne différente de la forme :
#               - voici la premier ligne d'un tiret
#                 et voici le seconde
# 
#               327 - voici la premier ligne d'un para numéroté
#                     et voici le seconde
#       - prévoir personnalisation suivant les modes (réindentation
#         d'un environnement itemise deans latex...)
# 
proc te:sys_fmt {} {
  
  global EDITPREFS
  
  # Si pas de sélection : on sélectionne la ligne courante :
  # A MODIFIER POUR SELECTIONNER LE PARAGRAPHE ENGLOBANT
  # (passer par la creation d'un procedure te:selectParagraph)
  if [catch {.main.t index sel.first} idx_foo ] {
      .main.t tag add sel \
          "insert linestart" \
          "insert lineend + 1 chars"
  }
  
  # on étend la sélection à des ligne entières :
  .main.t tag add sel \
      "sel.first linestart" \
      "sel.last -1 chars lineend + 1 chars"

  # A ameliorer : garder l'indent de la premier ET de la deuxieme ligne
  # mais il faudra egalement modifier la proc stead_wrapString en rajoutant 
  # un parametre indentstring2 (valant pas defaut indentstring1:
  # # # on récupère l'indentation de la deuxieme ligne (pour la conserver)
  # # set line [.main.t get "sel.first + 1 line" "sel.first + 1 line lineend"]
  # # set indentString ""
  # # regexp "^(\[ \t\]*).*\$" $line wholeLine indentString
  
  # on récupère l'indentation de la première ligne (pour la conserver)
  catch {set line [.main.t get sel.first "sel.first lineend"]}
  set indentString ""
  regexp "^(\[ \t\]*).*\$" $line wholeLine indentString
  
  
  # On récupère la sélection dans txt (si elle existe)
  set txt [selection get]
  # if {[catch {selection get} txt]} {
     # stead:log -title "ERROR in wrap selection" "No Selection in Text"
  # }

  # on formate la nouvelle chaine
  stead:log -title "fmt"  "formating selection ..."
  set newTxt [stead_wrapString $txt  $EDITPREFS(fillcolumn)  $indentString]
  
  # Sauvegarde pour undo éventuel
  xtext_pushState
  xtext_markDirty .main.t

  # On supprime la sélection
  .main.t delete sel.first sel.last
  
  # Om mémorise le debut de la future sélection
  set oldStartOfSel [.main.t index insert]
  
  # On insert le nouveau texte :
  .main.t insert insert $newTxt\n
  
  # On resélectionne le text :
  .main.t tag add sel $oldStartOfSel insert

}

## stead_wrapString -- egalise les lignes de la chaine
# 
# version diam du 09/02/96
# 23/02/96 : suppression des espaces/tabulations autour des returns
#            et indentation de la derniere ligne
# a faire : 
#   - gérer les paragraphes (ils sont considérer comme des espaces)
#   - insérer l'indent au début de la derniere ligne
#   - prévoir le cas ou l'indentstring est de la forme "    # "

proc stead_wrapString {txt len {indentString ""}} {

    # global stead
    # upvar 0 stead(text) w

    # set paragPat "\n\[ \t\]*\n+"
    # regsub -all $paragPat $txt "<<<PARAGRAPH>>> txt
    
    
    # on remplace les <return> et les espaces environnants par un espace :
    regsub -all "\[\t \]*\n\[\t \]*" $txt { } txt
    # # # regsub -all "\n" $txt { } txt
    
    # on vire les premiers espace/tabulation :
    set txt [string trimleft $txt]
    
    # incr len -1
    # stead:log -- [expr - [string length $indentString] - 1]
    stead:log  "[expr - [string length $indentString] - 1]"
    set len [expr $len - [string length $indentString] - 1]
    set out {}
    while {[string len $txt]>$len} {
        set e [string last { } [string range $txt 0 $len]]
        if {$e == -1} {
            set e [string first { } $txt]
            if {$e == -1} break
        }
        append out "$indentString"
        append out "[string trim [string range $txt 0 [incr e -1]]]\n"
        set txt [string range $txt [incr e 2] end]
    }
    return $out$indentString$txt
}
# # 
# # Idée d'amélioration : utiliser cette procedure de Jeff Hobbs 
# # (14/06/01 sur compl.lang.tcl)
# # 
# proc stead_wrapString [list txt {len 75} {P \n\n} {P2 \254}] {
#     # @author Jeffrey Hobbs <jeff.hobbs@acm.org>
#     #
#     # @c Wraps the given <a text> into multiple lines not
#     # @c exceeding <a len> characters each. Lines shorter
#     # @c than <a len> characters might get filled up.
#     #
#     # @a text:	The string to operate on.
#     # @a len:	The maximum allowed length of a single line.
#     # @a P:	Paragraph boundary chars, defaults to \n\n
#     # @a P2:	Substitute for $P while processing, defaults to \254
#     #		this char must not be in the input text
#     #
#     # @r Basically <a text>, but with changed newlines to
#     # @r restrict the length of individual lines to at most
#     # @r <a len> characters.
# 
#     # @n This procedure is not checked by the testsuite.
# 
#     # @i wrap, word wrap
# 
#     # Convert all instances of paragraph separator $P into $P2
#     # Convert all newlines into spaces and initialize the result
#     # In 8.2+ this would be one string map
# 
#     regsub -all $P $txt $P2 txt
#     regsub -all "\n" $txt { } txt
#     incr len -1
#     set out {}
# 
#     # As long as the string is longer than the intended length of
#     # lines in the result:
# 
#     while {[string len $txt]>$len} {
# 	# - Find position of last space in the part of the text
# 	#   which could a line in the result.
# 
# 	# - We jump out of the loop if there is none and the whole
# 	#   text does not contain spaces anymore. In the latter case
# 	#   the rest of the text is one word longer than an intended
# 	#   line, we cannot avoid the longer line.
# 
# 	set i [string last { } [string range $txt 0 $len]]
# 	if {$i == -1 && [set i [string first { } $txt]] == -1} { break }
# 
# 	# Get the just fitting part of the text, remove any heading
# 	# and trailing spaces, then append it to the result string,
# 	# don't close it with a newline!
# 
# 	append out [string trim [string range $txt 0 [incr i -1]]]\n
# 
# 	# Shorten the text by the length of the processed part and
# 	# the space used to split it, then iterate.
# 
# 	set txt [string range $txt [incr i 2] end]
#     }
# 
#     # Convert the preserved paragraph boundaries back
# 
#     regsub -all $P2 $out$txt $P txt
#     return $txt
# }

#./
