Skip to content

Commit

Permalink
Merge pull request #34 from alexcorvi/1.0.0-rc1
Browse files Browse the repository at this point in the history
1.0.0 release
  • Loading branch information
alexcorvi committed Feb 26, 2017
2 parents 8f57ebb + 1d4a0f9 commit d066a3d
Show file tree
Hide file tree
Showing 74 changed files with 7,435 additions and 11,496 deletions.
10 changes: 0 additions & 10 deletions .babelrc

This file was deleted.

3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*
/*/
!/dist-node/
266 changes: 24 additions & 242 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,257 +2,39 @@

A library to convert URLs to a click-able HTML anchor elements

## Features
## [Getting Started, Documentations, Demos and more](http://alexcorvi.github.io/anchorme.js/)

* Highly sensitive.
* produces the least possible false positives if any.
* Skips HTML, so it doesn't break your HTML if it had a URL as an attribute for an element.
* Links with or without protocols.
* Preserve upper and lower case, although when detecting, it's basically case insensitive.
* Checks against full IANA list of TLDs.
* Works with IPs, FTPs, Emails and files.
* Also works when ports are defined.
* Small in size.
* No RegExp involved, very readable and maintainable.
* Supports setting custom attributes with any values.
* Supports checking IPs only, Emails only, or URLs only.
* Helper methods can be used for other purposes.
## What's Included

## Getting Started
* __Sensitivity__: It's Highly sensitive with the least false positives.
- It validates URLs and Emails against full IANA list
- Validates port numbers (if present)
- Validates IP octet numbers (if present)
* __Robustness__:
- Skips HTML, so it doesn't break your HTML if it had a URL as an attribute for an element.
- Links with or without protocols.
- Works with IPs, FTPs, Emails and files.
- Can detect parenthesis and quotation marks as part of the URL or as a surrounding to the URL.
* __Fast__: It's definitely fast! processing H.G. Wells _The Time Machine_ novel with over 1500 URLs inserted at random places takes only 3.5 seconds.
* __Light Weight__: Although it's a feature rich library with a full IANA list included, it's only __6KB__ when minified and gzipped.

### Download

#### File

Download the library from `dist` folder (either `anchorme.js` or `anchorme.min.js`).

#### NPM

Install via NPM: `npm install anchorme`

### Usage

```javascript

var anchorme = require("anchorme"); // if installed via NPM

var someText = "this is a text with a link www.github.com ..";
var result = anchorme(someText);

// You can also pass few options

anchorme(someText,{

// attributes to add to the anchor tags
attributes:[
// can be objects
{
name:"target",
value:"_blank",
},
// or functions
function(obj){
if(obj.reason === "email") return {name:"class",value:"email"};
else return {name:"class",value:"regular-link"}
}
// read below to know more about this
// and other options
],
})

```

## Demo

To test how this library would work for you, head over to [here](http://alexcorvi.github.io/anchorme.js/) to test it.

## Available options

### Truncation

This will convert a long like like this:
https://raw.githubusercontent.com/alexcorvi/anchorme.js/gh-pages/src/tests/hasprotocol.js
to this:
[https://raw.githubusercontent.com/alexcorv...](https://raw.githubusercontent.com/alexcorvi/anchorme.js/gh-pages/src/tests/hasprotocol.js)


**Default Value:** `0` (Won't truncate)

**Example**

```javascript

anchorme(string,{
truncate:40
})

```

### Truncate from the middle

This will make the truncation (as seen above) removing characters from the middle instead of the end. So it will produce a link like this one: [raw.githubusercontent.com/.../hasprotocol.js](https://raw.githubusercontent.com/alexcorvi/anchorme.js/gh-pages/src/tests/hasprotocol.js)

```javascript

anchorme(string,{
truncate:[26,15],
// means 26 characters from the beginning
// and 15 characters from the end
})

```

### Excluding

You can exclude IPs/Emails/URLs/Files like this:

```javascript

anchorme(string,{
emails:false,
urls:false,
ips:false,
files:false
})
// the example above won't do anything to your string
// since you're excluding every possible change
```

**Default Value:** all are `true`



### Adding attributes

You can add attributes to the links produced by anchorme. using the `attributes` prop in the options. this options should be an array of the attributes you'd like to pass.

Values of this array can be:

* Plain objects
```javascript
anchorme(string,{
attributes:[
{
// attribute name
name:"class",
// attribute value
value:"something"
},
{
name:"target",
value:"blank"
}
]
});
```

* Functions that return an object
```javascript
anchorme(string,{
attributes:[
{
name:"class",
value:"link"
},
function(data){
if(data.reason === "ip") return {name:"class",value:"ip-link"};
},
function(data){
if(data.protocol !== "mailto:") return {name:"target",value:"blank"};
// following conditions can also be used:
// if(data.raw.indexOf("@") > 0) return {name:"target",value:"blank"};
// if(data.reason !== "email") return {name:"target",value:"blank"};
}
]
});
```

Where `data` is an object containing detailed info about the link in question. The example above will add `ip-link` class to all the links that are IPs, and add `target='_blank'` to all the links that are not emails.

If you log the data object you'll get something similar to this:

```javascript

{
// the reason this fragment
// was detected
// possible reasons: "file", "url", "ip", "email"
"reason": "email",

// the protocol that the link came with
// or the protocol that was added to the link
"protocol": "mailto:",

// the link (without any modification)
"raw": "[email protected]",

// the encoded version of the link
// i.e. non-Latin characters -> URI encoding
// also doesn't have a protocol (if it came with any)
"encoded": "[email protected]",
}

```

### Setting default protocol

If the link came without protocol, like `www.google.com` then anchorme will add the `http://` by default. However you can set your own default protocol.


```javascript
anchorme(string,{
defaultProtocol:"ftp://",
// ... or anything
})
```

In some cases, you might want the protocol to be set conditionally. Anchorme allows you to pass a function as the `defaultProtocol` and uses whatever this function returns.

```javascript
anchorme(string,{
defaultProtocol:function(url){
// where url is like: "www.google.com"
if(url.indexOf("secure") > 0) return "https://";
else return "http://";
},
})
```


## Additional functionalities

### Listing all valid URLs

Although anchorme was authored to transform URLs in text strings to a click-able HTML anchor tags, passing `true` to `list` property in options will change the library's behavior and instead of returning a text with an HTML tags it will only return an array of valid URLs.

```javascript

anchorme(myText,{
list:true
})

```

### Validating


it can also be used for validation:
## Contributing

```javascript
anchorme.validate.ip("1.1.1.1:3000/something"); // returns true
anchorme.validate.email("[email protected]"); // return true
anchorme.validate.url("google.co.uk"); // returns true
```
This project is written in Typescript and compiled to JavaScript.

## Contributing
### Prerequisites:
- Typescript installed globally
- Jest installed globally (for testing)

### How to contribute
- Clone this repository
- `cd anchorme.js && npm install`
- install mocha globally (for running the tests): `mocha test/run`
- ..
- Build `node build/build`
- Test `node test/run`
- ..
- Add unit tests if needed
- Run `npm run test` for testing
- Run `npm run build` for building

* *
-----

License: The MIT License (MIT) - Copyright (c) 2017 Alex Corvi
70 changes: 70 additions & 0 deletions assets/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
$(function(){
/*!
* JavaScript for Bootstrap's docs (http://getbootstrap.com)
* Copyright 2011-2014 Twitter, Inc.
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
* details, see http://creativecommons.org/licenses/by/3.0/.
*/
!function(a){a(function(){if(navigator.userAgent.match(/IEMobile\/10\.0/)){var b=document.createElement("style");b.appendChild(document.createTextNode("@-ms-viewport{width:auto!important}")),document.querySelector("head").appendChild(b)}{var c=a(window),d=a(document.body);a(".navbar").outerHeight(!0)+10}d.scrollspy({target:".bs-docs-sidebar"}),c.on("load",function(){d.scrollspy("refresh")}),a(".bs-docs-container [href=#]").click(function(a){a.preventDefault()}),setTimeout(function(){var b=a(".bs-docs-sidebar");b.affix({offset:{top:function(){var c=b.offset().top,d=parseInt(b.children(0).css("margin-top"),10),e=a(".bs-docs-nav").height();return this.top=c-e-d},bottom:function(){return this.bottom=a(".bs-docs-footer").outerHeight(!0)}}})},100),setTimeout(function(){a(".bs-top").affix()},100)})}(jQuery);
});


