#!/bin/bash
# doc/rst - reStructuredText file support
# The rst library provides support for reStructuredText file generation.
# The following document was referenced often during implementation:
#
#   http://http://docutils.sourceforge.net/rst.html

set -e


######
# Native dependencies

doc_rst_client_packages=( python-docutils )


######
# Configuration

doc_rst_config_init() {
	lib_setting_vars --null rst_title

	lib_setting_arrays rst_header_chars
	rst_header_chars=( "*" "^" "=" "+" "~" "-" "." )

	lib_setting_vars rst_col_indent rst_col_limit rst_col_inc
	rst_col_indent=0
	rst_col_limit=72
	rst_col_inc=2

	lib_setting_vars rst_flow_hanging
	rst_flow_hanging=false

	lib_setting_vars rst_enum_start rst_enum_index
	rst_enum_start=1
	rst_enum_index=0

	lib_setting_arrays rst_html_stylesheets
}

doc_rst_config_check() {
	:
}

doc_rst_lib_init() {
	local level
	for level in $(seq 1 7); do
		eval "rst_h$level() { rst_header_n $level \"\$*\"; }"
	done
}


######
# Text reflowing

# rst_indent - Increments indent and calls another generation function
rst_indent() {
	local rst_col_indent=$((rst_col_indent + $rst_col_inc))
	func_trace "indent=$rst_col_indent limit=$rst_col_limit"
	run "$@"
}

rst_indent_str() { printf "%${rst_col_indent}s" ''; }

# rst_reflow - Rewraps text with current indent level and column limit
rst_reflow() {
	local -a text

	local indent=$(rst_indent_str)
	local line="$indent"
	while [ ${#*} -gt 0 ]; do
		if $rst_flow_hanging && [ ${#text[*]} -gt 0 ]; then
			local rst_flow_hanging=false
			rst_indent rst_reflow "$@"
			return
		fi
		local part=$1
		shift
		part=${part##[\t\n ]}
		part=${part%%[\t\n ]}

		if [ -z "$part" ]; then
			text+=( "$line" )
			[ -z "${line## }" ] || echo
			line="$indent"
			continue
		fi

		line="$line${line:+ }$part"

		local next=''
		local i=$rst_col_limit
		while ! [ $rst_col_limit -lt ${#line} ]; do
			if [ "${line[$i]}" != ' ' ]; then
				i=$((i - 1))
				continue
			fi
			# save last word for later
			next="${line:$((i + 1))}${next:+ }$next"
			part=${line:0:$i}
			break
		done

		# do not emit until we spill
		[ "$next" ] || continue

		text+=( "$line" )
		line=$next
	done
	[ "${line## }" ] && text+=( "$line" )

	echo "${text[*]}"
}

rst_reflow() { echo "$*"; }

rst_trim() {
	local var="$*"
	var="${var#"${var%%[![:space:]]*}"}"
	var="${var%"${var##*[![:space:]]}"}"
	echo -n "$var"
}

######
# Document

rst_title() {
	has_args 2 "$@"
	rst_header '$' "$1"
	rst_header '%' "$2"
}


######
# Headers

rst_header_n() {
	has_args 2 "$@"
	local level=$1
	local str=$2
	local char=${rst_header_chars[$((level - 1))]}
	rst_header "$char" "$str"
}

rst_header() {
	has_args 2 "$@"
	local char=$1

	local str=$2
	echo "$str"

	local bar=$(printf "%${#str}s" '')
	echo "${bar// /$char}"

	echo
}


######
# Blocks

rst_p() { rst_reflow "$@"; echo; }

rst_block_literal() {
	rst_reflow "$1::"
	shift
	rst_indent rst_reflow "$@"
}

rst_block_quote() {
	rst_indent rst_reflow "$@"
}


######
# Inline

rst_italic() { echo ":emphasis:\`$*\`"; }
rst_bold() { echo ":strong:\`$*\`"; }
rst_subscript() { echo ":subscript:\`$*\`"; }
rst_superscript() { echo ":superscript:\`$*\`"; }
rst_title_ref() { echo ":title:\`$*\`"; }

rst_literal() { echo ":literal:\`$*\`"; }
rst_code() { echo ":code:\`$*\`"; }
rst_math() { echo ":math:\`$*\`"; }
rst_pep() { echo ":PEP:\`$*\`"; }
rst_rfc() { echo ":RFC:\`$*\`"; }


######
# Lists

rst_bullet_item() {
	local rst_flow_hanging=true
	rst_reflow " - $1"
}
rst_bullet_items() {
	local rst_indent=$((rst_indent + 2))
	for_each rst_bullet_item "$@"
}

rst_enum_item() {
	local rst_flow_hanging=true
	rst_reflow "$rst_enum_index. $@"
	$((rst_enum_index++))
}
rst_enum_items() {
	local rst_enum_index=$rst_enum_start
	for_each rst_enum_item "$@"
}

rst_def_item() {
	echo "$1"
	rst_reflow "$2"
}
rst_def_items() { for_each_pair rst_def_item "$@"; }

rst_option_item() {
	echo "$1"
	rst_indent rst_reflow "$2"
}
rst_option_items() { for_each_pair rst_option_item "$@"; }


######
# Rendering

rst_to_html() {
	local -a opts
	if [ "${rst_html_css[*]}" ]; then
		local IFS=','
		opts+=( "--stylesheet=${rst_html_css[*]}" )
	fi
	run rst2html "${opts[@]}" "$@"
}
rst_to_latex() { run rst2latex "$@"; }
rst_to_pdf() {
	rst_to_latex "$1" >"$tmp";
	latex_to_pdf "$tmp" "$2"
}

View the Script Reference Index


Generated on Tue Apr 25 21:20:50 PDT 2017 by mcsh i7 v0.18.0.