Giter VIP home page Giter VIP logo

sparklemotion / nokogiri Goto Github PK

View Code? Open in Web Editor NEW
6.1K 159.0 900.0 37.04 MB

Nokogiri (鋸) makes it easy and painless to work with XML and HTML from Ruby.

Home Page: https://nokogiri.org/

License: MIT License

Ruby 32.60% Shell 0.20% Java 17.16% C 37.30% HTML 2.53% XSLT 0.05% Yacc 0.18% REXX 0.05% Dockerfile 0.18% Makefile 0.15% Ragel 2.52% C++ 7.07% CSS 0.01% sed 0.01%
ruby nokogiri xml sax ruby-gem xslt xerces libxml2 libxslt

nokogiri's Introduction

Nokogiri

Nokogiri (鋸) makes it easy and painless to work with XML and HTML from Ruby. It provides a sensible, easy-to-understand API for reading, writing, modifying, and querying documents. It is fast and standards-compliant by relying on native parsers like libxml2, libgumbo, and xerces.

Guiding Principles

Some guiding principles Nokogiri tries to follow:

  • be secure-by-default by treating all documents as untrusted by default
  • be a thin-as-reasonable layer on top of the underlying parsers, and don't attempt to fix behavioral differences between the parsers

Features Overview

  • DOM Parser for XML, HTML4, and HTML5
  • SAX Parser for XML and HTML4
  • Push Parser for XML and HTML4
  • Document search via XPath 1.0
  • Document search via CSS3 selectors, with some jquery-like extensions
  • XSD Schema validation
  • XSLT transformation
  • "Builder" DSL for XML and HTML documents

Status

Github Actions CI Appveyor CI

Gem Version SemVer compatibility

CII Best Practices Tidelift dependencies

Support, Getting Help, and Reporting Issues

All official documentation is posted at https://nokogiri.org (the source for which is at https://github.com/sparklemotion/nokogiri.org/, and we welcome contributions).

Reading

Your first stops for learning more about Nokogiri should be:

Ask For Help

There are a few ways to ask exploratory questions:

Please do not mail the maintainers at their personal addresses.

Report A Bug

The Nokogiri bug tracker is at https://github.com/sparklemotion/nokogiri/issues

Please use the "Bug Report" or "Installation Difficulties" templates.

Security and Vulnerability Reporting

Please report vulnerabilities at https://hackerone.com/nokogiri

Full information and description of our security policy is in SECURITY.md

Semantic Versioning Policy

Nokogiri follows Semantic Versioning (since 2017 or so). Dependabot's SemVer compatibility score for Nokogiri

We bump Major.Minor.Patch versions following this guidance:

