Skip to content

Commit

Permalink
0.1.1 (or so I hope)
Browse files Browse the repository at this point in the history
  • Loading branch information
randomouscrap98 committed Dec 18, 2022
1 parent 5fa12f5 commit f2f689d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bbscope"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
license = "MIT"
description = "BBCode to HTML with scoping rules, auto-close tags, highly extensible"
Expand Down
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,11 @@ basic bbcode tags, you'll see in the above:
- The last two parameters are optional newline consumption before and after the opening and
closing tag. For instance, if you wanted to consume the first newline __before__ the opening tag, and
the first newline __after__ the closing tag, those two might look like `Some((1,0)), Some((0,1))`
(this is subject to change)
(this may change in the future)

### Rocket Web example
There are many web frameworks to choose from for rust, so having an example for each would be a
bit difficult. Someone suggested Rocket, so here's an example in 0.5_rc2:
bit difficult. Someone suggested Rocket, so here's an example in 0.5.0_rc2:

```rust
#[macro_use] extern crate rocket;
Expand Down Expand Up @@ -159,10 +159,18 @@ is made at autolinking them (your mileage may vary)
bbcode parser I was using worked, and this was written to replace that. If there's a need,
I can add modes for \n vs \<br\>
- Performance was not a main concern, although you can enable additional performance
features `perf` feature (enables some regex optimizations, about a 4x improvement in my
features with the `perf` feature (enables some regex optimizations, about a 4x improvement in my
testing)
- Many rules are arbitrary and meant to copy an existing bbcode parser I used for many years

## Changelog:

- **0.0.6**: Small bugfix for conditional compilation
- **0.1.0**: Full rewrite; if using `BBCode::default()`, or `BBCode::basics()` and `BBCode::extras()`,
it should still compatible, but if you were creating custom tags at all, the entire system was
scrapped in favor of the `ScopeInfo` and `EmitScope` combo
- **0.1.1**: Small bugfix to enforce Sync + Send on closures (so bbcode can be used across threads)

## Future

I mostly published this for my own projects, which have specific requirements, but if for
Expand Down
34 changes: 29 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,22 @@ static NORMALTEXTID: &str = "normaltext";
/// The type for your emit closure which will take the open tag capture, body, and close tag capture and
/// output whatever you want. used with
pub type EmitScope = Box<dyn Fn(Option<Captures>, &str, Option<Captures>)->String + Send + Sync>;
/// The type for your emit closure when you're doing basic regex replacement with [`MatchType::Simple`]
pub type EmitSimple = Box<dyn Fn(Captures)->String + Send + Sync>; //Inefficient to use String but we have to in order to support replacements etc

/// Information about a scoped tag with open and close elements. This gives you the power to craft
/// many kinds of markup, not just bbcode, and have it understand scope
pub struct ScopeInfo {
/// A list of [`MatchInfo`] ids for tags which are allowed to be parsed within the body of
/// this scope. If [`None`], any tag is allowed (default)
pub only: Option<Vec<&'static str>>,
/// Whether or not this scope automatically closes previous scopes of the same type. Generally
/// this isn't how tags work: doing [b][b][b]EXTRA BOLD[/b][/b][/b] produces triple bold text.
/// However, elements like [*] (list item) benefit from closing the previous scope if it's the
/// same type
pub double_closes: bool,
/// The core of the parsing system: your provided closure which transforms the pre-parsed data
/// given into HTML (or whatever)
pub emit: EmitScope,
}

Expand Down Expand Up @@ -53,7 +63,7 @@ impl ScopeInfo {
/// just use the [`Simple`] option
pub enum MatchType {
/// A match type that requires no scoping rules: just a simple regex replacement (or whatever replacement you want)
Simple(Box<dyn Fn(Captures)->String + Send + Sync>), //Inefficient to use String but we have to in order to support replacements etc
Simple(EmitSimple),
/// The match should expect an open tag, which increases scope and performs open scope rules
Open(Arc<ScopeInfo>),
/// The match should expect a closing tag, which decreases scope and performs close scope rules
Expand All @@ -64,8 +74,11 @@ pub enum MatchType {
/// Not necessary a scoped element, could define eating garbage, passing normal text through, etc.
/// It's all up to the 'match_type'
pub struct MatchInfo {
/// A unique identifier for you to reference in things like [`ScopeInfo.only`]
pub id: &'static str,
/// The regex for this parse item. Most likely an open or close tag, but you can do anything you want
pub regex : Regex,
/// The type of match, indicates whether to open or close a scope (or perform no scoping)
pub match_type: MatchType,
}

Expand All @@ -75,10 +88,18 @@ pub struct MatchInfo {
/// A scope for bbcode tags. Scopes increase and decrease as tags are opened and closed. Scopes are placed on a stack
/// to aid with auto-closing tags
struct BBScope<'a> {
/// Id of the [`MatchInfo`] which produced this scope. Used for tracking, double_closes detection, etc
id: &'static str,
/// The scope information from the [`MatchInfo`] which describes the nature of this current scope. Should
/// always be a reference, as it's just informational
info: Arc<ScopeInfo>,
/// The regex capture for the open tag. We save this for later, when we finally emit the completed scope.
/// Your [`EmitScope`] closure in [`ScopeInfo`] receives this as the first argument
open_tag_capture: Option<Captures<'a>>,
body: String, //where to dump current result (when this scope is one top)
/// The currently retained body of this scope. If the scope is on top, this is where general text goes
/// before the closing tag is detected. Your [`EmitScope`] closure in [`ScopeInfo`] receives this as the
/// second argument
body: String,
}

impl BBScope<'_> {
Expand Down Expand Up @@ -233,6 +254,8 @@ impl BBCode
Ok(Self::from_matchers(Self::basics()?))
}

/// Create a BBCode parser from the given list of matchers. If you're building a custom set of tags,
/// or merging [`BBCode::basic()`] with [`BBCode::extras()`] (and maybe more), use this endpoint
pub fn from_matchers(matchers: Vec<MatchInfo>) -> Self {
Self {
matchers: Arc::new(matchers),
Expand Down Expand Up @@ -342,7 +365,8 @@ impl BBCode

/// Get a vector of ALL basic matchers! This is the function you want to call to get a vector for the bbcode
/// generator!
pub fn basics() -> Result<Vec<MatchInfo>, regex::Error> {
pub fn basics() -> Result<Vec<MatchInfo>, regex::Error>
{
//First, get the default direct replacements
let mut matches : Vec<MatchInfo> = Vec::new();

Expand All @@ -361,7 +385,6 @@ impl BBCode
match_type: MatchType::Simple(Box::new(|_c| String::new()))
});


#[allow(unused_variables)]
{
Self::add_tagmatcher(&mut matches, "b", ScopeInfo::basic(Box::new(|o,b,c| format!("<b>{b}</b>"))), None, None)?;
Expand Down Expand Up @@ -405,7 +428,8 @@ impl BBCode
}

/// Some fancy extra bbcode. Does not include basics! These are nonstandard, you don't have to use them!
pub fn extras() -> Result<Vec<MatchInfo>, Error> {
pub fn extras() -> Result<Vec<MatchInfo>, Error>
{
let mut matches : Vec<MatchInfo> = Vec::new();
Self::add_tagmatcher(&mut matches, "h1", ScopeInfo::basic(Box::new(|_o,b,_c| format!("<h1>{}</h1>",b))), None, None)?;
Self::add_tagmatcher(&mut matches, "h2", ScopeInfo::basic(Box::new(|_o,b,_c| format!("<h2>{}</h2>",b))), None, None)?;
Expand Down

0 comments on commit f2f689d

Please sign in to comment.