Giter Club home page Giter Club logo

dominantcolor's Introduction

CocoaMarkdown

Markdown parsing and rendering for iOS and macOS

CocoaMarkdown is a cross-platform framework for parsing and rendering Markdown, built on top of the C reference implementation of CommonMark.

Why?

CocoaMarkdown aims to solve two primary problems better than existing libraries:

  1. More flexibility. CocoaMarkdown allows you to define custom parsing hooks or even traverse the Markdown AST using the low-level API.
  2. Efficient NSAttributedString creation for easy rendering on iOS and macOS. Most existing libraries just generate HTML from the Markdown, which is not a convenient representation to work with in native apps.

Example app macOS

Example app iOS

Installation

First you will want to add this project as a submodule to your project:

git submodule add https://github.com/indragiek/CocoaMarkdown.git

Then, you need to pull down all of its dependencies.

cd CocoaMarkdown
git submodule update --init --recursive

Next, drag the .xcodeproj file from within CocoaMarkdown into your project. After that, click on the General tab of your target. Select the plus button under "Embedded Binaries" and select the CocoaMarkdown.framework.

API

Traversing the Markdown AST

CMNode and CMIterator wrap CommonMark's C types with an object-oriented interface for traversal of the Markdown AST.

let document = CMDocument(contentsOfFile: path, options: [])
document.rootNode.iterator().enumerateUsingBlock { (node, _, _) in
    print("String value: \(node.stringValue)")
}

Building Custom Renderers

The CMParser class isn't really a parser (it just traverses the AST), but it defines an NSXMLParser-style delegate API that provides handy callbacks for building your own renderers:

@protocol CMParserDelegate <NSObject>
@optional
- (void)parserDidStartDocument:(CMParser *)parser;
- (void)parserDidEndDocument:(CMParser *)parser;
...
- (void)parser:(CMParser *)parser foundText:(NSString *)text;
- (void)parserFoundHRule:(CMParser *)parser;
...
@end

CMAttributedStringRenderer is an example of a custom renderer that is built using this API.

Rendering Attributed Strings

CMAttributedStringRenderer is the high level API that will be useful to most apps. It creates an NSAttributedString directly from Markdown, skipping the step of converting it to HTML altogether.

Going from a Markdown document to rendering it on screen is as easy as:

let document = CMDocument(contentsOfFile: path, options: [])
let renderer = CMAttributedStringRenderer(document: document, attributes: CMTextAttributes())
textView.attributedText = renderer.render()

Or, using the convenience method on CMDocument:

textView.attributedText = CMDocument(contentsOfFile: path, options: []).attributedStringWithAttributes(CMTextAttributes())

HTML elements can be supported by implementing CMHTMLElementTransformer. The framework includes several transformers for commonly used tags:

Transformers can be registered with the renderer to use them:

let document = CMDocument(contentsOfFile: path, options: [])
let renderer = CMAttributedStringRenderer(document: document, attributes: CMTextAttributes())
renderer.registerHTMLElementTransformer(CMHTMLStrikethroughTransformer())
renderer.registerHTMLElementTransformer(CMHTMLSuperscriptTransformer())
textView.attributedText = renderer.render()

Customizing Attributed strings rendering

All attributes used to style the text are customizable using the CMTextAttributes class.

Every Markdown element type can be customized using the corresponding CMStyleAttributes property in CMTextAttributes, defining 3 different kinds of attributes:

  • String attributes, i.e. regular NSAttributedString attributes
  • Font attributes, for easy font setting
  • Paragraph attributes, relevant only for block elements

Attributes for any Markdown element kind can be directly set:

let textAttributes = CMTextAttributes()
textAttributes.linkAttributes.stringAttributes[NSAttributedString.Key.backgroundColor] = UIColor.yellow

A probably better alternative for style customization is to use grouped attributes setting methods available in CMTextAttributes:

let textAttributes = CMTextAttributes()

// Set the text color for all headers
textAttributes.addStringAttributes([ .foregroundColor: UIColor(red: 0.0, green: 0.446, blue: 0.657, alpha: 1.0)], 
                                   forElementWithKinds: .anyHeader)

// Set a specific font + font-traits for all headers
let boldItalicTrait: UIFontDescriptor.SymbolicTraits = [.traitBold, .traitItalic]
textAttributes.addFontAttributes([ .family: "Avenir Next" ,
                                   .traits: [ UIFontDescriptor.TraitKey.symbolic: boldItalicTrait.rawValue]], 
                                 forElementWithKinds: .anyHeader)
// Set specific font traits for header1 and header2
textAttributes.setFontTraits([.weight: UIFont.Weight.heavy], 
                             forElementWithKinds: [.header1, .header2])

