Export View to HTML

DXL Script to export the current view to an HTML file.
This is a very quick way to share information with someone who does not have doors access without the need to publish a document.

Also see Email Selected Objects.

//  Export View to HTML File 

/*
	Tony Goodman	Initial Version
*/

pragma runLim, 0

DB      dbMain       = null
DBE     exportBtn    = null
DBE     dbeFileName  = null

Module m = null

int VIEW      = 0
int OBJECT    = 1
int SELECTION = 2

Buffer tb2 = create

/*************************
	escapeQuotes
*************************/
void escapeQuotes(Buffer buf, Buffer &bTemp) {
	int i = 0

	setempty(bTemp)

	for (i = 0; i < length(buf); i++)
	{
		if (buf[i] == '"')
		{
			bTemp += '"' ""
		}

		bTemp += buf[i] ""
	}
}

/*************************
	escapeBrackets
*************************/
void escapeBrackets(string s, Buffer &bTemp) {
	int i = 0

	setempty(bTemp)

	for (i = 0; i < length(s); i++)
	{
		if (s[i] == '<')
		{
			bTemp += "&lt;"
		}
		else if (s[i] == '>')
		{
			bTemp += "&gt;"
		}
		else
		{
			bTemp += s[i] ""
		}
	}
}

/*************************
	convertRichText
*************************/
void convertRichText(Buffer& b, string s, int& len, int max)
{
	RichTextParagraph rp = null
    RichText rt = null
    bool     limitText = false
	int ind = 0
	int i = 0

    if (!null len && !null max)
        limitText = true
    else
        limitText = false

    if (limitText && len >= max)
        return

    setempty b

	for rp in s do
	{
		ind = rp.indentLevel

		for (i = 0; i < ind; i += 360)
		{
				b += "<ul>"
		}

		if (rp.isBullet)
		{
			b += "<li>"
		}

    for rt in rp do {
        if (limitText && len >= max)
            break
        setempty tb2
        tb2 += rt.text
        if (limitText)
           // truncateBuffer(tb2, len, max)
        safeHTMLBuffer(tb2, true, true)

        if (rt.bold)
            b += "<b>"
        if (rt.underline)
            b += "<u>"
        if (rt.italic)
            b += "<i>"
        if (rt.strikethru)
            b += "<s>"
        if (rt.superscript)
            b += "<sup>"
        if (rt.subscript)
            b += "<sub>"
        if (rt.charset == charsetSymbol)
            b += "<font face=\"Symbol\">"

        b += tb2

        if (rt.charset == charsetSymbol)
            b += "</font>"
        if (rt.subscript)
            b += "</sub>"
        if (rt.superscript)
            b += "</sup>"
        if (rt.strikethru)
            b += "</s>"
        if (rt.italic)
            b += "</i>"
        if (rt.underline)
            b += "</u>"
        if (rt.bold)
            b += "</b>"

		if (rt.newline)
            b += "<br>"
    }

	if (rp.isBullet)
	{
		b += "</li>"
	}

	for (i = 0; i < ind; i += 360)
	{
			b += "</ul>"
	}
}

}

/*************************
	emitHeader
*************************/
void emitHeader(Buffer htmlBuffer)
{
	htmlBuffer += "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
	htmlBuffer += "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
	htmlBuffer += "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
	htmlBuffer += "<head>\n"

	htmlBuffer += "<style>\n"

	htmlBuffer += ".myCell {\n"
	htmlBuffer += "margin: 0px;\n"
	htmlBuffer += "padding: 5px;\n"
	htmlBuffer += "vertical-align: top;\n"
	htmlBuffer += "font: 11px Arial, sans-serif;\n"
	htmlBuffer += "border: 1px solid #CCCCCC;\n"
	htmlBuffer += "}\n"

	htmlBuffer += ".myTable {\n"
	htmlBuffer += "margin: 0px;\n"
	htmlBuffer += "padding: 0px;\n"
	htmlBuffer += "vertical-align: top;\n"
	htmlBuffer += "}\n"

	htmlBuffer += ".myAnchor {\n"
	htmlBuffer += "text-decoration: none;\n"
	htmlBuffer += "font: 11px Arial, sans-serif;\n"
	htmlBuffer += "color: #000000;\n"
	htmlBuffer += "}\n"

	htmlBuffer += ".myAnchorBold {\n"
	htmlBuffer += "text-decoration: none;\n"
	htmlBuffer += "font: bold 11px Arial, sans-serif, bold;\n"
	htmlBuffer += "color: #000000;\n"
	htmlBuffer += "}\n"

	htmlBuffer += "</style>\n"
	htmlBuffer += "</head>\n"
	htmlBuffer += "<body>\n"
}

