/* * $Id: ImportTextCommandPrompt.cpp,v 1.18 2006/03/05 05:00:09 ozawa Exp $ * * Copyright 2005- ONGS Inc. All rights reserved. * * author: Masanori OZAWA (ozawa@ongs.co.jp) * version: $Revision: 1.18 $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY ONGS INC ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ONGS INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the ONGS Inc. * */ #include "xdtp.h" #include "modules/imports/ImportTextCommandPrompt.h" #include "Utilities.h" #include "URLTool.h" #include "XMLTool.h" #define TYPE_COMMAND_PROMPT "text/command-prompt" using namespace XDTP; ImportTextCommandPrompt::ImportTextCommandPrompt() { } ImportTextCommandPrompt::~ImportTextCommandPrompt() { } /** * XSL変換後のXML文章を保存する直前に呼び出されます。 * * @param aDocument XML文章 */ void ImportTextCommandPrompt::treatPostDocument(xmlDocPtr aDocument) { GLSDImportModuleAdapter::treatPostDocument(aDocument); int count; XMLTool tool; xmlNodePtr root = xmlDocGetRootElement(aDocument); xmlNodeSetPtr nodes; xmlXPathObjectPtr obj = tool.getNodeList(root, "//import[@type=\"text/command-prompt\"]"); m_needTIP = false; if (obj) { nodes = obj->nodesetval; for (count = 0; count < nodes->nodeNr; count++) { if (!transform(aDocument, nodes->nodeTab[count])) { THROW("ImportTextCommandPrompt: transform failed."); } } xmlXPathFreeObject(obj); } } /** * XML文章を保存した直後に呼び出されます。 * * @param aFile 保存したファイル名 */ void ImportTextCommandPrompt::treatPostFile(const Glib::ustring& aFile) { GLSDImportModuleAdapter::treatPostFile(aFile); if (m_needTIP) { if (!transformImportPoint(aFile, TYPE_COMMAND_PROMPT)) { THROW("ImportTextCommandPrompt: Unable to transform the import point."); } } } bool ImportTextCommandPrompt::transform(xmlDocPtr aDocument, xmlNodePtr aNode) { Glib::ustring ref; Glib::ustring caption; Glib::ustring encoding; if (!getImportAttributes(aNode, ref, caption, encoding)) { return false; } if ("html" == m_OutputType) { return command_promptTo_nHTML(aDocument, aNode, ref, caption, encoding); } else if ("xhtml" == m_OutputType) { return command_promptTo_nHTML(aDocument, aNode, ref, caption, encoding); } else if ("text" == m_OutputType) { return preserveImport(aDocument, aNode, ref, caption, encoding); } // otherwise, do not operation. return true; } bool ImportTextCommandPrompt::command_promptTo_nHTML (xmlDocPtr aDocument, xmlNodePtr aNode, const Glib::ustring& aRef, const Glib::ustring& aCaption, const Glib::ustring& anEncoding) { // スタイルシートを取得 xmlNodePtr comment = getStyleSheet(aDocument, "text/css"); if (comment) { // スタイルシートにイメージのスタイルの指定があるか確認 Glib::ustring content = (comment->content ? (const char*)comment->content : ""); Glib::ustring::size_type pos = content.find("div.command-prompt"); if (Glib::ustring::npos == pos) { // スタイルシートにイメージのスタイルを追加 content += LINE_SEP; content += " div.command-prompt {" LINE_SEP; content += " margin-top: 1.0mm;" LINE_SEP; content += " margin-bottom: 1.5em;" LINE_SEP; content += " text-align: center;" LINE_SEP; content += " }" LINE_SEP; content += " blockquote.command-prompt {" LINE_SEP; content += " margin-top: 2.0mm;" LINE_SEP; content += " margin-bottom: 1.5mm;" LINE_SEP; content += " padding-top: 0.5em;" LINE_SEP; content += " padding-left: 1.0em;" LINE_SEP; content += " padding-right: 1.0em;" LINE_SEP; content += " padding-bottom: 0.5em;" LINE_SEP; content += " border: solid thin silver;" LINE_SEP; content += " overflow: clip;" LINE_SEP; content += " }" LINE_SEP; xmlNodeSetContent(comment, (const xmlChar*)content.c_str()); } } m_needTIP = true; // テキストノードを構築する xmlNodePtr div = xmlNewNode(NULL, (const xmlChar*)"div"); if (!div) THROW("Out of memory!"); xmlSetProp(div, (const xmlChar*)"style", (const xmlChar*)"text-indent: 0em; line-height: 1.2em;"); xmlAddChild(div, createNewImportPointNode(TYPE_COMMAND_PROMPT, aRef, aCaption, anEncoding)); xmlNodePtr block = xmlNewNode(NULL, (const xmlChar*)"blockquote"); if (!block) { xmlFreeNode(div); THROW("Out of memory!"); } xmlSetProp(block, (const xmlChar*)"cite", (const xmlChar*)aRef.c_str()); xmlSetProp(block, (const xmlChar*)"class", (const xmlChar*)"command-prompt"); xmlAddChild(block, div); xmlNodePtr title = xmlNewNode(NULL, (const xmlChar*)"div"); if (!title) { xmlFreeNode(block); THROW("Out of memory!"); } xmlSetProp(title, (const xmlChar*)"class", (const xmlChar*)"command-prompt"); xmlAddChild(title, xmlNewText((const xmlChar*)aCaption.c_str())); xmlFreeNode(xmlReplaceNode(aNode, title)); xmlAddPrevSibling(title, block); return true; } /** * ファイルからインポート処理対象の部分を抽出し、置換処理を * 行う際に呼び出されます。 * * @param aRef インポート先のファイル * @param aCaption キャプション * @param anEncoding インポート先のファイルのエンコード * @param aNewData 置換すべき文字列を応答します。 * @return 処理結果を応答します。 */ TIP_STATUS ImportTextCommandPrompt::transformImportPointCallback (const Glib::ustring& aRef, const Glib::ustring& aCaption, const Glib::ustring& anEncoding, Glib::ustring& aNewData) { // ファイルを読み込み、テキストノードを構築する bool bFailed = false; std::string tmpfile; try { Glib::RefPtr ioc = getIOChannel(aRef, tmpfile); setEncoding(ioc, anEncoding); Glib::ustring line; Glib::ustring space = " "; // space 8 Glib::ustring::size_type pos; while (ioc->read_line(line) == Glib::IO_STATUS_NORMAL) { line = Utilities::strTrimCRLF(line); if ("html" == m_OutputType) { // タブをスペース展開する for (pos = line.find('\t'); Glib::ustring::npos != pos; pos = line.find('\t')) { line = line.substr(0, pos) + space.substr(pos % 8) + line.substr(pos + 1); } // エスケープ処理 line = escapeString(line); } aNewData += line + "
" LINE_SEP; } ioc->close(); } catch (Exception exception) { exception.print(stderr); bFailed = true; } catch (Glib::Error error) { std::string msg = Glib::locale_from_utf8(error.what()); fprintf(stderr, "%s: %s (%s)" LINE_SEP, APP_NAME, msg.c_str(), aRef.c_str()); bFailed = true; } catch (std::exception exception) { fprintf(stderr, "%s: %s (%s)" LINE_SEP, APP_NAME, exception.what(), aRef.c_str()); bFailed = true; } catch (...) { fprintf(stderr, "%s: ImportTextCommandPrompt: unknown error occured. (%s)" LINE_SEP, APP_NAME, aRef.c_str()); bFailed = true; } if (0 < tmpfile.length()) { remove(tmpfile.c_str()); } return (bFailed ? TIP_FAILED : TIP_SUCCESS); }