// Center block-quote paragraphs        
textAttributes.addParagraphStyleAttributes([ .alignment: NSTextAlignment.center.rawValue], 
                                           forElementWithKinds: .blockQuote)

// Set a background color for code elements        
textAttributes.addStringAttributes([ .backgroundColor: UIColor(white: 0.9, alpha: 0.5)], 
                                   forElementWithKinds: [.inlineCode, .codeBlock])

List styles can be customized using dedicated paragraph style attributes:

// Customize the list bullets
textAttributes.addParagraphStyleAttributes([ .listItemBulletString: "๐Ÿ" ], 
                                           forElementWithKinds: .unorderedList)
textAttributes.addParagraphStyleAttributes([ .listItemBulletString: "๐ŸŒผ" ], 
                                           forElementWithKinds: .unorderedSublist)

// Customize numbered list item labels format and distance between label and paragraph
textAttributes.addParagraphStyleAttributes([ .listItemNumberFormat: "(%02ld)", 
                                             .listItemLabelIndent: 30 ],    
                                           forElementWithKinds: .orderedList)

Font and paragraph attributes are incremental, meaning that they allow to modify only specific aspects of the default rendering styles.

Additionally on iOS, Markdown elements styled using the font attributes API get automatic Dynamic-Type compliance in the generated attributed string, just like default rendering styles.

Rendering HTML

CMHTMLRenderer provides the ability to render HTML from Markdown:

let document = CMDocument(contentsOfFile: path, options: [])
let renderer = CMHTMLRenderer(document: document)
let HTML = renderer.render()

Or, using the convenience method on CMDocument:

let HTML = CMDocument(contentsOfFile: path).HTMLString()

Example Apps

The project includes example apps for iOS and macOS to demonstrate rendering attributed strings.

Contact

License

CocoaMarkdown is licensed under the MIT License. See LICENSE for more information.

dominantcolor's People

Contributors

1amageek avatar bdaz avatar boyvanamstel avatar dagronf avatar dimohamdy avatar edwellbrook avatar indragiek avatar jamalk avatar jernejstrasner avatar marcelofabri avatar metasmile avatar mikezucc avatar mviamari avatar odeke-em avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dominantcolor's Issues

Compiles fine in Simulator but doesn't compile on iPhone 7 Plus device?

I'm using your code in my Swift 3 app and it works fine in the simulator but when I try to run it on my 7 Plus device, it doesn't compile, complaining that value of UIImage has no member dominantColors.

The weird thing is running your project as a stand-alone works fine on my device.

Xcode does see the DominantColor framework when I try to import it using import DominantColor, so I'm really at a lost.

Any clues?

Are results meant to be stable?

When I sample the same image multiple times I get very different results:

Something like:

            let c1 = image.dominantColors()
            let c2 = image.dominantColors()
            let c3 = image.dominantColors()

            print(c1)
            print(c2)
            print(c3)

Results in quite different colors:

[NSCustomColorSpace Device RGB colorspace 0.601163 0.451928 0.29805 1, NSCustomColorSpace Device RGB colorspace 0.167657 0.346547 0.366693 1, NSCustomColorSpace Device RGB colorspace 0.932639 0.899493 0.844565 1, NSCustomColorSpace Device RGB colorspace 0.300963 0.190313 0.13295 1, NSCustomColorSpace Device RGB colorspace 0.209064 0.370543 0.368402 1, NSCustomColorSpace Device RGB colorspace 0.959817 0.783332 0.505265 1, NSCustomColorSpace Device RGB colorspace 0.866478 0.734177 0.559615 1, NSCustomColorSpace Device RGB colorspace 0.80283 0.586079 0.331463 1, NSCustomColorSpace Device RGB colorspace 0.145703 0.320739 0.346772 1, NSCustomColorSpace Device RGB colorspace 0.221972 0.415689 0.443135 1, NSCustomColorSpace Device RGB colorspace 0.737809 0.513082 0.260469 1, NSCustomColorSpace Device RGB colorspace 0.281155 0.455335 0.465255 1, NSCustomColorSpace Device RGB colorspace 0.221931 0.405273 0.408174 1, NSCustomColorSpace Device RGB colorspace 0.21869 0.409611 0.429996 1, NSCustomColorSpace Device RGB colorspace 0.234584 0.400131 0.392035 1, NSCustomColorSpace Device RGB colorspace 0.21333 0.391863 0.38884 1]
[NSCustomColorSpace Device RGB colorspace 0.179195 0.35601 0.368129 1, NSCustomColorSpace Device RGB colorspace 0.221092 0.394226 0.392182 1, NSCustomColorSpace Device RGB colorspace 0.731796 0.527369 0.303106 1, NSCustomColorSpace Device RGB colorspace 0.900029 0.709735 0.447639 1, NSCustomColorSpace Device RGB colorspace 0.899187 0.828078 0.731685 1, NSCustomColorSpace Device RGB colorspace 0.981269 0.937817 0.851738 1, NSCustomColorSpace Device RGB colorspace 0.563752 0.426373 0.29075 1, NSCustomColorSpace Device RGB colorspace 0.380421 0.251262 0.160972 1, NSCustomColorSpace Device RGB colorspace 0.144352 0.32968 0.356929 1, NSCustomColorSpace Device RGB colorspace 0.243707 0.430158 0.451196 1, NSCustomColorSpace Device RGB colorspace 0.587503 0.488635 0.360218 1, NSCustomColorSpace Device RGB colorspace 0.159995 0.325696 0.34995 1, NSCustomColorSpace Device RGB colorspace 0.2791 0.162244 0.11213 1, NSCustomColorSpace Device RGB colorspace 0.215359 0.141883 0.117462 1, NSCustomColorSpace Device RGB colorspace 0.21733 0.40994 0.436859 1, NSCustomColorSpace Device RGB colorspace 0.141187 0.325496 0.352944 1]
[NSCustomColorSpace Device RGB colorspace 0.220951 0.405691 0.415336 1, NSCustomColorSpace Device RGB colorspace 0.169029 0.349393 0.370444 1, NSCustomColorSpace Device RGB colorspace 0.927746 0.764487 0.524068 1, NSCustomColorSpace Device RGB colorspace 0.938916 0.901397 0.843266 1, NSCustomColorSpace Device RGB colorspace 0.162621 0.338714 0.355336 1, NSCustomColorSpace Device RGB colorspace 0.289514 0.169255 0.111449 1, NSCustomColorSpace Device RGB colorspace 0.530895 0.42339 0.305094 1, NSCustomColorSpace Device RGB colorspace 0.645131 0.485872 0.323021 1, NSCustomColorSpace Device RGB colorspace 0.725126 0.511703 0.278788 1, NSCustomColorSpace Device RGB colorspace 0.812128 0.594165 0.335176 1, NSCustomColorSpace Device RGB colorspace 0.198869 0.375221 0.376283 1, NSCustomColorSpace Device RGB colorspace 0.260764 0.208588 0.180555 1, NSCustomColorSpace Device RGB colorspace 0.412618 0.265703 0.16161 1, NSCustomColorSpace Device RGB colorspace 0.51031 0.32944 0.17197 1, NSCustomColorSpace Device RGB colorspace 0.583589 0.607618 0.549271 1, NSCustomColorSpace Device RGB colorspace 0.289885 0.460979 0.465333 1]

Sorting more and grouping each results by hue representativeness or similarity is needed.

First of all, Thank you for your nice work! Awesome.
But in general case, library users finally needs only 1~2 color groups like primary, secondary or background(outbound) colors. Currently the result seems that in each 2 items are pretty similar. Also in this example https://github.com/indragiek/DominantColor/raw/master/mac.png, I think first color is not dominant color, it may be secondary or background with the last color.

Currently you did perform it by "size" like following.

// Sort the clusters by size in descending order so that the
// most dominant colors come first.
 clusters.sortInPlace { $0.size > $1.size }

Are you have some plans to improve? Or, please let me know some hints or important parts of your lib.

Thanks.

Platform specific extensions

Extensions to UIImage on iOS and NSImage on Mac to make it easier to use without having to manually create a CGImage.

Framework targets

Framework targets for iOS and Mac for the reusable parts of the project.

Does CIE2000 have high cost?

I have own implementation for CIE76 and CIE2000.

For 5,000 samples, it take 10times than CIE76 in my computer.

Does CIE2000 is expensive calculation? I am not sure that i make correctly or not.
Plz someone comment this issue!

Benchmark C implementation of k-means

Some numbers from the existing Swift implementation:

n = 100 averaged 4 ms
n = 1000 averaged 39 ms
n = 2000 averaged 74 ms
n = 5000 averaged 187 ms
n = 10000 averaged 384 ms

(2.3GHz i7, 2012 rMBP)

iOS App

iOS app for testing the algorithm.

Figure out why memoization of RGB -> LAB is slow

For the same image, using -Os optimization level:

Unmemoized

n = 100 averaged 4 ms
n = 1000 averaged 39 ms
n = 2000 averaged 81 ms
n = 5000 averaged 202 ms
n = 10000 averaged 416 ms

Memoized

n = 100 averaged 8 ms
n = 1000 averaged 68 ms
n = 2000 averaged 133 ms
n = 5000 averaged 318 ms
n = 10000 averaged 639 ms

Roughly twice as slow with memoization.

Unit tests

  • K-means
  • RGB <-> LAB
  • CIE 2000
  • Complete tests with reference images

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.