Major: (we've never done this)

  • Significant backwards-incompatible changes to the public API that would require rewriting existing application code.
  • Some examples of backwards-incompatible changes we might someday consider for a Major release are at ROADMAP.md.

Minor:

  • Features and bugfixes.
  • Updating packaged libraries for non-security-related reasons.
  • Dropping support for EOLed Ruby versions. Some folks find this objectionable, but SemVer says this is OK if the public API hasn't changed.
  • Backwards-incompatible changes to internal or private methods and constants. These are detailed in the "Changes" section of each changelog entry.
  • Removal of deprecated methods or parameters, after a generous transition period; usually when those methods or parameters are rarely-used or dangerous to the user. Essentially, removals that do not justify a major version bump.

Patch:

  • Bugfixes.
  • Security updates.
  • Updating packaged libraries for security-related reasons.

Sponsorship

You can help sponsor the maintainers of this software through one of these organizations:

Installation

Requirements:

  • Ruby >= 3.0
  • JRuby >= 9.4.0.0

If you are compiling the native extension against a system version of libxml2:

  • libxml2 >= 2.9.2 (recommended >= 2.12.0)

Native Gems: Faster, more reliable installation

"Native gems" contain pre-compiled libraries for a specific machine architecture. On supported platforms, this removes the need for compiling the C extension and the packaged libraries, or for system dependencies to exist. This results in much faster installation and more reliable installation, which as you probably know are the biggest headaches for Nokogiri users.

Supported Platforms

Nokogiri ships pre-compiled, "native" gems for the following platforms:

  • Linux:
    • x86-linux and x86_64-linux (req: glibc >= 2.17)
    • aarch64-linux and arm-linux (req: glibc >= 2.29)
    • Note that musl platforms like Alpine are supported
  • Darwin/MacOS: x86_64-darwin and arm64-darwin
  • Windows: x86-mingw32, x64-mingw32, and x64-mingw-ucrt
  • Java: any platform running JRuby 9.4 or higher

To determine whether your system supports one of these gems, look at the output of bundle platform or ruby -e 'puts Gem::Platform.local.to_s'.

If you're on a supported platform, either gem install or bundle install should install a native gem without any additional action on your part. This installation should only take a few seconds, and your output should look something like:

$ gem install nokogiri
Fetching nokogiri-1.11.0-x86_64-linux.gem
Successfully installed nokogiri-1.11.0-x86_64-linux
1 gem installed

Other Installation Options

Because Nokogiri is a C extension, it requires that you have a C compiler toolchain, Ruby development header files, and some system dependencies installed.

The following may work for you if you have an appropriately-configured system:

gem install nokogiri

If you have any issues, please visit Installing Nokogiri for more complete instructions and troubleshooting.

How To Use Nokogiri

Nokogiri is a large library, and so it's challenging to briefly summarize it. We've tried to provide long, real-world examples at Tutorials.

Parsing and Querying

Here is example usage for parsing and querying a document:

#! /usr/bin/env ruby

require 'nokogiri'
require 'open-uri'

# Fetch and parse HTML document
doc = Nokogiri::HTML(URI.open('https://nokogiri.org/tutorials/installing_nokogiri.html'))

# Search for nodes by css
doc.css('nav ul.menu li a', 'article h2').each do |link|
  puts link.content
end

# Search for nodes by xpath
doc.xpath('//nav//ul//li/a', '//article//h2').each do |link|
  puts link.content
end

# Or mix and match
doc.search('nav ul.menu li a', '//article//h2').each do |link|
  puts link.content
end

Encoding

Strings are always stored as UTF-8 internally. Methods that return text values will always return UTF-8 encoded strings. Methods that return a string containing markup (like to_xml, to_html and inner_html) will return a string encoded like the source document.

WARNING

Some documents declare one encoding, but actually use a different one. In these cases, which encoding should the parser choose?

Data is just a stream of bytes. Humans add meaning to that stream. Any particular set of bytes could be valid characters in multiple encodings, so detecting encoding with 100% accuracy is not possible. libxml2 does its best, but it can't be right all the time.

If you want Nokogiri to handle the document encoding properly, your best bet is to explicitly set the encoding. Here is an example of explicitly setting the encoding to EUC-JP on the parser:

  doc = Nokogiri.XML('<foo><bar /></foo>', nil, 'EUC-JP')

Technical Overview

Guiding Principles

As noted above, two guiding principles of the software are:

  • be secure-by-default by treating all documents as untrusted by default
  • be a thin-as-reasonable layer on top of the underlying parsers, and don't attempt to fix behavioral differences between the parsers

Notably, despite all parsers being standards-compliant, there are behavioral inconsistencies between the parsers used in the CRuby and JRuby implementations, and Nokogiri does not and should not attempt to remove these inconsistencies. Instead, we surface these differences in the test suite when they are important/semantic; or we intentionally write tests to depend only on the important/semantic bits (omitting whitespace from regex matchers on results, for example).

CRuby

The Ruby (a.k.a., CRuby, MRI, YARV) implementation is a C extension that depends on libxml2 and libxslt (which in turn depend on zlib and possibly libiconv).

These dependencies are met by default by Nokogiri's packaged versions of the libxml2 and libxslt source code, but a configuration option --use-system-libraries is provided to allow specification of alternative library locations. See Installing Nokogiri for full documentation.

We provide native gems by pre-compiling libxml2 and libxslt (and potentially zlib and libiconv) and packaging them into the gem file. In this case, no compilation is necessary at installation time, which leads to faster and more reliable installation.

See LICENSE-DEPENDENCIES.md for more information on which dependencies are provided in which native and source gems.

JRuby

The Java (a.k.a. JRuby) implementation is a Java extension that depends primarily on Xerces and NekoHTML for parsing, though additional dependencies are on isorelax, nekodtd, jing, serializer, xalan-j, and xml-apis.

These dependencies are provided by pre-compiled jar files packaged in the java platform gem.

See LICENSE-DEPENDENCIES.md for more information on which dependencies are provided in which native and source gems.

Contributing

See CONTRIBUTING.md for an intro guide to developing Nokogiri.

Code of Conduct

We've adopted the Contributor Covenant code of conduct, which you can read in full in CODE_OF_CONDUCT.md.

License

This project is licensed under the terms of the MIT license.

See this license at LICENSE.md.

Dependencies

Some additional libraries may be distributed with your version of Nokogiri. Please see LICENSE-DEPENDENCIES.md for a discussion of the variations as well as the licenses thereof.

Authors

  • Mike Dalessio
  • Aaron Patterson
  • Yoko Harada
  • Akinori MUSHA
  • John Shahid
  • Karol Bucek
  • Sam Ruby
  • Craig Barnes
  • Stephen Checkoway
  • Lars Kanis
  • Sergio Arbeo
  • Timothy Elliott
  • Nobuyoshi Nakada

nokogiri's People

Contributors

benlangfeld avatar craigbarnes avatar dbussink avatar dependabot[bot] avatar ender672 avatar enebo avatar etiennebarrie avatar flavorjones avatar fuzzy-boiii23a avatar headius avatar jbarnette avatar jmhodges avatar jvshahid avatar kares avatar knu avatar larskanis avatar leejarvis avatar marutosi avatar mbklein avatar nobu avatar pmahoney avatar rafbm avatar rubys avatar serabe avatar stevecheckoway avatar tenderlove avatar twalpole avatar ujihisa avatar yob avatar yokolet 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  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

nokogiri's Issues

Documentation overhaul

We might want to write up some docs that present functionality broken down the same way that jQuery's docs do it (which I find totally useful and obvious):

  • core (parsing)
  • selectors
  • attributes
  • traversing
  • manipulation

Seg Faults and Bus Errors with 1.2.3 but not with 1.2.2

I haven't worked out a way to create a simple example of this, but when I tried to use webrat (which requires nokogiri) I found that my existing tests (about 10 test classes run from rake test:integration) when run together (not singly) caused a seg fault or a bus error (this was before I wrote any specific webrat tests).

So as far as I understand Nokogiri shouldn't even be being called. And when I could deduce where the error occurred it was somewhere deep in the rails framework (but suspiciously in an html parsing context). I tried step-debugging the code, but this gave me an error in a different place.

Running on a OSX 10.5.6, Ruby 1.8.6

My workaround was to downgrade nokogiri to 1.2.2

Sorry this wasn't such a useful issue, but maybe you can give me some guidance as to what information could help narrow down the possible cause.

Huge Memory Leak in the Nokogiri::XML::Builder

We’re using the Builder in Babylon to build XML stanzas (XMPP).

After running for a few hours each of our application was gaining a lot of weight… It took some hours to track the memory leaks downs (with Dike), and it seems that it comes from the Nokogiri::XML::Builder.

It seems that all the variables in the context of the caller are “wasted”, not cleaned after execution.

Could that be possible?

Please feel free to contact me if you have any question about this (julien.genestoux AT gmail.com for Gtalk ;) )