/*************************
	emitFooter
*************************/
void emitFooter(Buffer htmlBuffer)
{
	htmlBuffer += "</body>\n"
	htmlBuffer += "</html>\n"
	htmlBuffer += "\n"
}

/*************************
	emitTableObject
*************************/
void emitTableObject(Object oTable, int scope, Buffer htmlBuffer)
{
	Buffer tempBuf = create
	string s = ""
	Object oRow = null
	Object oCell = null
	bool 	tableCellsAreVisible = false
	bool tableCellsAreSelected = false

	if (isVisible(oTable))
	{
		if (scope == SELECTION)
		{
			if (!isSelected(oTable))
			{
				return
			}
		}

		htmlBuffer += "<tr><td class=\"myCell\"/><td class=\"myCell\"/><a class=\"myText\">>> Table</a></td></tr>\n"
		return
	}

	for oRow in oTable do
	{
		for oCell in oRow do
		{
			if (isVisible(oCell))
			{
				tableCellsAreVisible = true

				if (isSelected(oCell))
				{
					tableCellsAreSelected = true
				}
			}
		}
	}

	if (!tableCellsAreVisible) return

	if (scope == SELECTION && !tableCellsAreSelected)
	{
		return
	}

	htmlBuffer += "<tr>\n"

	htmlBuffer += "<td class=\"myCell\"/>\n"

	htmlBuffer += "<td class=\"myCell\">\n"

	htmlBuffer += "<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n"

	for oRow in oTable do
	{
		htmlBuffer += "<tr>\n"

		for oCell in oRow do
		{
			if (!isVisible(oCell))
			{
				continue
			}

			htmlBuffer += "<td class=\"myCell\">\n"
			htmlBuffer += "<a class=\"myText\"> "
			convertRichText(tempBuf, richText(oCell."Object Text"), null, null)
			htmlBuffer += tempBuf
			htmlBuffer += "</a>\n"
			htmlBuffer += "</td>\n"
		}

		htmlBuffer += "</tr>\n"
	}

	htmlBuffer += "</table>"

	htmlBuffer += "</td>\n"

	htmlBuffer += "</tr>\n"

	delete(tempBuf)
	tempBuf = null
}

