diff --git a/src/main/java/com/ly/doc/builder/DocBuilderTemplate.java b/src/main/java/com/ly/doc/builder/DocBuilderTemplate.java index 88cd7b7fe..a75a287e4 100644 --- a/src/main/java/com/ly/doc/builder/DocBuilderTemplate.java +++ b/src/main/java/com/ly/doc/builder/DocBuilderTemplate.java @@ -84,16 +84,28 @@ public ApiAllData getApiData(ApiConfig config, JavaProjectBuilder javaProjectBui public void buildApiDoc(List apiDocList, ApiConfig config, String template, String fileExtension) { FileUtil.mkdirs(config.getOutPath()); for (ApiDoc doc : apiDocList) { - Template mapper = BeetlTemplateUtil.getByName(template); - mapper.binding(TemplateVariable.DESC.getVariable(), doc.getDesc()); - mapper.binding(TemplateVariable.NAME.getVariable(), doc.getName()); - mapper.binding(TemplateVariable.LIST.getVariable(), doc.getList()); - mapper.binding(TemplateVariable.REQUEST_EXAMPLE.getVariable(), config.isRequestExample()); - mapper.binding(TemplateVariable.RESPONSE_EXAMPLE.getVariable(), config.isResponseExample()); + Template mapper = buildApiDocTemplate(doc, config, template); FileUtil.nioWriteFile(mapper.render(), config.getOutPath() + DocGlobalConstants.FILE_SEPARATOR + doc.getName() + fileExtension); } } + /** + * build api doc template + * + * @param doc api doc + * @param config api config + * @param template template + */ + public Template buildApiDocTemplate(ApiDoc doc, ApiConfig config, String template) { + Template mapper = BeetlTemplateUtil.getByName(template); + mapper.binding(TemplateVariable.DESC.getVariable(), doc.getDesc()); + mapper.binding(TemplateVariable.NAME.getVariable(), doc.getName()); + mapper.binding(TemplateVariable.LIST.getVariable(), doc.getList()); + mapper.binding(TemplateVariable.REQUEST_EXAMPLE.getVariable(), config.isRequestExample()); + mapper.binding(TemplateVariable.RESPONSE_EXAMPLE.getVariable(), config.isResponseExample()); + return mapper; + } + /** * Merge all api doc into one document * @@ -104,26 +116,24 @@ public void buildApiDoc(List apiDocList, ApiConfig config, String templa * @param outPutFileName output file */ public void buildAllInOne(List apiDocList, ApiConfig config, JavaProjectBuilder javaProjectBuilder, - String template, String outPutFileName) { + String template, String outPutFileName) { buildDoc(apiDocList, config, javaProjectBuilder, template, outPutFileName, null, null); } + /** - * Merge all api doc into one document + * get render doc template * * @param apiDocList list data of Api doc * @param config api config * @param javaProjectBuilder JavaProjectBuilder * @param template template - * @param outPutFileName output file * @param apiDoc apiDoc * @param index index html */ - public void buildDoc(List apiDocList, ApiConfig config, JavaProjectBuilder javaProjectBuilder, - String template, String outPutFileName, ApiDoc apiDoc, String index) { - String outPath = config.getOutPath(); + public Template buildAllRenderDocTemplate(List apiDocList, ApiConfig config, JavaProjectBuilder javaProjectBuilder, + String template, ApiDoc apiDoc, String index) { String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND); - FileUtil.mkdirs(outPath); List errorCodeList = DocUtil.errorCodeDictToList(config, javaProjectBuilder); Template tpl = BeetlTemplateUtil.getByName(template); String style = config.getStyle(); @@ -151,7 +161,7 @@ public void buildDoc(List apiDocList, ApiConfig config, JavaProjectBuild boolean onlyHasDefaultGroup = apiDocList.stream().allMatch(doc -> Objects.equals(TornaConstants.DEFAULT_GROUP_CODE, doc.getGroup())); int codeIndex = 0; if (onlyHasDefaultGroup) { - if (apiDocList.size() > 0) { + if (!apiDocList.isEmpty()) { codeIndex = apiDocList.get(0).getChildrenApiDocs().size(); } } else { @@ -172,6 +182,25 @@ public void buildDoc(List apiDocList, ApiConfig config, JavaProjectBuild tpl.binding(TemplateVariable.ORDER.getVariable(), apiDoc.order); tpl.binding(TemplateVariable.LIST.getVariable(), apiDoc.getList());//类名 } + return tpl; + } + + /** + * Merge all api doc into one document + * + * @param apiDocList list data of Api doc + * @param config api config + * @param javaProjectBuilder JavaProjectBuilder + * @param template template + * @param outPutFileName output file + * @param apiDoc apiDoc + * @param index index html + */ + public void buildDoc(List apiDocList, ApiConfig config, JavaProjectBuilder javaProjectBuilder, + String template, String outPutFileName, ApiDoc apiDoc, String index) { + String outPath = config.getOutPath(); + FileUtil.mkdirs(outPath); + Template tpl = buildAllRenderDocTemplate(apiDocList, config, javaProjectBuilder, template, apiDoc, index); FileUtil.nioWriteFile(tpl.render(), outPath + DocGlobalConstants.FILE_SEPARATOR + outPutFileName); } @@ -266,13 +295,25 @@ public void buildSearchJs(ApiConfig config, JavaProjectBuilder javaProjectBuilde * @param javaProjectBuilder javaProjectBuilder */ public void buildErrorCodeDoc(ApiConfig config, String template, String outPutFileName, JavaProjectBuilder javaProjectBuilder) { + Template tpl = buildErrorCodeDocTemplate(config, template, javaProjectBuilder); + FileUtil.nioWriteFile(tpl.render(), config.getOutPath() + DocGlobalConstants.FILE_SEPARATOR + outPutFileName); + } + + /** + * build errorCode adoc template + * + * @param config api config + * @param template template + * @param javaProjectBuilder javaProjectBuilder + */ + public Template buildErrorCodeDocTemplate(ApiConfig config, String template, JavaProjectBuilder javaProjectBuilder) { List errorCodeList = DocUtil.errorCodeDictToList(config, javaProjectBuilder); String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND); Template tpl = BeetlTemplateUtil.getByName(template); setCssCDN(config, tpl); tpl.binding(TemplateVariable.CREATE_TIME.getVariable(), strTime); tpl.binding(TemplateVariable.LIST.getVariable(), errorCodeList); - FileUtil.nioWriteFile(tpl.render(), config.getOutPath() + DocGlobalConstants.FILE_SEPARATOR + outPutFileName); + return tpl; } /** @@ -286,7 +327,7 @@ public void buildErrorCodeDoc(ApiConfig config, String template, String outPutFi * @param indexAlias index alias */ public void buildErrorCodeDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder, - List apiDocList, String template, String outPutFileName, String indexAlias) { + List apiDocList, String template, String outPutFileName, String indexAlias) { List errorCodeList = DocUtil.errorCodeDictToList(config, javaProjectBuilder); String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND); Template errorTemplate = BeetlTemplateUtil.getByName(template); @@ -325,7 +366,7 @@ public void buildErrorCodeDoc(ApiConfig config, JavaProjectBuilder javaProjectBu * @param indexAlias index alias */ public void buildDirectoryDataDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder, List apiDocList, - String template, String outPutFileName, String indexAlias) { + String template, String outPutFileName, String indexAlias) { List directoryList = DocUtil.buildDictionary(config, javaProjectBuilder); Template mapper = BeetlTemplateUtil.getByName(template); String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND); @@ -367,6 +408,18 @@ public void buildDirectoryDataDoc(ApiConfig config, JavaProjectBuilder javaProje * @param outPutFileName output file */ public void buildDirectoryDataDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder, String template, String outPutFileName) { + Template mapper = buildDirectoryDataDocTemplate(config, javaProjectBuilder, template); + FileUtil.nioWriteFile(mapper.render(), config.getOutPath() + DocGlobalConstants.FILE_SEPARATOR + outPutFileName); + } + + /** + * build common_data doc Template + * + * @param config api config + * @param javaProjectBuilder JavaProjectBuilder + * @param template template + */ + public Template buildDirectoryDataDocTemplate(ApiConfig config, JavaProjectBuilder javaProjectBuilder, String template) { List directoryList = DocUtil.buildDictionary(config, javaProjectBuilder); Template mapper = BeetlTemplateUtil.getByName(template); setDirectoryLanguageVariable(config, mapper); @@ -375,7 +428,7 @@ public void buildDirectoryDataDoc(ApiConfig config, JavaProjectBuilder javaProje String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND); mapper.binding(TemplateVariable.CREATE_TIME.getVariable(), strTime); mapper.binding(TemplateVariable.DICT_LIST.getVariable(), directoryList); - FileUtil.nioWriteFile(mapper.render(), config.getOutPath() + DocGlobalConstants.FILE_SEPARATOR + outPutFileName); + return mapper; } private List listOfApiData(ApiConfig config, JavaProjectBuilder javaProjectBuilder) { diff --git a/src/main/java/com/ly/doc/builder/WordDocBuilder.java b/src/main/java/com/ly/doc/builder/WordDocBuilder.java new file mode 100644 index 000000000..a4563af0e --- /dev/null +++ b/src/main/java/com/ly/doc/builder/WordDocBuilder.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2018-2023 smart-doc + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.ly.doc.builder; + +import com.ly.doc.constants.DocGlobalConstants; +import com.ly.doc.factory.BuildTemplateFactory; +import com.ly.doc.helper.JavaProjectBuilderHelper; +import com.ly.doc.model.ApiConfig; +import com.ly.doc.model.ApiDoc; +import com.ly.doc.template.IDocBuildTemplate; +import com.power.common.util.DateTimeUtil; +import com.power.common.util.FileUtil; +import com.thoughtworks.qdox.JavaProjectBuilder; +import org.beetl.core.Template; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.Objects; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + +/** + * @author chenqi + * @version 1.0 + */ +public class WordDocBuilder { + private static final String TEMPLATE_DOCX = "template/word/template.docx"; + + + private static final String BUILD_DOCX = "index.docx"; + private static final String BUILD_ERROR_DOCX = "error.docx"; + private static final String BUILD_DICT_DOCX = "dict.docx"; + + /** + * build controller api + * + * @param config config + */ + public static void buildApiDoc(ApiConfig config) throws Exception { + JavaProjectBuilder javaProjectBuilder = JavaProjectBuilderHelper.create(); + buildApiDoc(config, javaProjectBuilder); + } + + /** + * build controller api + * + * @param config config + */ + public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) throws Exception { + DocBuilderTemplate builderTemplate = new DocBuilderTemplate(); + builderTemplate.checkAndInit(config, Boolean.TRUE); + config.setParamsDataToTree(false); + ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder); + IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework()); + Objects.requireNonNull(docBuildTemplate, "doc build template is null"); + List apiDocList = docBuildTemplate.getApiData(configBuilder); + + if (config.isAllInOne()) { + String version = config.isCoverOld() ? "" : "-V" + DateTimeUtil.long2Str(System.currentTimeMillis(), DocGlobalConstants.DATE_FORMAT_YYYY_MM_DD_HH_MM); + String docName = builderTemplate.allInOneDocName(config, "AllInOne" + version + ".docx", ".docx"); + apiDocList = docBuildTemplate.handleApiGroup(apiDocList, config); + String outPath = config.getOutPath(); + FileUtil.mkdirs(outPath); + Template tpl = builderTemplate.buildAllRenderDocTemplate(apiDocList, config, javaProjectBuilder, DocGlobalConstants.ALL_IN_ONE_WORD_XML_TPL, null, null); + copyAndReplaceDocx(tpl.render(), outPath + DocGlobalConstants.FILE_SEPARATOR + docName); + } else { + FileUtil.mkdir(config.getOutPath()); + for (ApiDoc doc : apiDocList) { + Template template = builderTemplate.buildApiDocTemplate(doc, config, DocGlobalConstants.WORD_XML_TPL); + copyAndReplaceDocx(template.render(), config.getOutPath() + DocGlobalConstants.FILE_SEPARATOR + doc.getName() + BUILD_DOCX); + } + Template errorCodeDocTemplate = builderTemplate.buildErrorCodeDocTemplate(config, DocGlobalConstants.WORD_ERROR_XML_TPL, javaProjectBuilder); + copyAndReplaceDocx(errorCodeDocTemplate.render(), config.getOutPath() + DocGlobalConstants.FILE_SEPARATOR + BUILD_ERROR_DOCX); + + Template directoryDataDocTemplate = builderTemplate.buildDirectoryDataDocTemplate(config, javaProjectBuilder, DocGlobalConstants.WORD_DICT_XML_TPL); + copyAndReplaceDocx(directoryDataDocTemplate.render(), config.getOutPath() + DocGlobalConstants.FILE_SEPARATOR + BUILD_DICT_DOCX); + } + } + + + /** + * replace docx content + * + * @param content doc content + * @param docxOutputPath docx output path + * @return + * @since 1.0.0 + */ + public static void copyAndReplaceDocx(String content, String docxOutputPath) throws Exception { + InputStream resourceAsStream = WordDocBuilder.class.getClassLoader().getResourceAsStream(TEMPLATE_DOCX); + Objects.requireNonNull(resourceAsStream, "word template docx is not found"); + + ZipInputStream zipInputStream = new ZipInputStream(resourceAsStream); + ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(Paths.get(docxOutputPath))); + // Traverse the files in the compressed package + ZipEntry entry; + while ((entry = zipInputStream.getNextEntry()) != null) { + String entryName = entry.getName(); + + if (entryName.equals("word/document.xml")) { + zipOutputStream.putNextEntry(new ZipEntry(entryName)); + byte[] bytes = content.getBytes(StandardCharsets.UTF_8); + zipOutputStream.write(bytes, 0, bytes.length); + } else { + // copy + zipOutputStream.putNextEntry(entry); + byte[] buffer = new byte[1024]; + int len; + while ((len = zipInputStream.read(buffer)) > 0) { + zipOutputStream.write(buffer, 0, len); + } + } + + zipOutputStream.closeEntry(); + zipInputStream.closeEntry(); + } + + zipInputStream.close(); + zipOutputStream.close(); + } + +} diff --git a/src/main/java/com/ly/doc/constants/DocGlobalConstants.java b/src/main/java/com/ly/doc/constants/DocGlobalConstants.java index b3554c869..646e9e08f 100644 --- a/src/main/java/com/ly/doc/constants/DocGlobalConstants.java +++ b/src/main/java/com/ly/doc/constants/DocGlobalConstants.java @@ -52,6 +52,11 @@ public interface DocGlobalConstants { String ALL_IN_ONE_HTML_TPL = "AllInOne.html"; + String ALL_IN_ONE_WORD_XML_TPL = "word/AllInOneWordTemplate.xml"; + String WORD_XML_TPL = "word/index.xml"; + String WORD_ERROR_XML_TPL = "word/error.xml"; + String WORD_DICT_XML_TPL = "word/dict.xml"; + String HTML_API_DOC_TPL = "HtmlApiDoc.html"; String ERROR_CODE_LIST_MD_TPL = "ErrorCodeList.md"; @@ -259,4 +264,6 @@ public interface DocGlobalConstants { String JAR_TEMP = "./smart-temp/"; String DEFAULT_PRIMITIVE = "defaultPrimitive"; + + String DATE_FORMAT_YYYY_MM_DD_HH_MM = "yyyyMMddHHmm"; } diff --git a/src/main/java/com/ly/doc/function/WordXmlEscape.java b/src/main/java/com/ly/doc/function/WordXmlEscape.java new file mode 100644 index 000000000..d29356fd7 --- /dev/null +++ b/src/main/java/com/ly/doc/function/WordXmlEscape.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2018-2023 smart-doc + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.ly.doc.function; + +import com.ly.doc.utils.DocUtil; +import org.beetl.core.Context; +import org.beetl.core.Function; + +/** + * beetl template function + * @author yu 2021/6/26. + */ +public class WordXmlEscape implements Function { + + @Override + public String call(Object[] paras, Context ctx) { + String str = String.valueOf(paras[0]) + .replaceAll(" ", " ") + .replaceAll("  ", " ") + .replaceAll(" ", "") + .replaceAll("
", "") + .replaceAll("&", "&") + .replaceAll("<", "<"); + return DocUtil.getEscapeAndCleanComment(str); + } +} diff --git a/src/main/resources/smart-doc-beetl.properties b/src/main/resources/smart-doc-beetl.properties index 3fdef04bf..271e9f660 100644 --- a/src/main/resources/smart-doc-beetl.properties +++ b/src/main/resources/smart-doc-beetl.properties @@ -1,6 +1,7 @@ DELIMITER_STATEMENT_START=<% DELIMITER_STATEMENT_END=%> FN.htmlEscape=com.ly.doc.function.HtmlEscape +FN.wordXmlEscape=com.ly.doc.function.WordXmlEscape FN.removeLineBreaks=com.ly.doc.function.RemoveLineBreaks FN.lineBreaksToBr=com.ly.doc.function.LineBreaksToBr FNP.strUtil=org.beetl.ext.fn.StringUtil \ No newline at end of file diff --git a/src/main/resources/template/word/AllInOneWordTemplate.xml b/src/main/resources/template/word/AllInOneWordTemplate.xml new file mode 100644 index 000000000..4346b1181 --- /dev/null +++ b/src/main/resources/template/word/AllInOneWordTemplate.xml @@ -0,0 +1,3019 @@ + + + + <%if(isNotEmpty(projectName)){%> + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(projectName)} + + + <%}%> + + <%if(isNotEmpty(revisionLogList)){%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Version + + + + + + + + + + + + + + + + + + + + + + + + + + Update Time + + + + + + + + + + + + + + + + + + + + + + + + + + Status + + + + + + + + + + + + + + + + + + + + + + + + + + Author + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + <% + for(revisionLog in revisionLogList){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${revisionLog.version} + + + + + + + + + + + + + + + + + + + + + + + + + + ${revisionLog.revisionTime} + + + + + + + + + + + + + + + + + + + + + + + + + + ${revisionLog.status} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(revisionLog.author)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(revisionLog.remarks)} + + + + + <%}%> + + <%}%> + + + <% + for(apiGroup in apiDocList){ + %> + + <% + if(!apiDocListOnlyHasDefaultGroup) {%> + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(apiGroup.group)} + + + <%}%> + + <% + for(api in apiGroup.childrenApiDocs){ + %> + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(api.desc)} + + + + <% + for(doc in api.list){ + %> + + <%if(doc.deprecated){%> + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(doc.desc)} + + + <%}else{%> + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(doc.desc)} + + + <%}%> + + + + + + + + + + + + + + + + + + + + + + URL: + + + + + + + + + + + + + + HYPERLINK " ${doc.url}" + + + + + + + + + + + + + + + ${doc.url} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Type: + + + + + + + ${doc.type} + + + + <%if(isNotEmpty(doc.author)){%> + + + + + + + + + + + + + + + + + + + + Author: + + + + + + + ${wordXmlEscape(doc.author)} + + + <%}%> + + + + + + + + + + + + + + + + + + + + + Content-Type: + + + + + + + ${doc.contentType} + + + + + + + + + + + + + + + + + + + + + + + Description: + + + + + + + ${wordXmlEscape(doc.detail)} + + + + + <%if(isNotEmpty(doc.headers)){%> + + + + + + + + + + + + + + + + + + Request-headers: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Header + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + + + + + + + + + + + + + + + + + + + + + + Required + + + + + + + + + + + + + + + + + + + + + + + + + + Since + + + + + <% + for(header in doc.requestHeaders){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${header.name} + + + + + + + + + + + + + + + + + + + + + + + + + + ${header.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(header.desc)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${header.required} + + + + + + + + + + + + + + + + + + + + + + + + + + ${header.since} + + + + + <%}%> + + <%}%> + + + + <%if(isNotEmpty(doc.pathParams)){%> + + + + + + + + + + + + + + + + + + Path-parameters: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Parameter + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + + + + + + + + + + + + + + + + + + + + + + Required + + + + + + + + + + + + + + + + + + + + + + + + + + Since + + + + + <% + for(param in doc.pathParams){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.field)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.desc)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.required} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.version} + + + + + <%}%> + + <%}%> + + + + <%if(isNotEmpty(doc.queryParams)){%> + + + + + + + + + + + + + + + + + + Query-parameters: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Parameter + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + + + + + + + + + + + + + + + + + + + + + + Required + + + + + + + + + + + + + + + + + + + + + + + + + + Since + + + + + <% + for(param in doc.queryParams){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.field)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.desc)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.required} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.version} + + + + + <%}%> + + <%}%> + + + + <%if(isNotEmpty(doc.requestParams)){%> + + + + + + + + + + + + + + + + + + Query-parameters: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Parameter + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + + + + + + + + + + + + + + + + + + + + + + Required + + + + + + + + + + + + + + + + + + + + + + + + + + Since + + + + + <% + for(param in doc.requestParams){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.field)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.desc)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.required} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.version} + + + + + <%}%> + + <%}%> + + + <%if(isNotEmpty(doc.requestUsage)&&isRequestExample){%> + + + + + + + + + + + + + + + + + + Request-example: + + + <% + for(l in strutil.split(doc.requestUsage, "\n")){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(l)} + + + <%}%> + + <%}%> + + + <%if(isNotEmpty(doc.responseParams)){%> + + + + + + + + + + + + + + + + + + Response-fields: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Field + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + + + + + + + + + + + + + + + + + + + + + + Since + + + + + <% + for(param in doc.responseParams){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.field)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.desc)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.version} + + + + + <%}%> + + <%}%> + + + <%if(isNotEmpty(doc.responseUsage)&&isResponseExample){ + %> + + + + + + + + + + + + + + + + + + Response-example: + + + <% + for(l in strutil.split(doc.responseUsage, "\n")){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(l)} + + + <%}%> + <%}%> + + + + + + <%}%> + + + <%}%> + + + <%}%> + + + + <%if(isNotEmpty(errorCodeList)){ + %> + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(errorListTitle)} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Error code + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + <% + for(error in errorCodeList){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(error.value)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(error.desc)} + + + + + <%}%> + + <%}%> + + <%if(isNotEmpty(dictList)){ + %> + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(dictListTitle)} + + + <% + for(dict in dictList){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + <% + for(dataDict in dict.dataDictList){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(dataDict.value)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${dataDict.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(dataDict.desc)} + + + + + <%}%> + + <%}%> + <%}%> + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/template/word/dict.xml b/src/main/resources/template/word/dict.xml new file mode 100644 index 000000000..9f9145fef --- /dev/null +++ b/src/main/resources/template/word/dict.xml @@ -0,0 +1,285 @@ + + + + + <%if(isNotEmpty(dictList)){ + %> + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(dictListTitle)} + + + <% + for(dict in dictList){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + <% + for(dataDict in dict.dataDictList){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(dataDict.value)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${dataDict.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(dataDict.desc)} + + + + + <%}%> + + <%}%> + <%}%> + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/template/word/error.xml b/src/main/resources/template/word/error.xml new file mode 100644 index 000000000..fb74703bc --- /dev/null +++ b/src/main/resources/template/word/error.xml @@ -0,0 +1,229 @@ + + + + + <%if(isNotEmpty(list)){ + %> + + + + + + + + + + + + + + + + + + + + Error Code List + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Error code + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + <% + for(error in list){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(error.value)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(error.desc)} + + + + + <%}%> + + <%}%> + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/template/word/index.xml b/src/main/resources/template/word/index.xml new file mode 100644 index 000000000..c0e30047e --- /dev/null +++ b/src/main/resources/template/word/index.xml @@ -0,0 +1,2150 @@ + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(desc)} + + + + <% + for(doc in list){ + %> + + <%if(doc.deprecated){%> + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(doc.desc)} + + + <%}else{%> + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(doc.desc)} + + + <%}%> + + + + + + + + + + + + + + + + + + + + + + URL: + + + + + + + + + + + + + + HYPERLINK " ${doc.url}" + + + + + + + + + + + + + + + ${doc.url} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Type: + + + + + + + ${doc.type} + + + + <%if(isNotEmpty(doc.author)){%> + + + + + + + + + + + + + + + + + + + + Author: + + + + + + + ${wordXmlEscape(doc.author)} + + + <%}%> + + + + + + + + + + + + + + + + + + + + + Content-Type: + + + + + + + ${doc.contentType} + + + + + + + + + + + + + + + + + + + + + + + Description: + + + + + + + ${wordXmlEscape(doc.detail)} + + + + + <%if(isNotEmpty(doc.headers)){%> + + + + + + + + + + + + + + + + + + Request-headers: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Header + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + + + + + + + + + + + + + + + + + + + + + + Required + + + + + + + + + + + + + + + + + + + + + + + + + + Since + + + + + <% + for(header in doc.requestHeaders){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${header.name} + + + + + + + + + + + + + + + + + + + + + + + + + + ${header.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(header.desc)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${header.required} + + + + + + + + + + + + + + + + + + + + + + + + + + ${header.since} + + + + + <%}%> + + <%}%> + + + + <%if(isNotEmpty(doc.pathParams)){%> + + + + + + + + + + + + + + + + + + Path-parameters: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Parameter + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + + + + + + + + + + + + + + + + + + + + + + Required + + + + + + + + + + + + + + + + + + + + + + + + + + Since + + + + + <% + for(param in doc.pathParams){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.field)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.desc)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.required} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.version} + + + + + <%}%> + + <%}%> + + + + <%if(isNotEmpty(doc.queryParams)){%> + + + + + + + + + + + + + + + + + + Query-parameters: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Parameter + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + + + + + + + + + + + + + + + + + + + + + + Required + + + + + + + + + + + + + + + + + + + + + + + + + + Since + + + + + <% + for(param in doc.queryParams){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.field)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.desc)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.required} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.version} + + + + + <%}%> + + <%}%> + + + + <%if(isNotEmpty(doc.requestParams)){%> + + + + + + + + + + + + + + + + + + Query-parameters: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Parameter + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + + + + + + + + + + + + + + + + + + + + + + Required + + + + + + + + + + + + + + + + + + + + + + + + + + Since + + + + + <% + for(param in doc.requestParams){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.field)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.desc)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.required} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.version} + + + + + <%}%> + + <%}%> + + + <%if(isNotEmpty(doc.requestUsage)&&isRequestExample){%> + + + + + + + + + + + + + + + + + + Request-example: + + + <% + for(l in strutil.split(doc.requestUsage, "\n")){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(l)} + + + <%}%> + + <%}%> + + + <%if(isNotEmpty(doc.responseParams)){%> + + + + + + + + + + + + + + + + + + Response-fields: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Field + + + + + + + + + + + + + + + + + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + + + + + + + + + Description + + + + + + + + + + + + + + + + + + + + + + + + + + Since + + + + + <% + for(param in doc.responseParams){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.field)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.type} + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(param.desc)} + + + + + + + + + + + + + + + + + + + + + + + + + + ${param.version} + + + + + <%}%> + + <%}%> + + + <%if(isNotEmpty(doc.responseUsage)&&isResponseExample){ + %> + + + + + + + + + + + + + + + + + + Response-example: + + + <% + for(l in strutil.split(doc.responseUsage, "\n")){ + %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${wordXmlEscape(l)} + + + <%}%> + <%}%> + + <%}%> + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/template/word/template.docx b/src/main/resources/template/word/template.docx new file mode 100644 index 000000000..0e7586692 Binary files /dev/null and b/src/main/resources/template/word/template.docx differ