Decoding characters?

Hello!

When building a node, it seems that special characters are encoded :

irb(main):004:0> doc = Nokogiri::XML::Document.new
=> <?xml version="1.0"?>

irb(main):005:0> n = Nokogiri::XML::Node.new("toto", doc)
=> <toto/>

irb(main):013:0> n["salut"]= "hum&"
=> "hum&"

irb(main):014:0> doc
=> <?xml version="1.0"?>
<toto salut="hum&amp;"/>

In our application, we actually use a XML Push Parser to parse this content... here is a small bit of the implementtation (see the full implementation here :

def start_element(qname, attributes = [])
  e = Nokogiri::XML::Element.new(qname, @doc)
  add_namespaces_and_attributes_to_node(attributes, e)
  [...]
end
def add_namespaces_and_attributes_to_node(attrs, node) 
  (attrs.size / 2).times do |i|
    name, value = attrs[2 * i], attrs[2 * i + 1]
    node.set_attribute name, value
end

The problem is that the push parser doesn't "unescape" the content of the attributes... and then, when we recreate a new node, these attributes are escaped again. The solution would probabluy be to unescape the content of these attributes before adding them to the node, but I have no idea on how to do this!

Thanks a bunch

odd number of arguments

There seems to be a problem with parsing if the html tags are irregular.
For example, in an iframe tag, if the 'height' attribute is present but
no value is written for it, then an error occurs saying that "odd number
of arguments for hash".
Please suggest a solution for this problem.

xpath does not find nested tags by name

> > fx = Nokogiri::XML)
> > fx.xpath(‘/rdf:RDF/item’)
> > => nil
> > fx.xpath(’rdf:RDF/.each do |tag|
> > p tag.name
> > p xchg.path
> > end
> > “channel”
> > “/rdf:RDF/_1
> > “item”
> > “/rdf:RDF/_2
> > “item”
> > "/rdf:RDF/
3"
> > “item”
> > “/rdf:RDF/*4
> > …

Implement Nokogiri::XML::Node#<=>

Nodes can be compared as to where they are in the document tree. Implementing spaceship would let us sort a node set by appearance in the document.

http://xmlsoft.org/html/libxml-xpath.html#xmlXPathCmpNodes

css attribute conditionals can break

require 'nokogiri'
require 'open-uri'

url = 'http://www.google.com/advanced_search?hl=en'
doc = Nokogiri.parse( open(url).read )

list = [
 'input[@name^="as_"]',  # okay
 'input[@name^= "as_"]', # error
 'input[@name ^="as_"]', # error
 'input[@name ^= "as_"]' # error
]

list.each do | css |
 begin
   doc.search( css )
   puts "#{css} - okay"
 rescue StandardError => e
   puts "#{css} - #{e.message}"
 end
end

adding a non-empty NodeSet raises an obscure error

This code raises a RuntimeError with the message "Could not reparent node (xmlDocCopyNode)":

h = Nokogiri::HTML.parse("<p>sometext</p>")
n = h.at('p')
n.add_next_sibling(n.children)

We should probably pick one of these two things to do instead:

  1. raise an error that says "Hey, dummy, that's a NodeSet, not a Node. We need you to add just n.children[0] through n.children.last one by one with add_next_sibling"
  2. flatten the NodeSet out for the user

Possible missupport of invalid XML attributes

We recently switched from Builder to Nokogiri for XML generation, with big speed improvements.

And now we're looking to update XML reading, however, legacy data has some standard incorrect fields that worked with Rails XmlSimple (which uses REXML) but does not work with Nokogiri. Here is an example:

>> xml = "<dummy><data_multiple><1><name>Bob</name></1><2><name>Joe</name></2></data_multiple></dummy>"
>> XmlSimple.xml_in(xml)
=> {"data_multiple"=>[{"1"=>[{"name"=>["Bob"]}], "2"=>[{"name"=>["Joe"]}]}]}
>> Nokogiri::XML(xml)
=> <?xml version="1.0"?>
<dummy><data_mutiple>1&gt;<name>Bob</name></data_mutiple>1&gt;2&gt;<name>Joe</name></dummy>

Note the <1></1> tags are being escaped and thus breaking things.

I'm not sure if this is excepted behavior, or a parsing issue.

generating a <p> calls Kernel#p when using send

copy/paste/run the following code. should explain itself...

require 'rubygems'
require 'nokogiri'

@builder = Nokogiri::HTML::Builder.new do |doc|
doc.html {
doc.head {
doc.title "FOOBAR"
}
doc.body {
# THIS WORKS LIKE A CHARM
doc.send(:h1, "A", { :class => 'foo'})
# THIS ONLY WORKS IF I 'undef p' FIRST
doc.send(:p, "B", { :class => 'bar'})
}
}
end

puts @builder.doc

Requiring Nokogiri 1.2.3 under JRuby 1.2 does not load

$ cat test.rb
require "rubygems"
require "nokogiri"

doc = Nokogiri::HTML(File.read(ARGV[0]))
p doc

$ jruby -w test.rb data.html
/Users/francois/Library/Java/JRuby/jruby-1.2.0/lib/ruby/gems/1.8/gems/nokogiri-1.2.3-java/lib/nokogiri/xml/node.rb:180: undefined method next_sibling' for classNokogiri::XML::Node' (NameError)
from /Users/francois/Library/Java/JRuby/jruby-1.2.0/lib/ruby/gems/1.8/gems/nokogiri-1.2.3-java/lib/nokogiri/xml/node.rb:31:in require' from /Users/francois/Library/Java/JRuby/current/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:inrequire'
from /Users/francois/Library/Java/JRuby/jruby-1.2.0/lib/ruby/gems/1.8/gems/nokogiri-1.2.3-java/lib/nokogiri/xml.rb:3
from /Users/francois/Library/Java/JRuby/jruby-1.2.0/lib/ruby/gems/1.8/gems/nokogiri-1.2.3-java/lib/nokogiri/xml.rb:31:in require' from /Users/francois/Library/Java/JRuby/current/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:inrequire'
from /Users/francois/Library/Java/JRuby/jruby-1.2.0/lib/ruby/gems/1.8/gems/nokogiri-1.2.3-java/lib/nokogiri.rb:10
from /Users/francois/Library/Java/JRuby/jruby-1.2.0/lib/ruby/gems/1.8/gems/nokogiri-1.2.3-java/lib/nokogiri.rb:36:in require' from /Users/francois/Library/Java/JRuby/current/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:inrequire'
from test.rb:2

$ jruby -S gem list -l nokogiri

*** LOCAL GEMS ***

nokogiri (1.2.3)

$ jruby --version
jruby 1.2.0 (ruby 1.8.6 patchlevel 287) (2009-03-16 rev 9419) [i386-java]

recycled object error

frequently getting the following error when running on MRI FFI:

/home/mike/code/nokogiri/test/helper.rb:11: libxml version info:     {"nokogiri"=>"1.2.4", "warnings"=>[], "libxml"=>{"platform"=>"ruby",     "binding"=>"ffi", "loaded"=>"2.6.31"}}
Loaded suite -e
Started
...
Finished in 3.285882 seconds.

  1) Error:
test_attribute_roundtrip(TestReader):
RangeError: 0xdb7eb02a is recycled object
    /home/mike/code/nokogiri/lib/nokogiri/ffi/structs/common_node.rb:11:in     `_id2ref'
    /home/mike/code/nokogiri/lib/nokogiri/ffi/structs/common_node.rb:11:in     `ruby_node'
    /home/mike/code/nokogiri/lib/nokogiri/ffi/xml/node.rb:252:in     `wrap'
    /home/mike/code/nokogiri/lib/nokogiri/ffi/xml/node.rb:107:in     `attribute_nodes'
    /home/mike/code/nokogiri/lib/nokogiri/ffi/xml/reader.rb:42:in     `attribute_nodes'
    /home/mike/code/nokogiri/lib/nokogiri/xml/reader.rb:52:in     `attributes'
    ./test/test_reader.rb:142:in `test_attribute_roundtrip'
    /home/mike/code/nokogiri/lib/nokogiri/xml/reader.rb:61:in `call'
    /home/mike/code/nokogiri/lib/nokogiri/xml/reader.rb:61:in `each'
    ./test/test_reader.rb:141:in `test_attribute_roundtrip'

544 tests, 1367 assertions, 0 failures, 1 errors
rake aborted!
Command failed with status (1): [/usr/bin/ruby1.8 -w     -Ilib:ext:bin:test -e ...]

Add html tag lookup

Add html tag information lookup. We should be able to look up html tag information.

http://xmlsoft.org/html/libxml-HTMLparser.html#htmlTagLookup

<ignore>

i wish i could delete this ticket

replace memcpy with AbstractMemory#put_bytes() in FFI implementation

From Wayne Meissner:

I noticed in nokogiri, in Document.read_io that you use LibXML.memcpy to transfer data from a ruby string to a native memory buffer.

It'll be much faster to use AbstractMemory#put_bytes(), as the memcpy mapping will triple copy the string data on JRuby.

basically, what happens behind the scene is:

  1. The string data is copied to a temporary native memory buffer
  2. The temp memory is passed as the parameter
  3. memcpy copies the data from the temp memory to the destination memory you specified
  4. The temporary native memory is copied back to the ruby string.

compared to put_bytes:

  1. The string data is copied once from the ruby byte array backing the ruby string into the destination memory address.
  2. There is no step 2.

For large files, this might make a difference.

reparenting an unlinked node results in double-free

this code, run under valgrind, demonstrates:

doc = Nokogiri::XML <<-EOHTML
<root>
 <a>
   <b/>
 </a>
</root>
EOHTML

root = doc.at("root")
a = root.at("a")
b = a.at("b")
a.add_next_sibling(b.unlink)

puts doc.to_s

NodeSet#dup should work

NodeSet#dup is broken. The duplicate set should contain the same nodes as the duplicated set.

Nokogiri::XML::NodeSet << operator refuses to add Nokogiri::XML::Elements

I've got two nodesets. When I try:

nodeset1 << nodeset2

... Nokogiri laughs at me with:

ArgumentError: node must be a Nokogiri::XML::Node
    from (irb):29:in `<<'
    from (irb):29
    from :0

Ironically, the elements of a NodeSet are Nokogiri::XML::Elements, which is just an empty subclass of Nokogiri::XML::Node.

It looks like the offending bit is line 52 of xml_node_set.c:

static VALUE push(VALUE self, VALUE rb_node)
{
  xmlNodeSetPtr node_set;
  xmlNodePtr node;

  if(! rb_funcall(rb_node, rb_intern("is_a?"), 1, cNokogiriXmlNode)) // <-- THIS ONE
    rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");

  Data_Get_Struct(self, xmlNodeSet, node_set);
  Data_Get_Struct(rb_node, xmlNode, node);
  xmlXPathNodeSetAdd(node_set, node);
  return self;
}

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.