add markdown flag for deck description

Needed so we can display consistently, and gradually transition over
This commit is contained in:
Damien Elmes 2021-02-09 18:46:48 +10:00
parent 333bbf3ee4
commit 9ce4b21935
9 changed files with 66 additions and 7 deletions

View File

@ -6,3 +6,5 @@ deck-config-used-by-decks =
*[other] { $decks } decks
}
deck-config-default-name = Default
deck-config-description-markdown = Enable markdown+clean HTML
deck-config-description-markdown-hint = Will appear as text on Anki 2.1.40 and below.

View File

@ -867,6 +867,10 @@ table.review-log {{ {revlog_style} }}
def set_preferences(self, prefs: Preferences) -> None:
self._backend.set_preferences(prefs)
def render_markdown(self, text: str, sanitize: bool = True) -> str:
"Not intended for public consumption at this time."
return self._backend.render_markdown(markdown=text, sanitize=sanitize)
# legacy name
_Collection = Collection

View File

@ -236,6 +236,7 @@ class DeckConf(QDialog):
f.autoplaySounds.setChecked(c["autoplay"])
f.replayQuestion.setChecked(c.get("replayq", True))
# description
f.enable_markdown.setChecked(self.deck.get("md", False))
f.desc.setPlainText(self.deck["desc"])
gui_hooks.deck_conf_did_load_config(self, self.deck, self.conf)
@ -320,6 +321,7 @@ class DeckConf(QDialog):
c["autoplay"] = f.autoplaySounds.isChecked()
c["replayq"] = f.replayQuestion.isChecked()
# description
self.deck["md"] = f.enable_markdown.isChecked()
self.deck["desc"] = f.desc.toPlainText()
gui_hooks.deck_conf_will_save_config(self, self.deck, self.conf)
self.mw.col.decks.save(self.deck)

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>623</width>
<width>638</width>
<height>514</height>
</rect>
</property>
@ -670,6 +670,16 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_markdown">
<property name="toolTip">
<string>DECK_CONFIG_DESCRIPTION_MARKDOWN_HINT</string>
</property>
<property name="text">
<string>DECK_CONFIG_DESCRIPTION_MARKDOWN</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="desc"/>
</item>

View File

@ -185,6 +185,8 @@ class Overview:
desc += " " + tr(TR.STUDYING_DELETING_THIS_DECK_FROM_THE_DECK)
else:
desc = deck.get("desc", "")
if deck.get("md", False):
desc = self.mw.col.render_markdown(desc)
if not desc:
return "<p>"
if deck["dyn"]:

View File

@ -207,11 +207,12 @@ service BackendService {
rpc FullDownload(SyncAuth) returns (Empty);
rpc SyncServerMethod(SyncServerMethodIn) returns (Json);
// translation/messages
// translation/messages/text manipulation
rpc TranslateString(TranslateStringIn) returns (String);
rpc FormatTimespan(FormatTimespanIn) returns (String);
rpc I18nResources(Empty) returns (Json);
rpc RenderMarkdown(RenderMarkdownIn) returns (String);
// tags
@ -303,6 +304,8 @@ message DeckCommon {
// but not currently used for anything
int32 learning_studied = 6;
reserved 8 to 13;
bytes other = 255;
}
@ -318,6 +321,9 @@ message NormalDeck {
uint32 extend_new = 2;
uint32 extend_review = 3;
string description = 4;
bool markdown_description = 5;
reserved 6 to 11;
}
message FilteredDeck {
@ -1245,3 +1251,8 @@ message SetConfigStringIn {
Config.String.Key key = 1;
string value = 2;
}
message RenderMarkdownIn {
string markdown = 1;
bool sanitize = 2;
}

View File

@ -23,6 +23,7 @@ use crate::{
latex::{extract_latex, extract_latex_expanding_clozes, ExtractedLatex},
log,
log::default_logger,
markdown::render_markdown,
media::check::MediaChecker,
media::sync::MediaSyncProgress,
media::MediaManager,
@ -48,7 +49,7 @@ use crate::{
SyncStage,
},
template::RenderedNode,
text::{escape_anki_wildcards, extract_av_tags, strip_av_tags, AVTag},
text::{escape_anki_wildcards, extract_av_tags, sanitize_html_no_images, strip_av_tags, AVTag},
timestamp::TimestampSecs,
types::Usn,
};
@ -1402,6 +1403,15 @@ impl BackendService for Backend {
.map_err(Into::into)
}
fn render_markdown(&self, input: pb::RenderMarkdownIn) -> BackendResult<pb::String> {
let mut text = render_markdown(&input.markdown);
if input.sanitize {
// currently no images
text = sanitize_html_no_images(&text);
}
Ok(text.into())
}
// tags
//-------------------------------------------------------------------

View File

@ -39,6 +39,8 @@ impl Deck {
pub fn new_normal() -> Deck {
let mut norm = NormalDeck::default();
norm.config_id = 1;
// enable in the future
// norm.markdown_description = true;
Deck {
id: DeckID(0),
@ -95,6 +97,7 @@ impl Deck {
pub fn rendered_description(&self) -> String {
if let DeckKind::Normal(normal) = &self.kind {
if normal.markdown_description {
let description = render_markdown(&normal.description);
// before allowing images, we'll need to handle relative image
// links on the various platforms
@ -102,6 +105,9 @@ impl Deck {
} else {
String::new()
}
} else {
String::new()
}
}
}

View File

@ -75,6 +75,10 @@ mod dynfix {
}
}
fn is_false(b: &bool) -> bool {
!b
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct DeckCommonSchema11 {
#[serde(deserialize_with = "deserialize_number_from_string")]
@ -95,6 +99,8 @@ pub struct DeckCommonSchema11 {
browser_collapsed: bool,
#[serde(default)]
desc: String,
#[serde(default, rename = "md", skip_serializing_if = "is_false")]
markdown_description: bool,
#[serde(rename = "dyn")]
dynamic: u8,
#[serde(flatten)]
@ -218,6 +224,7 @@ impl Default for NormalDeckSchema11 {
today: Default::default(),
other: Default::default(),
dynamic: 0,
markdown_description: false,
},
conf: 1,
extend_new: 0,
@ -292,6 +299,7 @@ impl From<NormalDeckSchema11> for NormalDeck {
config_id: deck.conf,
extend_new: deck.extend_new.max(0) as u32,
extend_review: deck.extend_rev.max(0) as u32,
markdown_description: deck.common.markdown_description,
description: deck.common.desc,
}
}
@ -365,6 +373,10 @@ impl From<Deck> for DeckCommonSchema11 {
} else {
0
},
markdown_description: match &deck.kind {
DeckKind::Normal(n) => n.markdown_description,
DeckKind::Filtered(_) => false,
},
desc: match deck.kind {
DeckKind::Normal(n) => n.description,
DeckKind::Filtered(_) => String::new(),