diff --git a/src/main/java/com/power/doc/builder/ApiDocBuilder.java b/src/main/java/com/power/doc/builder/ApiDocBuilder.java index 20f42c5..70aa54d 100644 --- a/src/main/java/com/power/doc/builder/ApiDocBuilder.java +++ b/src/main/java/com/power/doc/builder/ApiDocBuilder.java @@ -4,6 +4,9 @@ import com.power.common.util.CollectionUtil; import com.power.common.util.DateTimeUtil; import com.power.common.util.FileUtil; import com.power.common.util.StringUtil; +import com.power.doc.constants.GlobalConstants; +import com.power.doc.constants.Language; +import com.power.doc.constants.TemplateVariable; import com.power.doc.model.ApiConfig; import com.power.doc.model.ApiDoc; import com.power.doc.model.ApiErrorCode; @@ -12,10 +15,11 @@ import org.beetl.core.Template; import java.util.List; -import static com.power.doc.constants.GlobalConstants.FILE_SEPARATOR; +import static com.power.doc.constants.GlobalConstants.*; /** * use to create markdown doc + * * @author yu 2019/09/20 */ public class ApiDocBuilder { @@ -42,6 +46,12 @@ public class ApiDocBuilder { if (StringUtil.isEmpty(config.getOutPath())) { throw new RuntimeException("doc output path can't be null or empty"); } + if (null != config.getLanguage()) { + System.setProperty(GlobalConstants.DOC_LANGUAGE, config.getLanguage().getCode()); + } else { + //default is chinese + System.setProperty(GlobalConstants.DOC_LANGUAGE, Language.CHINESE.getCode()); + } SourceBuilder sourceBuilder = new SourceBuilder(config); List apiDocList = sourceBuilder.getControllerApiData(); if (config.isAllInOne()) { @@ -62,10 +72,10 @@ public class ApiDocBuilder { FileUtil.mkdirs(outPath); SourceBuilder sourceBuilder = new SourceBuilder(true); ApiDoc doc = sourceBuilder.getSingleControllerApiData(controllerName); - Template mapper = BeetlTemplateUtil.getByName("ApiDoc.btl"); - mapper.binding("desc", doc.getDesc()); - mapper.binding("name", doc.getName()); - mapper.binding("list", doc.getList());//类名 + Template mapper = BeetlTemplateUtil.getByName(API_DOC_TPL); + mapper.binding(TemplateVariable.DESC.getVariable(), doc.getDesc()); + mapper.binding(TemplateVariable.NAME.getVariable(), doc.getName()); + mapper.binding(TemplateVariable.LIST.getVariable(), doc.getList());//类名 FileUtil.writeFileNotAppend(mapper.render(), outPath + FILE_SEPARATOR + doc.getName() + "Api.md"); } @@ -78,10 +88,10 @@ public class ApiDocBuilder { private static void buildApiDoc(List apiDocList, String outPath) { FileUtil.mkdirs(outPath); for (ApiDoc doc : apiDocList) { - Template mapper = BeetlTemplateUtil.getByName("ApiDoc.btl"); - mapper.binding("desc", doc.getDesc()); - mapper.binding("name", doc.getName()); - mapper.binding("list", doc.getList());//类名 + Template mapper = BeetlTemplateUtil.getByName(API_DOC_TPL); + mapper.binding(TemplateVariable.DESC.getVariable(), doc.getDesc()); + mapper.binding(TemplateVariable.NAME.getVariable(), doc.getName()); + mapper.binding(TemplateVariable.LIST.getVariable(), doc.getList());//类名 FileUtil.nioWriteFile(mapper.render(), outPath + FILE_SEPARATOR + doc.getName() + "Api.md"); } } @@ -95,9 +105,9 @@ public class ApiDocBuilder { String outPath = config.getOutPath(); FileUtil.mkdirs(outPath); Template tpl = BeetlTemplateUtil.getByName("AllInOne.btl"); - tpl.binding("apiDocList", apiDocList); - tpl.binding("errorCodeList", config.getErrorCodes()); - tpl.binding("revisionLogList", config.getRevisionLogs()); + tpl.binding(TemplateVariable.API_DOC_LIST.getVariable(), apiDocList); + tpl.binding(TemplateVariable.ERROR_CODE_LIST.getVariable(), config.getErrorCodes()); + tpl.binding(TemplateVariable.VERSION_LIST.getVariable(), config.getRevisionLogs()); String version = DateTimeUtil.long2Str(System.currentTimeMillis(), "yyyyMMddHHmm"); FileUtil.nioWriteFile(tpl.render(), outPath + FILE_SEPARATOR + "AllInOne-V" + version + ".md"); } @@ -110,9 +120,9 @@ public class ApiDocBuilder { */ private static void buildErrorCodeDoc(List errorCodeList, String outPath) { if (CollectionUtil.isNotEmpty(errorCodeList)) { - Template mapper = BeetlTemplateUtil.getByName("ErrorCodeList.btl"); - mapper.binding("list", errorCodeList);//类名 - FileUtil.nioWriteFile(mapper.render(), outPath + FILE_SEPARATOR + "ErrorCodeList.md"); + Template mapper = BeetlTemplateUtil.getByName(ERROR_CODE_LIST_TPL); + mapper.binding(TemplateVariable.LIST.getVariable(), errorCodeList);//类名 + FileUtil.nioWriteFile(mapper.render(), outPath + FILE_SEPARATOR + ERROR_CODE_LIST_MD); } } } diff --git a/src/main/java/com/power/doc/builder/HtmlApiDocBuilder.java b/src/main/java/com/power/doc/builder/HtmlApiDocBuilder.java index fa19947..96b2714 100644 --- a/src/main/java/com/power/doc/builder/HtmlApiDocBuilder.java +++ b/src/main/java/com/power/doc/builder/HtmlApiDocBuilder.java @@ -1,19 +1,26 @@ package com.power.doc.builder; +import com.power.common.util.CollectionUtil; +import com.power.common.util.DateTimeUtil; import com.power.common.util.FileUtil; import com.power.common.util.StringUtil; +import com.power.doc.constants.GlobalConstants; +import com.power.doc.constants.Language; +import com.power.doc.constants.TemplateVariable; import com.power.doc.model.ApiConfig; import com.power.doc.model.ApiDoc; +import com.power.doc.model.ApiErrorCode; import com.power.doc.utils.BeetlTemplateUtil; +import com.power.doc.utils.MarkDownUtil; import org.beetl.core.Template; -import java.io.File; import java.util.List; -import static com.power.doc.constants.GlobalConstants.FILE_SEPARATOR; +import static com.power.doc.constants.GlobalConstants.*; /** * @author yu 2019/9/20. + * @since 1.7+ */ public class HtmlApiDocBuilder { @@ -27,27 +34,44 @@ public class HtmlApiDocBuilder { if (StringUtil.isEmpty(config.getOutPath())) { throw new RuntimeException("doc output path can't be null or empty"); } + if (null != config.getLanguage()) { + System.setProperty(GlobalConstants.DOC_LANGUAGE, config.getLanguage().getCode()); + } else { + //default is chinese + System.setProperty(GlobalConstants.DOC_LANGUAGE, Language.CHINESE.getCode()); + } SourceBuilder sourceBuilder = new SourceBuilder(config); List apiDocList = sourceBuilder.getControllerApiData(); - buildIndex(apiDocList, config.getOutPath()); + buildIndex(apiDocList, config); copyCss(config.getOutPath()); + buildApiDoc(apiDocList, config.getOutPath()); + buildErrorCodeDoc(config.getErrorCodes(), config.getOutPath()); } private static void copyCss(String outPath) { - Template indexCssTemplate = BeetlTemplateUtil.getByName("index.css"); - Template mdCssTemplate = BeetlTemplateUtil.getByName("markdown.css"); - FileUtil.nioWriteFile(indexCssTemplate.render(), outPath + FILE_SEPARATOR + "index.css"); - FileUtil.nioWriteFile(mdCssTemplate.render(), outPath + FILE_SEPARATOR + "markdown.css"); + Template indexCssTemplate = BeetlTemplateUtil.getByName(INDEX_CSS_TPL); + Template mdCssTemplate = BeetlTemplateUtil.getByName(MARKDOWN_CSS_TPL); + FileUtil.nioWriteFile(indexCssTemplate.render(), outPath + FILE_SEPARATOR + INDEX_CSS_TPL); + FileUtil.nioWriteFile(mdCssTemplate.render(), outPath + FILE_SEPARATOR + MARKDOWN_CSS_TPL); } - private static void buildIndex(List apiDocList, String outPath) { - FileUtil.mkdirs(outPath); - Template indexTemplate = BeetlTemplateUtil.getByName("Index.btl"); + private static void buildIndex(List apiDocList, ApiConfig config) { + FileUtil.mkdirs(config.getOutPath()); + Template indexTemplate = BeetlTemplateUtil.getByName(INDEX_TPL); ApiDoc doc = apiDocList.get(0); - String homePage = doc.getName(); - indexTemplate.binding("home", homePage); - indexTemplate.binding("apiDocList", apiDocList); - FileUtil.nioWriteFile(indexTemplate.render(), outPath + FILE_SEPARATOR + "api.html"); + String homePage = doc.getAlias(); + indexTemplate.binding(TemplateVariable.HOME_PAGE.getVariable(), homePage); + indexTemplate.binding(TemplateVariable.API_DOC_LIST.getVariable(), apiDocList); + if (null != config.getLanguage()) { + if (Language.CHINESE.code.equals(config.getLanguage().getCode())) { + indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), "A. 错误码列表"); + } else { + indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), "A. Error Code List"); + } + } else { + indexTemplate.binding(TemplateVariable.ERROR_LIST_TITLE.getVariable(), "A. 错误码列表"); + } + FileUtil.nioWriteFile(indexTemplate.render(), config.getOutPath() + FILE_SEPARATOR + "api.html"); } @@ -59,12 +83,41 @@ public class HtmlApiDocBuilder { */ private static void buildApiDoc(List apiDocList, String outPath) { FileUtil.mkdirs(outPath); + Template htmlApiDoc; for (ApiDoc doc : apiDocList) { - Template mapper = BeetlTemplateUtil.getByName("ApiDoc.btl"); - mapper.binding("desc", doc.getDesc()); - mapper.binding("name", doc.getName()); - mapper.binding("list", doc.getList());//类名 - FileUtil.nioWriteFile(mapper.render(), outPath + FILE_SEPARATOR + doc.getName() + "Api.md"); + Template apiTemplate = BeetlTemplateUtil.getByName(API_DOC_TPL); + apiTemplate.binding(TemplateVariable.DESC.getVariable(), doc.getDesc()); + apiTemplate.binding(TemplateVariable.NAME.getVariable(), doc.getName()); + apiTemplate.binding(TemplateVariable.LIST.getVariable(), doc.getList());//类名 + + String html = MarkDownUtil.toHtml(apiTemplate.render()); + htmlApiDoc = BeetlTemplateUtil.getByName(HTML_API_DOC_TPL); + htmlApiDoc.binding(TemplateVariable.HTML.getVariable(), html); + htmlApiDoc.binding(TemplateVariable.TITLE.getVariable(),doc.getName()); + htmlApiDoc.binding(TemplateVariable.CREATE_TIME.getVariable(), DateTimeUtil.long2Str(System.currentTimeMillis() + , DateTimeUtil.DATE_FORMAT_SECOND)); + FileUtil.nioWriteFile(htmlApiDoc.render(), outPath + FILE_SEPARATOR + doc.getAlias() + ".html"); + } + } + + /** + * 构建错误码列表 + * + * @param errorCodeList 错误列表 + * @param outPath + */ + private static void buildErrorCodeDoc(List errorCodeList, String outPath) { + if (CollectionUtil.isNotEmpty(errorCodeList)) { + Template error = BeetlTemplateUtil.getByName(ERROR_CODE_LIST_TPL); + error.binding(TemplateVariable.LIST.getVariable(), errorCodeList);//类名 + String errorHtml = MarkDownUtil.toHtml(error.render()); + Template errorCodeDoc = BeetlTemplateUtil.getByName(HTML_API_DOC_TPL); + errorCodeDoc.binding(TemplateVariable.TITLE.getVariable(),"error code"); + errorCodeDoc.binding(TemplateVariable.HTML.getVariable(), errorHtml); + errorCodeDoc.binding(TemplateVariable.CREATE_TIME.getVariable(), DateTimeUtil.long2Str(System.currentTimeMillis() + , DateTimeUtil.DATE_FORMAT_SECOND)); + FileUtil.nioWriteFile(errorCodeDoc.render(), outPath + FILE_SEPARATOR + "error_code.html"); + } } } diff --git a/src/main/java/com/power/doc/builder/SourceBuilder.java b/src/main/java/com/power/doc/builder/SourceBuilder.java index bd12057..0a06713 100644 --- a/src/main/java/com/power/doc/builder/SourceBuilder.java +++ b/src/main/java/com/power/doc/builder/SourceBuilder.java @@ -1,9 +1,6 @@ package com.power.doc.builder; -import com.power.common.util.CollectionUtil; -import com.power.common.util.JsonFormatUtil; -import com.power.common.util.StringUtil; -import com.power.common.util.UrlUtil; +import com.power.common.util.*; import com.power.doc.constants.AnnotationConstants; import com.power.doc.constants.DocTags; import com.power.doc.constants.GlobalConstants; @@ -48,6 +45,7 @@ public class SourceBuilder { private String packageMatch; private List headers; private String appUrl; + private AesInfo aesInfo; /** * if isStrict value is true,it while check all method @@ -75,6 +73,7 @@ public class SourceBuilder { this.appUrl = config.getServerUrl(); } + aesInfo = config.getAesInfo(); this.packageMatch = config.getPackageFilters(); this.isStrict = config.isStrict(); loadJavaFiles(config.getSourcePaths()); @@ -154,22 +153,32 @@ public class SourceBuilder { public List getControllerApiData() { List apiDocList = new ArrayList<>(); + int order = 0; for (JavaClass cls : javaClasses) { if (checkController(cls)) { String controllerName = cls.getName(); if (StringUtil.isNotEmpty(packageMatch)) { if (DocUtil.isMatch(packageMatch, cls.getCanonicalName())) { + order++; List apiMethodDocs = buildControllerMethod(cls); ApiDoc apiDoc = new ApiDoc(); - apiDoc.setDesc(cls.getComment()); + apiDoc.setOrder(order); apiDoc.setName(controllerName); + apiDoc.setAlias(controllerName); + this.handControllerAlias(apiDoc); + apiDoc.setDesc(cls.getComment()); apiDoc.setList(apiMethodDocs); apiDocList.add(apiDoc); } } else { + order++; List apiMethodDocs = buildControllerMethod(cls); ApiDoc apiDoc = new ApiDoc(); + apiDoc.setOrder(order); + apiDoc.setAlias(MD6Util.md6(controllerName)); apiDoc.setName(controllerName); + apiDoc.setAlias(controllerName); + this.handControllerAlias(apiDoc); apiDoc.setDesc(cls.getComment()); apiDoc.setList(apiMethodDocs); apiDocList.add(apiDoc); @@ -215,11 +224,14 @@ public class SourceBuilder { } List methods = cls.getMethods(); List methodDocList = new ArrayList<>(methods.size()); + int methodOrder = 0; for (JavaMethod method : methods) { if (StringUtil.isEmpty(method.getComment()) && isStrict) { throw new RuntimeException("Unable to find comment for method " + method.getName() + " in " + cls.getCanonicalName()); } + methodOrder++; ApiMethodDoc apiMethodDoc = new ApiMethodDoc(); + apiMethodDoc.setOrder(methodOrder); apiMethodDoc.setDesc(method.getComment()); List annotations = method.getAnnotations(); String url = null; @@ -644,7 +656,7 @@ public class SourceBuilder { } } if (DocClassUtil.isPrimitive(typeName)) { - return DocUtil.jsonValueByType(typeName); + return DocUtil.jsonValueByType(typeName).replace("\"", ""); } StringBuilder data0 = new StringBuilder(); JavaClass cls = builder.getClassByName(typeName); @@ -1102,4 +1114,22 @@ public class SourceBuilder { } return fieldList; } + + /** + * handle controller name + * + * @param apiDoc ApiDoc + */ + private void handControllerAlias(ApiDoc apiDoc) { + if (null != aesInfo && StringUtil.isNotEmpty(aesInfo.getKey()) + && StringUtil.isNotEmpty(aesInfo.getVector())) { + String name = AESUtil.encodeByCBC(apiDoc.getName(), aesInfo.getKey(), aesInfo.getVector()); + int length = name.length(); + if (name.length() < 32) { + apiDoc.setAlias(name); + } else { + apiDoc.setAlias(name.substring(length - 32, length)); + } + } + } } diff --git a/src/main/java/com/power/doc/constants/GlobalConstants.java b/src/main/java/com/power/doc/constants/GlobalConstants.java index f1904e8..318d9d1 100644 --- a/src/main/java/com/power/doc/constants/GlobalConstants.java +++ b/src/main/java/com/power/doc/constants/GlobalConstants.java @@ -6,6 +6,22 @@ package com.power.doc.constants; public class GlobalConstants { public static final String FILE_SEPARATOR = System.getProperty("file.separator"); + + public static final String DOC_LANGUAGE = "smart-doc_language"; + + public static final String API_DOC_TPL = "ApiDoc.btl"; + + public static final String HTML_API_DOC_TPL = "HtmlApiDoc.btl"; + + public static final String ERROR_CODE_LIST_TPL = "ErrorCodeList.btl"; + + public static final String ERROR_CODE_LIST_MD = "ErrorCodeList.md"; + + public static final String INDEX_TPL = "Index.btl"; + + public static final String INDEX_CSS_TPL = "index.css"; + + public static final String MARKDOWN_CSS_TPL = "markdown.css"; /** * controller注解全名称 */ diff --git a/src/main/java/com/power/doc/constants/Language.java b/src/main/java/com/power/doc/constants/Language.java new file mode 100644 index 0000000..78dd2aa --- /dev/null +++ b/src/main/java/com/power/doc/constants/Language.java @@ -0,0 +1,20 @@ +package com.power.doc.constants; + +/** + * 语言支持 + * @author yu 2019/9/21. + */ +public enum Language { + ENGLISH("en-US"), + CHINESE("zh-CN"); + + public String code; + + Language(String code) { + this.code = code; + } + + public String getCode(){ + return this.code; + } +} diff --git a/src/main/java/com/power/doc/constants/TemplateVariable.java b/src/main/java/com/power/doc/constants/TemplateVariable.java new file mode 100644 index 0000000..7dbe115 --- /dev/null +++ b/src/main/java/com/power/doc/constants/TemplateVariable.java @@ -0,0 +1,30 @@ +package com.power.doc.constants; + +/** + * @author yu 2019/9/21. + */ +public enum TemplateVariable { + DESC("desc"), + NAME("name"), + LIST("list"), + API_DOC_LIST("apiDocList"), + ERROR_CODE_LIST("errorCodeList"), + VERSION_LIST("revisionLogList"), + HOME_PAGE("homePage"), + HTML("html"), + TITLE("title"), + ERROR_LIST_TITLE("errorListTitle"), + CREATE_TIME("createTime"); + + + + private String variable; + + TemplateVariable(String variable) { + this.variable = variable; + } + + public String getVariable(){ + return this.variable; + } +} diff --git a/src/main/java/com/power/doc/model/AesInfo.java b/src/main/java/com/power/doc/model/AesInfo.java new file mode 100644 index 0000000..a98af81 --- /dev/null +++ b/src/main/java/com/power/doc/model/AesInfo.java @@ -0,0 +1,41 @@ +package com.power.doc.model; + +/** + * aes加密信息 + * @since 1.7+ + * @author yu 2019/9/21. + */ +public class AesInfo { + + /** + * aes加密key + */ + private String key; + + /** + * 加密初始向量 + */ + private String vector; + + public static AesInfo create() { + return new AesInfo(); + } + + public String getKey() { + return key; + } + + public AesInfo setKey(String key) { + this.key = key; + return this; + } + + public String getVector() { + return vector; + } + + public AesInfo setVector(String vector) { + this.vector = vector; + return this; + } +} diff --git a/src/main/java/com/power/doc/model/ApiConfig.java b/src/main/java/com/power/doc/model/ApiConfig.java index 12da0db..2f1e720 100644 --- a/src/main/java/com/power/doc/model/ApiConfig.java +++ b/src/main/java/com/power/doc/model/ApiConfig.java @@ -1,6 +1,7 @@ package com.power.doc.model; import com.power.common.util.CollectionUtil; +import com.power.doc.constants.Language; import java.util.List; @@ -66,6 +67,19 @@ public class ApiConfig { */ private List revisionLogs; + /** + * @since 1.7+ + * aes加密信息 + */ + private AesInfo aesInfo; + + /** + * 语言 + * @since 1.7+ + */ + private Language language; + + public String getServerUrl() { return serverUrl; } @@ -147,4 +161,19 @@ public class ApiConfig { this.revisionLogs = CollectionUtil.asList(revisionLogs); } + public AesInfo getAesInfo() { + return aesInfo; + } + + public void setAesInfo(AesInfo aesInfo) { + this.aesInfo = aesInfo; + } + + public Language getLanguage() { + return language; + } + + public void setLanguage(Language language) { + this.language = language; + } } diff --git a/src/main/java/com/power/doc/model/ApiDoc.java b/src/main/java/com/power/doc/model/ApiDoc.java index 462cb87..a6c08ef 100644 --- a/src/main/java/com/power/doc/model/ApiDoc.java +++ b/src/main/java/com/power/doc/model/ApiDoc.java @@ -4,12 +4,23 @@ import java.util.List; public class ApiDoc { + /** + * @since 1.7+ + * 文档顺序 + */ + public int order; /** * 类名 */ private String name; + /** + * @since 1.7+ + * md5加密后的文件名(用于处理html) + */ + private String alias; + /** * 方法文档列表 */ @@ -44,5 +55,19 @@ public class ApiDoc { this.desc = desc; } + public int getOrder() { + return order; + } + public void setOrder(int order) { + this.order = order; + } + + public String getAlias() { + return alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } } diff --git a/src/main/java/com/power/doc/model/ApiMethodDoc.java b/src/main/java/com/power/doc/model/ApiMethodDoc.java index 50b0e60..6be06cf 100644 --- a/src/main/java/com/power/doc/model/ApiMethodDoc.java +++ b/src/main/java/com/power/doc/model/ApiMethodDoc.java @@ -7,6 +7,11 @@ import java.io.Serializable; */ public class ApiMethodDoc implements Serializable { + /** + * @since 1.7+ + */ + private int order; + private String desc; private String url; @@ -97,4 +102,12 @@ public class ApiMethodDoc implements Serializable { public void setHeaders(String headers) { this.headers = headers; } + + public int getOrder() { + return order; + } + + public void setOrder(int order) { + this.order = order; + } } diff --git a/src/main/java/com/power/doc/model/ApiReqHeader.java b/src/main/java/com/power/doc/model/ApiReqHeader.java index 24b7fd7..fe1c0aa 100644 --- a/src/main/java/com/power/doc/model/ApiReqHeader.java +++ b/src/main/java/com/power/doc/model/ApiReqHeader.java @@ -22,6 +22,18 @@ public class ApiReqHeader { */ private String desc; + /** + * @since 1.7.0 + * 请求有是否必须 + */ + private boolean required; + + /** + * @since 1.7.0 + * 起始版本 + */ + private String since = "-"; + public static ApiReqHeader header() { return new ApiReqHeader(); } @@ -52,4 +64,22 @@ public class ApiReqHeader { this.desc = desc; return this; } + + public boolean isRequired() { + return required; + } + + public ApiReqHeader setRequired(boolean required) { + this.required = required; + return this; + } + + public String getSince() { + return since; + } + + public ApiReqHeader setSince(String since) { + this.since = since; + return this; + } } diff --git a/src/main/java/com/power/doc/utils/DocUtil.java b/src/main/java/com/power/doc/utils/DocUtil.java index d531c87..ee86ced 100644 --- a/src/main/java/com/power/doc/utils/DocUtil.java +++ b/src/main/java/com/power/doc/utils/DocUtil.java @@ -5,6 +5,7 @@ import com.power.common.util.DateTimeUtil; import com.power.common.util.IDCardUtil; import com.power.common.util.RandomUtil; import com.power.common.util.StringUtil; +import com.power.doc.constants.GlobalConstants; import com.thoughtworks.qdox.model.JavaAnnotation; import java.util.*; @@ -17,7 +18,7 @@ import java.util.*; */ public class DocUtil { - private static Faker faker = new Faker(new Locale("zh-CN")); + private static Faker faker = new Faker(new Locale(System.getProperty(GlobalConstants.DOC_LANGUAGE))); private static Faker enFaker = new Faker(new Locale("en-US")); diff --git a/src/main/java/com/power/doc/utils/MarkDownUtil.java b/src/main/java/com/power/doc/utils/MarkDownUtil.java new file mode 100644 index 0000000..576227d --- /dev/null +++ b/src/main/java/com/power/doc/utils/MarkDownUtil.java @@ -0,0 +1,37 @@ +package com.power.doc.utils; + +import com.vladsch.flexmark.ext.tables.TablesExtension; +import com.vladsch.flexmark.html.HtmlRenderer; +import com.vladsch.flexmark.parser.Parser; +import com.vladsch.flexmark.parser.ParserEmulationProfile; +import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.data.MutableDataSet; + +import java.util.Arrays; + +/** + * @since 1.7+ + * @author yu 2019/9/21. + */ +public class MarkDownUtil { + + /** + * markdown to html + * + * @param content markdown contents + * @return parse html contents + */ + public static String toHtml(String content) { + MutableDataSet options = new MutableDataSet(); + options.setFrom(ParserEmulationProfile.MARKDOWN); + // enable table parse! + options.set(Parser.EXTENSIONS, Arrays.asList(TablesExtension.create())); + + Parser parser = Parser.builder(options).build(); + HtmlRenderer renderer = HtmlRenderer.builder(options).build(); + + Node document = parser.parse(content); + return renderer.render(document); + } + +} diff --git a/src/main/resources/template/AllInOne.btl b/src/main/resources/template/AllInOne.btl index 60bad96..9b070aa 100644 --- a/src/main/resources/template/AllInOne.btl +++ b/src/main/resources/template/AllInOne.btl @@ -27,16 +27,16 @@ for(doc in api.list){ <%if(isNotEmpty(doc.headers)){%> **Request-headers:** -Name | Type|Description ----|---|--- +Header | Type|Description|Required|Since +---|---|---|---|---- ${doc.headers} <%}%> <%if(isNotEmpty(doc.requestParams)){%> **Request-parameters:** -Parameter | Type|Description|Required ----|---|---|--- +Parameter | Type|Description|Required|Since +---|---|---|---|--- ${doc.requestParams} <%}%> @@ -49,8 +49,8 @@ ${doc.requestUsage} <%if(isNotEmpty(doc.responseParams)){%> **Response-fields:** -Field | Type|Description ----|---|--- +Field | Type|Description|Since +---|---|---|--- ${doc.responseParams} <%}%> diff --git a/src/main/resources/template/ApiDoc.btl b/src/main/resources/template/ApiDoc.btl index bec42d2..15ad0ec 100644 --- a/src/main/resources/template/ApiDoc.btl +++ b/src/main/resources/template/ApiDoc.btl @@ -4,17 +4,17 @@ for(doc in list){ %> ## ${doc.desc} -**URL:** ${doc.url} +**URL:** `${doc.url}` -**Type:** ${doc.type} +**Type:** `${doc.type}` -**Content-Type:** ${doc.contentType} +**Content-Type:** `${doc.contentType}` <%if(isNotEmpty(doc.headers)){%> **Request-headers:** -Name | Type|Description ----|---|--- +Header | Type|Description|Required|Since +---|---|---|---|---- ${doc.headers} <%}%> diff --git a/src/main/resources/template/HtmlApiDoc.btl b/src/main/resources/template/HtmlApiDoc.btl new file mode 100644 index 0000000..13445d7 --- /dev/null +++ b/src/main/resources/template/HtmlApiDoc.btl @@ -0,0 +1,24 @@ + + + + + + + + + + ${title} + + +
+ ${html} +
+ Generated by smart-doc at ${createTime} + Suggestions, contact, support and error reporting on + Gitee or + Github + +
+
+ + \ No newline at end of file diff --git a/src/main/resources/template/Index.btl b/src/main/resources/template/Index.btl index 683ae24..33eb53c 100644 --- a/src/main/resources/template/Index.btl +++ b/src/main/resources/template/Index.btl @@ -3,38 +3,45 @@ + + + + api doc
- +
\ No newline at end of file diff --git a/src/main/resources/template/index.css b/src/main/resources/template/index.css index 52d09fe..02f1043 100644 --- a/src/main/resources/template/index.css +++ b/src/main/resources/template/index.css @@ -1 +1,228 @@ -.book-summary{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;position:absolute;top:0;left:-300px;bottom:0;z-index:1;overflow-y:auto;width:300px;color:#364149;background:#fafafa;border-right:1px solid rgba(0,0,0,.07);-webkit-transition:left 250ms ease;-moz-transition:left 250ms ease;-o-transition:left 250ms ease;transition:left 250ms ease}.book-summary ul.summary{list-style:none;margin:0;padding:0;-webkit-transition:top .5s ease;-moz-transition:top .5s ease;-o-transition:top .5s ease;transition:top .5s ease}.book-summary ul.summary li{list-style:none}.book-summary ul.summary li.header{padding:10px 15px;padding-top:20px;text-transform:uppercase;color:#939da3}.book-summary ul.summary li.divider{height:1px;margin:7px 0;overflow:hidden;background:rgba(0,0,0,.07)}.book-summary ul.summary li i.fa-check{display:none;position:absolute;right:9px;top:16px;font-size:9px;color:#3c3}.book-summary ul.summary li.done>a{color:#364149;font-weight:400}.book-summary ul.summary li.done>a i{display:inline}.book-summary ul.summary li a,.book-summary ul.summary li span{display:block;padding:10px 15px;border-bottom:0;color:#364149;background:0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;position:relative}.book-summary ul.summary li a:hover{text-decoration:underline}.book-summary ul.summary li a:focus{outline:0}.book-summary ul.summary li.active>a{color:#008cff;background:0;text-decoration:none}.book-summary ul.summary li ul{padding-left:20px}@media(max-width:600px){.book-summary{width:calc(100% - 60px);bottom:0;left:-100%}}.book.with-summary .book-summary{left:0}.book.without-animation .book-summary{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important}.book{position:relative;width:100%;height:100%}@media(min-width:600px){.book.with-summary .book-body{left:300px}}@media(max-width:600px){.book.with-summary{overflow:hidden}.book.with-summary .book-body{-webkit-transform:translate(calc(100% - 60px),0);-moz-transform:translate(calc(100% - 60px),0);-ms-transform:translate(calc(100% - 60px),0);-o-transform:translate(calc(100% - 60px),0);transform:translate(calc(100% - 60px),0)}}.book.without-animation .book-body{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important}.book-body{position:absolute;top:0;right:0;left:0;bottom:0;overflow-y:auto;color:#000;background:#fff;-webkit-transition:left 250ms ease;-moz-transition:left 250ms ease;-o-transition:left 250ms ease;transition:left 250ms ease}@media(max-width:1240px){.book-body{-webkit-transition:-webkit-transform 250ms ease;-moz-transition:-moz-transform 250ms ease;-o-transition:-o-transform 250ms ease;transition:transform 250ms ease;padding-bottom:20px}}#book-search-input{padding:6px;background:0;transition:top .5s ease;border-bottom:1px solid rgba(0,0,0,.07);border-top:1px solid rgba(0,0,0,.07);margin-bottom:10px;margin-top:-1px}#book-search-input input,#book-search-input input:focus,#book-search-input input:hover{width:100%;background:0;border:1px solid transparent;box-shadow:none;outline:0;line-height:22px;padding:7px 7px;color:inherit}a{text-decoration:none}body,html{height:100%}html{font-size:62.5%}body{margin:0}body{text-rendering:optimizeLegibility;font-smoothing:antialiased;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:.2px;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%} \ No newline at end of file +.book-summary { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + position: absolute; + top: 0; + left: -300px; + bottom: 0; + z-index: 1; + overflow-y: auto; + width: 300px; + color: #364149; + background: #fafafa; + border-right: 1px solid rgba(0, 0, 0, .07); + -webkit-transition: left 250ms ease; + -moz-transition: left 250ms ease; + -o-transition: left 250ms ease; + transition: left 250ms ease +} + +.book-summary ul.summary { + list-style: none; + margin: 0; + padding: 0; + -webkit-transition: top .5s ease; + -moz-transition: top .5s ease; + -o-transition: top .5s ease; + transition: top .5s ease +} + +.book-summary ul.summary li { + list-style: none +} + +.book-summary ul.summary li.header { + padding: 10px 15px; + padding-top: 20px; + text-transform: uppercase; + color: #939da3 +} + +.book-summary ul.summary li.divider { + height: 1px; + margin: 7px 0; + overflow: hidden; + background: rgba(0, 0, 0, .07) +} + +.book-summary ul.summary li i.fa-check { + display: none; + position: absolute; + right: 9px; + top: 16px; + font-size: 9px; + color: #3c3 +} + +.book-summary ul.summary li.done > a { + color: #364149; + font-weight: 400 +} + +.book-summary ul.summary li.done > a i { + display: inline +} + +.book-summary ul.summary li a, .book-summary ul.summary li span { + display: block; + padding: 10px 15px; + border-bottom: 0; + color: #364149; + background: 0; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + position: relative +} + +.book-summary ul.summary li a:hover { + text-decoration: underline +} + +.book-summary ul.summary li a:focus { + outline: 0 +} + +.book-summary ul.summary li.active > a { + color: #008cff; + background: 0; + text-decoration: none +} + +.book-summary ul.summary li ul { + padding-left: 20px +} + +@media (max-width: 600px) { + .book-summary { + width: calc(100% - 60px); + bottom: 0; + left: -100% + } +} + +.book.with-summary .book-summary { + left: 0 +} + +.book.without-animation .book-summary { + -webkit-transition: none !important; + -moz-transition: none !important; + -o-transition: none !important; + transition: none !important +} + +.book { + position: relative; + width: 100%; + height: 100% +} + +@media (min-width: 600px) { + .book.with-summary .book-body { + left: 300px + } +} + +@media (max-width: 600px) { + .book.with-summary { + overflow: hidden + } + + .book.with-summary .book-body { + -webkit-transform: translate(calc(100% - 60px), 0); + -moz-transform: translate(calc(100% - 60px), 0); + -ms-transform: translate(calc(100% - 60px), 0); + -o-transform: translate(calc(100% - 60px), 0); + transform: translate(calc(100% - 60px), 0) + } +} + +.book.without-animation .book-body { + -webkit-transition: none !important; + -moz-transition: none !important; + -o-transition: none !important; + transition: none !important +} + +.book-body { + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; + overflow-y: auto; + color: #000; + background: #fff; + -webkit-transition: left 250ms ease; + -moz-transition: left 250ms ease; + -o-transition: left 250ms ease; + transition: left 250ms ease +} + +@media (max-width: 1240px) { + .book-body { + -webkit-transition: -webkit-transform 250ms ease; + -moz-transition: -moz-transform 250ms ease; + -o-transition: -o-transform 250ms ease; + transition: transform 250ms ease; + padding-bottom: 20px + } +} + +#book-search-input { + padding: 6px; + background: 0; + transition: top .5s ease; + border-bottom: 1px solid rgba(0, 0, 0, .07); + border-top: 1px solid rgba(0, 0, 0, .07); + margin-bottom: 10px; + margin-top: -1px +} + +#book-search-input input, #book-search-input input:focus, #book-search-input input:hover { + width: 100%; + background: 0; + border: 1px solid transparent; + box-shadow: none; + outline: 0; + line-height: 22px; + padding: 7px 7px; + color: inherit +} + +a { + text-decoration: none +} + +body, html { + height: 100% +} + +html { + font-size: 62.5% +} + +body { + margin: 0 +} + +body { + text-rendering: optimizeLegibility; + font-smoothing: antialiased; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + letter-spacing: .2px; + text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100% +} + +#reference { + padding-top: 10px; + padding-bottom: 10px; + padding-left: 15px; +} + +.footer_link { + margin-bottom: 45px; +} \ No newline at end of file diff --git a/src/main/resources/template/markdown.css b/src/main/resources/template/markdown.css index 9b9137b..473a45d 100644 --- a/src/main/resources/template/markdown.css +++ b/src/main/resources/template/markdown.css @@ -1 +1,264 @@ -html{overflow-x:initial!important}:root{--bg-color:#fff;--text-color:#333;--select-text-bg-color:#b5d6fc;--select-text-font-color:auto;--monospace:"Lucida Console",Consolas,"Courier",monospace}html{font-size:14px;background-color:var(--bg-color);color:var(--text-color);font-family:Helvetica Neue,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased}body{margin:0;padding:0;height:auto;bottom:0;top:0;left:0;right:0;font-size:1rem;line-height:1.42857;overflow-x:hidden;background:inherit;tab-size:4}iframe{margin:auto}a.url{word-break:break-all}a:active,a:hover{outline:0}.in-text-selection,::selection{text-shadow:none;background:var(--select-text-bg-color);color:var(--select-text-font-color)}#write{margin:0 auto;height:auto;width:inherit;word-break:normal;overflow-wrap:break-word;position:relative;white-space:normal;overflow-x:visible;padding-top:40px}#write.first-line-indent p{text-indent:2em}#write.first-line-indent li p,#write.first-line-indent p *{text-indent:0}#write.first-line-indent li{margin-left:2em}.for-image #write{padding-left:8px;padding-right:8px}body.typora-export{padding-left:30px;padding-right:30px}.typora-export .footnote-line,.typora-export li,.typora-export p{white-space:pre-wrap}@media screen and (max-width:500px){body.typora-export{padding-left:0;padding-right:0}#write{padding-left:20px;padding-right:20px}.CodeMirror-sizer{margin-left:0!important}.CodeMirror-gutters{display:none!important}}#write li>figure:last-child{margin-bottom:.5rem}#write ol,#write ul{position:relative}img{max-width:100%;vertical-align:middle}button,input,select,textarea{color:inherit;font:inherit}input[type=checkbox],input[type=radio]{line-height:normal;padding:0}*,:after,:before{box-sizing:border-box}#write h1,#write h2,#write h3,#write h4,#write h5,#write h6,#write p,#write pre{width:inherit}#write h1,#write h2,#write h3,#write h4,#write h5,#write h6,#write p{position:relative}p{line-height:inherit}h1,h2,h3,h4,h5,h6{break-after:avoid-page;break-inside:avoid;orphans:2}p{orphans:4}h1{font-size:2rem}h2{font-size:1.8rem}h3{font-size:1.6rem}h4{font-size:1.4rem}h5{font-size:1.2rem}h6{font-size:1rem}.md-math-block,.md-rawblock,h1,h2,h3,h4,h5,h6,p{margin-top:1rem;margin-bottom:1rem}.hidden{display:none}.md-blockmeta{color:#ccc;font-weight:700;font-style:italic}a{cursor:pointer}sup.md-footnote{padding:2px 4px;background-color:hsla(0,0%,93%,.7);color:#555;border-radius:4px;cursor:pointer}sup.md-footnote a,sup.md-footnote a:hover{color:inherit;text-transform:inherit;text-decoration:inherit}#write input[type=checkbox]{cursor:pointer;width:inherit;height:inherit}figure{overflow-x:auto;margin:1.2em 0;max-width:calc(100% + 1pc);padding:0}figure>table{margin:0!important}tr{break-inside:avoid;break-after:auto}thead{display:table-header-group}table{border-collapse:collapse;border-spacing:0;width:100%;overflow:auto;break-inside:auto;text-align:left}table.md-table td{min-width:2pc}.CodeMirror-gutters{border-right:0;background-color:inherit}.CodeMirror-linenumber{user-select:none}.CodeMirror{text-align:left}.CodeMirror-placeholder{opacity:.3}.CodeMirror pre{padding:0 4px}.CodeMirror-lines{padding:0}div.hr:focus{cursor:none}#write pre{white-space:pre-wrap}#write.fences-no-line-wrapping pre{white-space:pre}#write pre.ty-contain-cm{white-space:normal}.CodeMirror-gutters{margin-right:4px}.md-fences{font-size:.9rem;display:block;break-inside:avoid;text-align:left;overflow:visible;white-space:pre;background:inherit;position:relative!important}.md-diagram-panel{width:100%;margin-top:10px;text-align:center;padding-top:0;padding-bottom:8px;overflow-x:auto}#write .md-fences.mock-cm{white-space:pre-wrap}.md-fences.md-fences-with-lineno{padding-left:0}#write.fences-no-line-wrapping .md-fences.mock-cm{white-space:pre;overflow-x:auto}.md-fences.mock-cm.md-fences-with-lineno{padding-left:8px}.CodeMirror-line,twitterwidget{break-inside:avoid}.footnotes{opacity:.8;font-size:.9rem;margin-top:1em;margin-bottom:1em}.footnotes+.footnotes{margin-top:0}.md-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:0 0;text-decoration:none;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:400;text-align:left;box-sizing:content-box;direction:ltr}li div{padding-top:0}blockquote{margin:1rem 0}li .mathjax-block,li p{margin:.5rem 0}li{margin:0;position:relative}blockquote>:last-child{margin-bottom:0}blockquote>:first-child,li>:first-child{margin-top:0}.footnotes-area{color:#888;margin-top:.714rem;padding-bottom:.143rem;white-space:normal}#write .footnote-line{white-space:pre-wrap}@media print{body,html{border:1px solid transparent;height:99%;break-after:avoid;break-before:avoid}#write{margin-top:0;padding-top:0;border-color:transparent!important}.typora-export *{-webkit-print-color-adjust:exact}html.blink-to-pdf{font-size:13px}.typora-export #write{padding-left:2pc;padding-right:2pc;padding-bottom:0;break-after:avoid}.typora-export #write:after{height:0}}.footnote-line{margin-top:.714em;font-size:.7em}a img,img a{cursor:pointer}pre.md-meta-block{font-size:.8rem;min-height:.8rem;white-space:pre-wrap;background:#ccc;display:block;overflow-x:hidden}p>.md-image:only-child:not(.md-img-error) img,p>img:only-child{display:block;margin:auto}p>.md-image:only-child{display:inline-block;width:100%}#write .MathJax_Display{margin:.8em 0 0}.md-math-block{width:100%}.md-math-block:not(:empty):after{display:none}[contenteditable=true]:active,[contenteditable=true]:focus{outline:0;box-shadow:none}.md-task-list-item{position:relative;list-style-type:none}.task-list-item.md-task-list-item{padding-left:0}.md-task-list-item>input{position:absolute;top:0;left:0;margin-left:-1.2em;margin-top:calc(1em - 10px);border:none}.math{font-size:1rem}.md-toc{min-height:3.58rem;position:relative;font-size:.9rem;border-radius:10px}.md-toc-content{position:relative;margin-left:0}.md-toc-content:after,.md-toc:after{display:none}.md-toc-item{display:block;color:#4183c4}.md-toc-item a{text-decoration:none}.md-toc-inner:hover{text-decoration:underline}.md-toc-inner{display:inline-block;cursor:pointer}.md-toc-h1 .md-toc-inner{margin-left:0;font-weight:700}.md-toc-h2 .md-toc-inner{margin-left:2em}.md-toc-h3 .md-toc-inner{margin-left:4em}.md-toc-h4 .md-toc-inner{margin-left:6em}.md-toc-h5 .md-toc-inner{margin-left:8em}.md-toc-h6 .md-toc-inner{margin-left:10em}@media screen and (max-width:48em){.md-toc-h3 .md-toc-inner{margin-left:3.5em}.md-toc-h4 .md-toc-inner{margin-left:5em}.md-toc-h5 .md-toc-inner{margin-left:6.5em}.md-toc-h6 .md-toc-inner{margin-left:8em}}a.md-toc-inner{font-size:inherit;font-style:inherit;font-weight:inherit;line-height:inherit}.footnote-line a:not(.reversefootnote){color:inherit}.md-attr{display:none}.md-fn-count:after{content:"."}code,pre,samp,tt{font-family:var(--monospace)}kbd{margin:0 .1em;padding:.1em .6em;font-size:.8em;color:#242729;background:#fff;border:1px solid #adb3b9;border-radius:3px;box-shadow:rgba(12,13,14,.2) 0 1px 0,#fff 0 0 0 2px inset;white-space:nowrap;vertical-align:middle}.md-comment{color:#a27f03;opacity:.8;font-family:var(--monospace)}code{text-align:left;vertical-align:initial}a.md-print-anchor{white-space:pre!important;border:initial none initial!important;display:inline-block!important;position:absolute!important;width:1px!important;right:0!important;outline:0!important;background:0 0!important;text-decoration:initial!important;text-shadow:initial!important}.md-inline-math .MathJax_SVG .noError{display:none!important}.html-for-mac .inline-math-svg .MathJax_SVG{vertical-align:.2px}.md-math-block .MathJax_SVG_Display{text-align:center;margin:0;position:relative;text-indent:0;max-width:none;max-height:none;min-height:0;min-width:100%;width:auto;overflow-y:hidden;display:block!important}.MathJax_SVG_Display,.md-inline-math .MathJax_SVG_Display{width:auto;margin:inherit;display:inline-block!important}.MathJax_SVG .MJX-monospace{font-family:var(--monospace)}.MathJax_SVG .MJX-sans-serif{font-family:sans-serif}.MathJax_SVG{display:inline;font-style:normal;font-weight:400;line-height:normal;zoom:90%;text-indent:0;text-align:left;text-transform:none;letter-spacing:normal;word-spacing:normal;overflow-wrap:normal;white-space:nowrap;float:none;direction:ltr;max-width:none;max-height:none;min-width:0;min-height:0;border:0;padding:0;margin:0}.MathJax_SVG *{transition:none 0s ease 0s}.MathJax_SVG_Display svg{vertical-align:middle!important;margin-bottom:0!important;margin-top:0!important}.os-windows.monocolor-emoji .md-emoji{font-family:Segoe UI Symbol,sans-serif}.md-diagram-panel>svg{max-width:100%}[lang=flow] svg,[lang=mermaid] svg{max-width:100%;height:auto}[lang=mermaid] .node text{font-size:1rem}table tr th{border-bottom:0}video{display:block;margin:0 auto}iframe,video{max-width:100%}iframe{width:100%;border:none}.highlight td,.highlight tr{border:0}.CodeMirror{height:auto}.CodeMirror.cm-s-inner{background:inherit}.CodeMirror-scroll{overflow:auto hidden;z-index:3}.CodeMirror-gutter-filler,.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror-gutters{border-right:1px solid #ddd;background:inherit;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;text-align:right;color:#999}.cm-s-inner .cm-keyword{color:#708}.cm-s-inner .cm-atom,.cm-s-inner.cm-atom{color:#219}.cm-s-inner .cm-number{color:#164}.cm-s-inner .cm-def{color:#00f}.cm-s-inner .cm-variable{color:#000}.cm-s-inner .cm-variable-2{color:#05a}.cm-s-inner .cm-variable-3{color:#085}.cm-s-inner .cm-string{color:#a11}.cm-s-inner .cm-property{color:#000}.cm-s-inner .cm-operator{color:#981a1a}.cm-s-inner .cm-comment,.cm-s-inner.cm-comment{color:#a50}.cm-s-inner .cm-string-2{color:#f50}.cm-s-inner .cm-meta,.cm-s-inner .cm-qualifier{color:#555}.cm-s-inner .cm-builtin{color:#30a}.cm-s-inner .cm-bracket{color:#997}.cm-s-inner .cm-tag{color:#170}.cm-s-inner .cm-attribute{color:#00c}.cm-s-inner .cm-header,.cm-s-inner.cm-header{color:#00f}.cm-s-inner .cm-quote,.cm-s-inner.cm-quote{color:#090}.cm-s-inner .cm-hr,.cm-s-inner.cm-hr{color:#999}.cm-s-inner .cm-link,.cm-s-inner.cm-link{color:#00c}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-del{text-decoration:line-through}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-error,.cm-invalidchar{color:red}.cm-constant{color:#268bd2}.cm-defined{color:#b58900}div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.cm-s-inner .CodeMirror-activeline-background{background:inherit}.CodeMirror{position:relative;overflow:hidden}.CodeMirror-scroll{height:100%;outline:0;position:relative;box-sizing:content-box;background:inherit}.CodeMirror-sizer{position:relative}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow:hidden}.CodeMirror-hscrollbar{bottom:0;left:0;overflow:hidden}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;padding-bottom:30px;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;box-sizing:content-box;padding-bottom:30px;margin-bottom:-2pc;display:inline-block}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:0 0!important;border:none!important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-lines{cursor:text}.CodeMirror pre{border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;overflow-wrap:normal;color:inherit;z-index:2;position:relative;overflow:visible}.CodeMirror-wrap pre{overflow-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-code pre{border-right:30px solid transparent;width:fit-content}.CodeMirror-wrap .CodeMirror-code pre{border-right:none;width:auto}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.CodeMirror-wrap .CodeMirror-scroll{overflow-x:hidden}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-measure pre{position:static}.CodeMirror div.CodeMirror-cursor{position:absolute;visibility:hidden;border-right:none;width:0}.CodeMirror-focused div.CodeMirror-cursor{visibility:inherit}.cm-searching{background:rgba(255,255,0,.4)}@media print{.CodeMirror div.CodeMirror-cursor{visibility:hidden}}:root{--side-bar-bg-color:#fafafa;--control-text-color:#777}html{font-size:1pc}body{font-family:Open Sans,Clear Sans,Helvetica Neue,Helvetica,Arial,sans-serif;color:#333;line-height:1.6}#write{max-width:80%;margin:0 auto;padding:30px 30px 75pt}#write>ol:first-child,#write>ul:first-child{margin-top:30px}a{color:#4183c4}h1,h2,h3,h4,h5,h6{position:relative;margin-top:1rem;margin-bottom:1rem;font-weight:700;line-height:1.4;cursor:text}h1:hover a.anchor,h2:hover a.anchor,h3:hover a.anchor,h4:hover a.anchor,h5:hover a.anchor,h6:hover a.anchor{text-decoration:none}h1 code,h1 tt,h2 code,h2 tt,h3 code,h3 tt,h4 code,h4 tt,h5 code,h5 tt,h6 code,h6 tt{font-size:inherit}h1{font-size:2.25em;line-height:1.2}h1,h2{padding-bottom:.3em;border-bottom:1px solid #eee}h2{font-size:1.75em;line-height:1.225}h3{font-size:1.5em;line-height:1.43}h4{font-size:1.25em}h5,h6{font-size:1em}h6{color:#777}blockquote,dl,ol,p,table,ul{margin:.8em 0}li>ol,li>ul{margin:0}hr{height:2px;padding:0;margin:1pc 0;background-color:#e7e7e7;border:0 none;overflow:hidden;box-sizing:content-box}li p.first{display:inline-block}ol,ul{padding-left:30px}ol:first-child,ul:first-child{margin-top:0}ol:last-child,ul:last-child{margin-bottom:0}blockquote{border-left:4px solid #dfe2e5;padding:0 15px;color:#777}blockquote blockquote{padding-right:0}table{padding:0;word-break:initial}table tr{border-top:1px solid #dfe2e5;margin:0;padding:0}table tr:nth-child(2n),thead{background-color:#f8f8f8}table tr th{font-weight:700;border-width:1px 1px 0;border-top-style:solid;border-right-style:solid;border-left-style:solid;border-top-color:#dfe2e5;border-right-color:#dfe2e5;border-left-color:#dfe2e5;border-image:initial;border-bottom-style:initial;border-bottom-color:initial}table tr td,table tr th{margin:0;padding:6px 13px}table tr td{border:1px solid #dfe2e5}table tr td:first-child,table tr th:first-child{margin-top:0}table tr td:last-child,table tr th:last-child{margin-bottom:0}.CodeMirror-lines{padding-left:4px}.code-tooltip{box-shadow:rgba(0,28,36,.3) 0 1px 1px 0;border-top:1px solid #eef2f2}.md-fences,code,tt{border:1px solid #e7eaed;background-color:#f8f8f8;border-radius:3px;padding:2px 4px 0;font-size:.9em}code{background-color:#f3f4f4;padding:0 2px}.md-fences{margin-bottom:15px;margin-top:15px;padding-top:8px;padding-bottom:6px}.md-task-list-item>input{margin-left:-1.3em}@media print{html{font-size:13px}pre,table{break-inside:avoid}pre{overflow-wrap:break-word}}.md-fences{background-color:#f8f8f8}#write pre.md-meta-block{padding:1rem;font-size:85%;line-height:1.45;background-color:#f7f7f7;border:0;border-radius:3px;color:#777;margin-top:0!important}.mathjax-block>.code-tooltip{bottom:.375rem}.md-mathjax-midline{background:#fafafa}#write>h3.md-focus:before{left:-1.5625rem;top:.375rem}#write>h4.md-focus:before,#write>h5.md-focus:before,#write>h6.md-focus:before{left:-1.5625rem;top:.285714rem}.md-image>.md-meta{border-radius:3px;padding:2px 0 0 4px;font-size:.9em;color:inherit}.md-tag{color:#a7a7a7;opacity:1}.md-toc{margin-top:20px;padding-bottom:20px}.sidebar-tabs{border-bottom:none}#typora-quick-open{border:1px solid #ddd;background-color:#f8f8f8}#typora-quick-open-item{background-color:#fafafa;border-color:#fefefe #e5e5e5 #e5e5e5 #eee;border-style:solid;border-width:1px}.on-focus-mode blockquote{border-left-color:rgba(85,85,85,.12)}.context-menu,.megamenu-content,footer,header{font-family:Segoe UI,Arial,sans-serif}.file-node-content:hover .file-node-icon,.file-node-content:hover .file-node-open-state{visibility:visible}.mac-seamless-mode #typora-sidebar{background-color:var(--side-bar-bg-color)}.md-lang{color:#b4654d}.html-for-mac .context-menu{--item-hover-bg-color:#e6f0fe}#md-notification .btn{border:0}.dropdown-menu .divider{border-color:#e5e5e5}.ty-preferences .window-content{background-color:#fafafa}.ty-preferences .nav-group-item.active{color:#fff;background:#999}.footnote-line,.typora-export,.typora-export li,.typora-export p{white-space:normal}.page-footer{margin-top:50px;border-top:1px solid #ccc;overflow:hidden;padding:10px 0;font-size:14px;color:gray}.footer-modification{float:right}.footer-modification a{text-decoration:none} \ No newline at end of file +body { + margin: 0; + padding: 0; + height: auto; + bottom: 0; + top: 0; + left: 0; + right: 0; + font-size: 1rem; + line-height: 1.42857; + overflow-x: hidden; + background: inherit; + tab-size: 4 +} + +.margin-tb-zero, +.markdown-body ol ol, +.markdown-body ul ol, +.markdown-body ol ul, +.markdown-body ul ul, +.markdown-body ol ul ol, +.markdown-body ul ul ol, +.markdown-body ol ul ul, +.markdown-body ul ul ul { + margin-top: 0; + margin-bottom: 0; +} +.markdown-body { + font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 16px; + color: #333; + line-height: 1.6; + word-wrap: break-word; + padding: 45px; + background: #fff; + #border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 3px 3px; + #max-width: 55%; + #margin-left:15%; + border-radius: 0 0 3px 3px; + max-width: 800px; + margin: 0px auto; + padding: 30px 30px 100px; + +} +.markdown-body > *:first-child { + margin-top: 0 !important; +} +.markdown-body > *:last-child { + margin-bottom: 0 !important; +} +.markdown-body * { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 1em; + margin-bottom: 16px; + font-weight: bold; + line-height: 1.4; +} +.markdown-body p, +.markdown-body blockquote, +.markdown-body ul, +.markdown-body ol, +.markdown-body dl, +.markdown-body table, +.markdown-body pre { + margin-top: 0; + margin-bottom: 16px; +} +.markdown-body h1 { + margin: 0.67em 0; + padding-bottom: 0.3em; + font-size: 2.25em; + line-height: 1.2; + border-bottom: 1px solid #eee; +} +.markdown-body h2 { + padding-bottom: 0.3em; + font-size: 1.75em; + line-height: 1.225; + border-bottom: 1px solid #eee; +} +.markdown-body h3 { + font-size: 1.5em; + line-height: 1.43; +} +.markdown-body h4 { + font-size: 1.25em; +} +.markdown-body h5 { + font-size: 1em; +} +.markdown-body h6 { + font-size: 1em; + color: #777; +} +.markdown-body ol, +.markdown-body ul { + padding-left: 2em; +} +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} +.markdown-body ol ul, +.markdown-body ul ul { + list-style-type: circle; +} +.markdown-body ol ul ul, +.markdown-body ul ul ul { + list-style-type: square; +} +.markdown-body ol { + list-style-type: decimal; +} +.markdown-body ul { + list-style-type: disc; +} +.markdown-body blockquote { + margin-left: 0; + margin-right: 0; + padding: 0 15px; + color: #777; + border-left: 4px solid #ddd; +} +.markdown-body table { + #display: block; + width: 100%; + overflow: auto; + word-break: normal; + word-break: keep-all; + border-collapse: collapse; + border-spacing: 0; +} +thead { + background-color: rgb(248, 248, 248); +} +.markdown-body table tr { + #background-color: #fff; + border-top: 1px solid #ccc; +} +.markdown-body table tr:nth-child(2n) { + background-color: #f8f8f8; +} +.markdown-body table th, +.markdown-body table td { + padding: 6px 13px; + border: 1px solid #ddd; +} +.markdown-body pre { + word-wrap: normal; + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: #f7f7f7; + -webkit-border-radius: 3px; + border-radius: 3px; +} +.markdown-body pre code { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + font-size: 100%; + line-height: inherit; + word-wrap: normal; + white-space: pre; + border: 0; + -webkit-border-radius: 3px; + border-radius: 3px; + background-color: transparent; +} +.markdown-body pre code:before, +.markdown-body pre code:after { + content: normal; +} +.markdown-body code { + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; + padding: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + margin: 0; + font-size: 85%; + background-color: rgba(0,0,0,0.04); + -webkit-border-radius: 3px; + border-radius: 3px; +} +.markdown-body code:before, +.markdown-body code:after { + letter-spacing: -0.2em; + content: "\00a0"; +} +.markdown-body a { + color: #4078c0; + text-decoration: none; + background: transparent; +} +.markdown-body img { + max-width: 100%; + max-height: 100%; + -webkit-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 0 10px #555; + box-shadow: 0 0 10px #555; +} +.markdown-body strong { + font-weight: bold; +} +.markdown-body em { + font-style: italic; +} +.markdown-body del { + text-decoration: line-through; +} +.task-list-item { + list-style-type: none; +} +.task-list-item input { + font: 13px/1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + margin: 0 0.35em 0.25em -1.6em; + vertical-align: middle; +} +.task-list-item input[disabled] { + cursor: default; +} +.task-list-item input[type="checkbox"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} +.task-list-item input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} +.markdown-body .page-footer { + margin-top: 45px; + height: 50px; + border-top: 1px solid #ccc; + overflow: hidden; + padding: 10px 0; + font-size: 14px; + color: gray +} + +.markdown-body .footer-modification { + float: right +} + +.markdown-body .footer-modification a { + text-decoration: none +} \ No newline at end of file