# jdoc-mode.tcl - mode for rich-text hypertext documents
######################################################################

::jldb::set_defaults {
  {menu:jdoc {jdoc} 1}
  {menu:sections {Sections} 0}
  {mode:jdoc:show_tags {Show Tags at Insert...} 5 {} {[5]}}
  {mode:jdoc:mkx_anchor {Anchor Name...} 7 {} {[6]}}
  {mode:jdoc:mkx_anchor_link {Local Cross Reference...} 0 {} {[7]}}
  {mode:jdoc:mkx_link {Cross Reference...} 0 {} {[8]}}
  {mode:jdoc:mkx_manpage {Man Page Reference...} 0 {} {[9]}}
  {mode:jdoc:hr {Horizontal Rule} 11}
  
  {{(new file)} {(new file)}}
  {{Link Name} {Link Name}}
  {{Link to:} {Link to:}}
  {{Anchor Name} {Anchor Name}}
  {{Anchor name:} {Anchor name:}}
  {{Manual page:} {Manual page:}}
  {{Top} {Top}}
  {{Bottom} {Bottom}}
  
  {{Help on jdoc Mode} {Help on `jdoc' Mode}}
}

proc mode:jdoc:init { t } {
  global JEDIT_MODEPREFS
  
  j:read_prefs -array JEDIT_MODEPREFS -prefix jdoc \
    -directory ~/.tk/jeditmodes -file jdoc-defaults {
    {textfont default}
    {textwidth 80}
    {textheight 24}
    {textwrap word}
    {sabbrev 0}
    {dabbrev 0}
    {autobreak 0}
    {autoindent 0}
    {savestate 0}
    {buttonbar 1}
    {buttons {
      jedit:cmd:save
      jedit:cmd:done
      jedit:cmd:print_postscript
    }}
    {docs {
      -
      {{Help on jdoc Mode} {jeditmodes/jdoc-mode.jdoc}}
    }}
    {menu,editor 1}
    {menu,file 1}
    {menu,edit 1}
    {menu,prefs 0}
    {menu,abbrev 1}
    {menu,filter 1}
    {menu,format 1}
    {menu,font 1}
    {menu,display 1}
    {menu,mode1 1}
    {menu,mode2 1}
    {menu,user 1}
  }
  
  $t tag bind jdoc:xref:link <Control-ButtonRelease-1> \
    {jdoc:x_link %W %x %y}
  $t tag bind jdoc:xref:manpage <Control-ButtonRelease-1> \
    {jdoc:x_manpage %W %x %y}
  $t tag configure jdoc:xref:link -underline 1
  $t tag configure jdoc:xref:manpage -underline 1
  
  $t tag configure special:hr:normal -font nil2 -background black
  
  # need to wait until normal font tags have been created for following:
  after idle [list $t tag raise special:hr:normal]
  
  # not marked in browsers, but marked here so you get visual feedback
  # when you create them:
  $t tag configure jdoc:anchor:anchorname -background grey75 -bgstipple gray25
  $t tag lower jdoc:anchor:anchorname
  
  # (and list tags are set after loading a file or when invoking list commands)
}

######################################################################
# save entire contents of text widget, including tags and marks
#   (overrides normal write procedure)
######################################################################

proc mode:jdoc:write { filename t } {
  ::aq::tag::archive_text_widget $t $filename
}

######################################################################
# read in archive of text widget, including tags and marks
#   (overrides normal read procedure)
######################################################################

proc mode:jdoc:read { filename t } {
  jedit:font:roman $t				;# start tagging as roman
  if { ! [file exists $filename] } then {
    $t delete 1.0 end
    $t mark set insert 1.0
    jedit:set_label $t "$filename [::jldb::long_text {(new file)}]"
  } else {					;# file exists
    ::aq::tag::restore_text_widget $t $filename
    global JEDIT_MODEPREFS
    if { ! $JEDIT_MODEPREFS(jdoc,savestate) } {
      $t tag remove sel 1.0 end
      $t mark set insert 1.0
      $t yview 1.0
    }
  }
  jedit:format:configure_all_list_tags $t
}

######################################################################
# show tags at insert point (useful for seeing anchor names, etc.)
######################################################################
### THIS SHOULD BE ADDED TO BASE JEDIT FUNCTIONALITY

::aq::command_register mode:jdoc:show_tags {}
proc mode:jdoc:show_tags { t } {
  set tags [$t tag names insert]
  ::aq::more \
    -title [::jldb::long_text "Current Tags"] \
    -width 40 -height 10 \
    -text [join [lsort $tags] "\n"]
}

######################################################################
# horizontal rule
######################################################################

::aq::command_register mode:jdoc:hr {}
proc mode:jdoc:hr { t } {
  set start [$t index insert]
  j:text:insert_string $t "\n"		;# coloured newline for rule
  $t tag add special:hr:normal $start	;# list item at level 1
}

######################################################################

proc mode:jdoc:mkx_anchor { t } {
  set from [$t index sel.first]
  set to [$t index sel.last]
  set anchor [string trim [$t get $from $to]]
  regsub -all -- {[ +-]} $anchor {_} anchor
  set anchor [::aq::prompt -title "Anchor Name" -text "Anchor name:" \
    -default $anchor]
  
  if {"x$anchor" == "x"} {
    return 1
  }
  
  foreach tag [list \
    jdoc:anchor:anchorname \
    jdoc:anchorname:$anchor \
  ] {
    ::aq::tag::tag_text $t $tag $from $to
  }
  return 0
}

proc mode:jdoc:mkx_link { t } {
  set from [$t index sel.first]
  set to [$t index sel.last]
  set link "[string trim [$t get $from $to]].jdoc"
  regsub -all -- {[ +-]} $link {_} link
  set link [::aq::prompt -file 1 -title "Link Name" -text "Link to:" \
    -default $link -file 1]
  
  if {"x$link" == "x"} {
    return 1
  }
  
  foreach tag [list \
    jdoc:xref:link \
    jdoc:link:$link \
  ] {
    ::aq::tag::tag_text $t $tag $from $to
  }
  return 0
}

proc mode:jdoc:mkx_anchor_link { t } {
  set from [$t index sel.first]
  set to [$t index sel.last]
  set link "#[string trim [$t get $from $to]]"
  regsub -all -- {[ +-]} $link {_} link
  set link [::aq::prompt -title "Link Name" -text "Link to:" \
    -default $link -file 1]
  
  if {"x$link" == "x"} {
    return 1
  }
  
  foreach tag [list \
    jdoc:xref:link \
    jdoc:link:$link \
  ] {
    ::aq::tag::tag_text $t $tag $from $to
  }
  return 0
}

proc mode:jdoc:mkx_manpage { t } {
  set from [$t index sel.first]
  set to [$t index sel.last]
  set manpage [string trim [$t get $from $to]]
  set manpage [::aq::prompt -title "Link Name" -text "Manual page:" \
    -default $manpage]
  
  if {"x$manpage" == "x"} {
    return 1
  }
  
  foreach tag [list \
    jdoc:xref:manpage \
    jdoc:manpage:$manpage \
    richtext:font:typewriter \
  ] {
    ::aq::tag::tag_text $t $tag $from $to
  }
  return 0
}

######################################################################
# mode:jdoc:mksectionsmenu menu t - find all level 1 headings in text
######################################################################

proc mode:jdoc:mksectionsmenu { menu 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]
  }
  
  $menu delete 0 last
  
  $menu add command -label [::jldb::long_text "Top"] -command \
    "$t mark set insert 1.0; $t yview -pickplace insert"
  $menu add separator
  foreach pair $sections {
    set section [lindex $pair 0]
    set location [lindex $pair 1]
    $menu add command -label $section \
      -command "$t mark set insert $location; $t yview insert"
  }
  $menu add separator
  $menu add command -label [::jldb::long_text "Bottom"] -command \
    "$t mark set insert end; $t yview -pickplace insert"
}

######################################################################

proc mode:jdoc:mkmenu1 { menu t } {
  j:menu:menubutton $menu $menu.m menu:jdoc
  
  $menu.m add command \
    -label [::jldb::long_text jedit:font:heading1 {Make Section Title}] \
    -underline [::jldb::underline jedit:font:heading1] \
    -accelerator {[1]} \
    -command "jedit:font:heading1 $t"
  $menu.m add command \
    -label [::jldb::long_text jedit:font:heading2 {Make Subsection Heading}] \
    -underline [::jldb::underline jedit:font:heading2] \
    -accelerator {[2]} \
    -command "jedit:font:heading2 $t"
  $menu.m add command \
    -label [::jldb::long_text jedit:font:heading3 {Make Subsubsection Heading}] \
    -underline [::jldb::underline jedit:font:heading3] \
    -accelerator {[3]} \
    -command "jedit:font:heading3 $t"
  $menu.m add command \
    -label [::jldb::long_text jedit:font:heading0 {Make Overall Topic Title}] \
    -underline [::jldb::underline jedit:font:heading0] \
    -command "jedit:font:heading0 $t"
  j:menu:commands $menu.m $t {
    -
    mode:jdoc:show_tags
    mode:jdoc:mkx_anchor
    mode:jdoc:mkx_anchor_link
    mode:jdoc:mkx_link
    mode:jdoc:mkx_manpage
    -
    mode:jdoc:hr
  }
  
  bind $t <Meta-Key-1> "jedit:font:heading1 $t"
  bind $t <Meta-Key-2> "jedit:font:heading2 $t"
  bind $t <Meta-Key-3> "jedit:font:heading3 $t"
  bind $t <Meta-Key-5> "mode:jdoc:show_tags $t"
  bind $t <Meta-Key-6> "mode:jdoc:mkx_anchor $t"
  bind $t <Meta-Key-7> "mode:jdoc:mkx_anchor_link $t"
  bind $t <Meta-Key-8> "mode:jdoc:mkx_link $t"
  bind $t <Meta-Key-9> "mode:jdoc:mkx_manpage $t"
}

proc mode:jdoc:mkmenu2 { menu t } {
  j:menu:menubutton $menu $menu.m menu:sections
  
  $menu.m configure -postcommand "mode:jdoc:mksectionsmenu $menu.m $t"
}




