diff --git a/src/ast/link.rs b/src/ast/link.rs
index eddb2ef..48f55d2 100644
--- a/src/ast/link.rs
+++ b/src/ast/link.rs
@@ -1,7 +1,7 @@
use rowan::ast::{support, AstNode};
use super::{AffiliatedKeyword, Link, Paragraph, Token};
-use crate::syntax::SyntaxKind;
+use crate::{syntax::SyntaxKind, SyntaxElement};
impl Link {
/// Returns link destination
@@ -35,9 +35,59 @@ impl Link {
/// assert!(!link.has_description());
/// let link = Org::parse("[[https://google.com][Google]]").first_node::().unwrap();
/// assert!(link.has_description());
+ /// let link = Org::parse("[[https://example.com][*abc* /abc/]]").first_node::().unwrap();
+ /// assert!(link.has_description());
/// ```
pub fn has_description(&self) -> bool {
- support::token(self.syntax(), SyntaxKind::TEXT).is_some()
+ self.syntax()
+ .children_with_tokens()
+ .any(|e| e.kind() == SyntaxKind::L_BRACKET)
+ }
+
+ /// Returns parsed description
+ ///
+ /// Returns empty iterator if this link doesn't contain description
+ ///
+ /// ```rust
+ /// use orgize::{Org, ast::Link, SyntaxKind};
+ ///
+ /// let link = Org::parse("[[https://google.com]]").first_node::().unwrap();
+ /// assert_eq!(link.description().count(), 0);
+ ///
+ /// let link = Org::parse("[[https://google.com][Google]]").first_node::().unwrap();
+ /// let description = link.description().collect::>();
+ /// assert_eq!((description[0].kind(), description[0].to_string()), (SyntaxKind::TEXT, "Google".into()));
+ ///
+ /// let link = Org::parse("[[https://example.com][*abc* /abc/]]").first_node::().unwrap();
+ /// let description = link.description().collect::>();
+ /// assert_eq!((description[0].kind(), description[0].to_string()), (SyntaxKind::BOLD, "*abc*".into()));
+ /// assert_eq!((description[2].kind(), description[2].to_string()), (SyntaxKind::ITALIC, "/abc/".into()));
+ /// ```
+ pub fn description(&self) -> impl Iterator- {
+ self.syntax()
+ .children_with_tokens()
+ .skip_while(|e| e.kind() != SyntaxKind::L_BRACKET)
+ .skip(1)
+ .take_while(|e| e.kind() != SyntaxKind::R_BRACKET2)
+ }
+
+ /// Returns description raw string
+ ///
+ /// Returns empty string if this link doesn't contain description
+ ///
+ /// ```rust
+ /// use orgize::{Org, ast::Link};
+ ///
+ /// let link = Org::parse("[[https://google.com]]").first_node::().unwrap();
+ /// assert_eq!(link.description_raw(), "");
+ /// let link = Org::parse("[[https://google.com][Google]]").first_node::().unwrap();
+ /// assert_eq!(link.description_raw(), "Google");
+ /// let link = Org::parse("[[https://example.com][*abc* /abc/]]").first_node::().unwrap();
+ /// assert_eq!(link.description_raw(), "*abc* /abc/");
+ /// ```
+ pub fn description_raw(&self) -> String {
+ self.description()
+ .fold(String::new(), |acc, e| acc + &e.to_string())
}
/// Returns `true` if link is an image link