/*************************
	emitView
*************************/
string emitView(Module m, int scope, Buffer htmlBuffer)
{
	string res          = ""
	Object o            = null
	Object currObj      = null
	Column c            = null
	real   w            = 0.0
	real   myWidth = 0.0
	Buffer tempBuf = create
	int i = 0

	emitHeader(htmlBuffer)

	currObj = current Object

	htmlBuffer += "<table class=\"myTable\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n"

	// header row
	htmlBuffer += "<tr>\n"
	htmlBuffer += "<td class=\"myCell\">\n"

	htmlBuffer += "<b>Exported from DOORS:</b> " stringOf(dateOf intOf today) "<br>"

	htmlBuffer += "<b>Module:</b> " fullName(m) " [version " version(m) "]<br>"

	if (scope == VIEW)
	{
		htmlBuffer += "<b>View:</b> " currentView(m) "<br>"
	}
	else if (scope == SELECTION)
	{
		htmlBuffer += "<b>View:</b> " currentView(m) " <b>(Selected Objects Only)</b><br>"
	}
	else if (scope == OBJECT)
	{
		htmlBuffer += "<b>View:</b> " currentView(m) " <b>(Single Object Only)</b><br>"
	}

	htmlBuffer += "</td>\n"
	htmlBuffer += "</tr>\n"
	htmlBuffer += "</table>\n"

	htmlBuffer += "<table class=\"myTable\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n"

	for c in m do
	{
		w += realOf(width(c))
	}

	// table header
	htmlBuffer += "<tr>\n"
	for c in m do
	{
		myWidth = (realOf(width(c)) / w) * 100.0
		htmlBuffer += "<th width=\"" (int intOf(myWidth)) "%\" class=\"myCell\"><b>" title(c) "</b></th>\n"
	}
	htmlBuffer += "</tr>\n"

	// standard DOORS module - just export all objects in order.
	for o in document m do
	{
		//print identifier(o) "\n"

		if (table(o))
		{
			emitTableObject(o, scope, htmlBuffer)
		}
		else
		{
			if (!isVisible(o))
			{
				continue
			}

			if (scope == SELECTION)
			{
				if (!(isSelected(o) || o == currObj))
				{
					continue
				}
			}

			// new row in the table for each object in the current entity
			htmlBuffer += "<tr>\n"

			for c in m do
			{
				if (main(c))
				{
					if (o."Object Heading" "" != "")
					{
						htmlBuffer += "<td class=\"myCell\"><b>" number(o) " "
						convertRichText(tempBuf, o."Object Heading" "", i, null)
						htmlBuffer += tempBuf
						htmlBuffer += "</b></td>\n"
					}
					else if (o."Object Text" "" != "")
					{
						htmlBuffer += "<td class=\"myCell\">"
						convertRichText(tempBuf, richText(o."Object Text"), i, null)
						htmlBuffer += tempBuf
						htmlBuffer += "</td>\n"
					}
					else
					{
						htmlBuffer += "<td class=\"myCell\"><br></td>\n"
					}
				}
				else
				{
					if (text(c, o) == "")
					{
						htmlBuffer += "<td class=\"myCell\"><br></td>\n"
					}
					else if (length(title(c)) >= 4 && (title(c))[0:3] == "HTML")
					{
						htmlBuffer += "<td class=\"myCell\">" text(c, o) "</td>\n"
					}
					else
					{
						htmlBuffer += "<td class=\"myCell\">"
						convertRichText(tempBuf, richText(c, o), i, null)
						htmlBuffer += tempBuf
						htmlBuffer += " </td>\n"
					}
				}
			}

			// end of row for the current object
			htmlBuffer += "</tr>\n"
		}
	}

	htmlBuffer += "</table>\n"

	emitFooter(htmlBuffer)

	return(res)
}

/*************************
	doExport
*************************/
void doExport(DB db)
{
	string res = ""
	string outputFile = get(dbeFileName)

	Buffer htmlBuffer = create

	res = emitView(m, VIEW, htmlBuffer)

	Stream out = write(outputFile)

	out << htmlBuffer

	close(out)

	infoBox("Export complete. See file:\n" outputFile)

	release(dbMain)
}

/*************************
	doClose
*************************/
void doClose(DB db)
{
	release(dbMain)
}

/*************************
	buildDialog
*************************/
void buildDialog()
{
	dbMain = create(m, "Export View to HTML", styleCentered|styleFixed)

	label(dbMain, "This utility exports the current view to an HTML file.\n\n")

	dbeFileName = fileName(dbMain, "Export to:", "U:\\" name(m) ".html", "*.html", "HTML Files", false)

	//dbeResults = text(dbMain, "Results:", "", 70, false)

	exportBtn = apply(dbMain, "Export", doExport)

	realize(dbMain)

	block(dbMain)
	destroy(dbMain)
	dbMain = null
}

/*************************
	htmlViewExport
*************************/
void htmlViewExport()
{
	m = current Module

	buildDialog()
}

htmlViewExport()