# jdoc_util.tcl - utility procedures for jdoc
#
###############################################################################
#  Copyright 1992-2001 by Jay Sekora.  This file may be freely distributed,   #
#  modified or unmodified, for any purpose, provided that this copyright      #
#  notice is retained verbatim in all copies and no attempt is made to        #
#  obscure the authorship of this file.  If you distribute any modified       #
#  versions, I ask, but do not require, that you clearly mark any changes     #
#  you make as such and that you provide your users with instructions for     #
#  getting the original sources.                                              #
###############################################################################

##############################################################################
# jdoc:init - basic initialisation
##############################################################################

proc jdoc:init {} {
  global aq_library
  global tk_library
  global J_PREFS			;# general aq user preferences
  global JDOC_PREFS			;# user preferences for jdoc
  global JDOC_PATH
  
  ::aq::aq_init aqdoc			;# prefs, libraries, bindings...
  
  j:rt:mkabbrevs			;# e.g. hl for j:rt:hl
  set JDOC_PATH "
    .
    [glob -nocomplain ~/tk/jdoc]
    [glob -nocomplain ~/.tk/jdoc]
    $aq_library/jdoc
    $tk_library/jdoc
  "
  
  jdoc:register_commands		;# force auto-loading of all commands
}


###############################################################################
#                                                     jdoc:resource_to_filename
# 
# search filesystem for filename corresponding to $resource
# return it if found; else null string.

proc jdoc:resource_to_filename { resource } {
  global JDOC_PREFS JDOC_PATH
  
  if { ! [string match "/*" $resource]} {
    #
    # not absolute path:
    #
    foreach dir $JDOC_PATH {
      foreach extension {.jhtml .jdoc} {
        if {[file exists $dir/$resource$extension]} {
          return $dir/$resource$extension
        }
      }
    }
  } else {
    #
    # absolute path:
    #
    foreach extension {.jhtml .jdoc} {
      if {[file exists $dir/$resource$extension]} {
        return $dir/$resource$extension
      }
    }
  }
  return {}
}


###############################################################################
#                                                               jdoc:load_topic
# 
# find and load a doc file, possibly jumping to a particular point in it
# the contents of the doc file will set up the Sections menu

proc jdoc:load_topic { topic } {
  global JDOC_PREFS JDOC_PATH
  
  .menu.sections.m delete 0 last
  
  set tmp_list [split $topic "#"]
  set resource [lindex $tmp_list 0]
  set anchor [lindex $tmp_list 1]
  
  if {[string match "http:*" $resource] || \
    [string match "ftp:*" $resource] || \
    [string match "*.html" $resource]} {
    wm withdraw .
    ::aq::view_url $topic
    exit 0
  }
  
  set FOUND 0
  
  # trim any trailing .jhtml or .jdoc from topic; will search for both
  #   in filesystem
  regsub -all -nocase -- {\.jhtml$|.jdoc$} $resource {} resource
  
  set filename [jdoc:resource_to_filename $resource]
  if {[string length $filename]} {
    tkwait visibility .t		;# unpatched Tk 3.6 bug workaround
    ::aq::tag::restore_text_widget .t $filename
    .t tag remove sel 1.0 end
    .t mark set insert 1.0
    .t yview 1.0
    .t configure -state disabled
    if {"x$anchor" != "x"} {		;# jump to anchor given
      jdoc:go_to_anchor $anchor .t
    }
  } else {
    .t configure -state normal
    j:rt text .t
    j:rt:hl "Can't find a document called `$resource'."
    j:rt:par
    j:rt:rm "The requested document was not found.  "
    j:rt:rm "It may not have been installed at your site."
    j:rt:done
    .t configure -state disabled
    tkwait window .
    exit 1
  }
  
  .menu.sections.m add command -label "Top" -command {
    .t mark set insert 1.0
    .t yview insert
  }
  .menu.sections.m add separator
  foreach pair [jdoc:find_sections .t] {
    set section [lindex $pair 0]
    set location [lindex $pair 1]
    .menu.sections.m add command -label $section \
      -command ".t mark set insert $location; .t yview insert"
  }
  .menu.sections.m add separator
  .menu.sections.m add command -label "Bottom" -command {
    .t mark set insert end
    .t yview -pickplace insert
  }
  
  wm title . "$resource"
  wm iconname . "$resource"
}