$(function() {
// build side menu
var html = '';

$('.bs-docs-section').each(function() {
var h1 = $(this).find('h1[id]').first(),
h23 = $(this).find('h2[id], h3[id]:not([data-no-menu])');

if (h1.length) {
html += '<li><a href="#' + h1[0].id + '">' + h1.clone().children().remove().end().text() + '</a>';

if (h23.length) {
html += '<ul class="nav">';
h23.each(function() {
html += '<li><a href="#' + this.id + '">' + $(this).clone().children().remove().end().text() + '</a></li>';
});
html += '</ul>';
}

html += '</li>';
}
});

if (html == '') {
$('[role=complementary]').hide();
$('[role=main]').toggleClass('col-md-9 col-md-12');
}
else {
$('.bs-docs-sidenav').html(html);
}

// add heading anchors
$('h1[id], h2[id], h3[id], h4[id], h5[id]').each(function() {
$(this).prepend('<a href="#' + this.id + '" class="anchor-link">§</i>');
});

// enable bootbox
$('[data-bootbox]').on('click', function() {
var $target = $('#' + $(this).data('bootbox'));
bootbox.alert({
title: $target.attr('title'),
message: $target.html(),
size: $(this).data('bootbox-size')
});
});
});

function trianglify(color1, color2, seed) {
var header = $('#content');
var pattern = Trianglify({
width: window.screen.width | header.outerWidth(),
height: header.outerHeight(),
cell_size: 90,
seed: seed,
x_colors: [color1, color2]
});

header.css('background-image', 'url(' + pattern.png() + ')');
}
1 change: 1 addition & 0 deletions assets/style.min.css

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions benchmark/bench.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const fs = require('fs');
const path = require("path");
const anchorme = require(path.join(process.cwd(),"dist-node","index.js")).default;
const bigData = fs.readFileSync(process.cwd()+"/benchmark/big.sample.txt","utf-8");
const t0 = new Date().getTime();
anchorme(bigData);
console.log(new Date().getTime() - t0);
Loading

0 comments on commit d066a3d

Please sign in to comment.