forc_doc/render/util/format/
docstring.rsuse crate::render::util::format::constant::*;
use comrak::{markdown_to_html, ComrakOptions};
use std::fmt::Write;
use sway_core::transform::{AttributeKind, AttributesMap};
use sway_lsp::utils::markdown::format_docs;
pub(crate) trait DocStrings {
fn to_html_string(&self) -> String;
fn to_raw_string(&self) -> String;
}
impl DocStrings for AttributesMap {
fn to_html_string(&self) -> String {
let docs = self.to_raw_string();
let mut options = ComrakOptions::default();
options.render.hardbreaks = true;
options.extension.strikethrough = true;
options.extension.table = true;
options.extension.autolink = true;
options.extension.superscript = true;
options.extension.footnotes = true;
options.parse.smart = true;
options.parse.default_info_string = Some(SWAY_FILEINE.into());
markdown_to_html(&format_docs(&docs), &options)
}
fn to_raw_string(&self) -> String {
let attributes = self.get(&AttributeKind::DocComment);
let mut docs = String::new();
if let Some(vec_attrs) = attributes {
for arg in vec_attrs.iter().flat_map(|attribute| &attribute.args) {
writeln!(docs, "{}", arg.name.as_str()).expect(
"problem appending `arg.name.as_str()` to `docs` with `writeln` macro.",
);
}
}
docs
}
}
pub(crate) fn create_preview(raw_attributes: Option<String>) -> Option<String> {
raw_attributes.as_ref().map(|description| {
let preview = split_at_markdown_header(description);
if preview.chars().count() > MAX_PREVIEW_CHARS && preview.contains(CLOSING_PARAGRAPH_TAG) {
let closing_tag_index = preview
.find(CLOSING_PARAGRAPH_TAG)
.expect("closing tag out of range");
let (preview, _) =
preview.split_at(closing_tag_index + CLOSING_PARAGRAPH_TAG.len() + 1);
if preview.chars().count() > MAX_PREVIEW_CHARS && preview.contains(NEWLINE_CHAR) {
let newline_index = preview
.find(NEWLINE_CHAR)
.expect("new line char out of range");
preview.split_at(newline_index).0.to_string()
} else {
preview.to_string()
}
} else {
preview.to_string()
}
})
}
pub(crate) fn split_at_markdown_header(raw_html: &str) -> &str {
for header in HTML_HEADERS {
if raw_html.contains(header) {
let v: Vec<_> = raw_html.split(header).collect();
return v.first().expect("expected non-empty &str");
}
continue;
}
raw_html
}