######################################################################
# jdoc:find_sections t - find all level 1 headings in text
######################################################################

proc jdoc:find_sections { t } {
  set ranges [$t tag ranges richtext:font:heading1]
  set sections {}
  
  ;# step through ranges two-at-a-time (start and end)
  while { [llength $ranges] > 0 } {
    set start [lindex $ranges 0]
    set end [lindex $ranges 1]
    set ranges [lreplace $ranges 0 1]	;# with nothing, ie shift
    set section_name [string trim [$t get $start $end]]
    set section_name [lindex [split $section_name "\n"] 0]
    lappend sections [list $section_name $start]
  }
  return $sections
}

######################################################################
# jdoc:configure_text t - text widget configuration
######################################################################

proc jdoc:configure_text { { t .t } } {
  global JDOC_PREFS
  
  if {$JDOC_PREFS(textwidth) < 20} {set JDOC_PREFS(textwidth) 20}
  if {$JDOC_PREFS(textheight) < 4} {set JDOC_PREFS(textheight) 4}
  
  # fonts:
  j:rt text .t				;# let j:rt set default font
  j:rt:done
  
  # hypertext styles and bindings:
  $t tag configure jdoc:xref:link -underline 1
  $t tag configure jdoc:xref:manpage -underline 1
  $t tag bind jdoc:xref:link <ButtonRelease-1> \
    {jdoc:x_link %W %x %y}
  $t tag bind jdoc:xref:manpage <ButtonRelease-1> \
    {jdoc:x_manpage %W %x %y}
  $t tag configure jdoc:xref:link -underline 1
  $t tag bind jdoc:xref:manpage <ButtonRelease-1> {jdoc:x_manpage %W %x %y}
  
  # list styles:
  $t tag configure special:list_item:1 -font \
    -*-symbol-*-*-*-*-*-120-*-*-*-*-*-*
  $t tag configure special:list_item:2 -font \
    -*-symbol-*-*-*-*-*-120-*-*-*-*-*-*
  $t tag configure special:hr:normal -font nil2 -background black
  catch {
    $t tag configure list:level:1 -lmargin1 9m -lmargin2 9m
    $t tag configure list:level:2 -lmargin1 18m -lmargin2 18m
  }
  catch {
    $t tag configure special:list_item:1 -lmargin1 5m -lmargin2 5m
    $t tag configure special:list_item:2 -lmargin1 14m -lmargin2 14m
  }
  $t tag raise special:list_item:1
  $t tag raise special:list_item:2
  $t tag raise special:hr:normal
  
  # other configuration
  catch {.t configure -width $JDOC_PREFS(textwidth)}
  catch {.t configure -height $JDOC_PREFS(textheight)}
  catch {.t configure -background $JDOC_PREFS(textbg)}
  catch {.t configure -foreground $JDOC_PREFS(textfg)}
  catch {.t configure -borderwidth $JDOC_PREFS(textbw)}
  catch {.t configure -selectbackground $JDOC_PREFS(textsb)}
  catch {.t configure -selectforeground $JDOC_PREFS(textsf)}
  catch {.t configure -selectborderwidth $JDOC_PREFS(textsbw)}
}

##############################################################################
# jdoc:first_doc_file - read first doc file from command line
##############################################################################

proc jdoc:first_doc_file {} {
  global argc argv
  
  if {$argc > 1} then {
    wm withdraw .
    ::aq::alert -text \
      [= "jdoc called with too many arguments.\nUsage: jdoc <topic>"]
    exit 1
  }
  
  if {$argc != 1} then {
    update
    jdoc:cmd:load .t
  } else {
    set topic [lindex $argv 0]
    jdoc:load_topic $topic
  }
}

