Coder Social home page Coder Social logo

nimibook's Introduction

nimibook

nimibook is a port of mdbook to Nim, powered by nimib. Nimibook allows to create a nice looking book from nim code and markdown, making sure that nim code is running correctly and being able to incorporate code outputs in the final book. An example book is nimibook documentation.

mdBook is a command line tool and Rust crate to create books using Markdown (as by the CommonMark specification) files. It's very similar to Gitbook, which is a command line tool (and Node.js library) for building beautiful books using GitHub/Git and Markdown (or AsciiDoc).

nimib is a Nim library to convert your Nim code and its outputs to html documents. The html output can be easily customized thanks to nim-mustache, and this is what allows it to use it to build nimibook. nimib documents are normal nim files which use nimib library to produce an output document.

One particular advantage of nimib is that it can incorporate interactive content taking advantage of nim's js backend. For the basic examples see nimib interactivity doc.

The Markdown dialect supported by both nimib and nimibook is the subset of Github Flavored Markdown provided by nim-markdown. For a quick reference of supported syntax see this cheatsheet (created with nimib).

Status

Nimibook is actively maintained (target issues for 2023) and it provides the basic functionality needed to create a book with markdown and nimib sources. It still has some features missing from mdbook (see this issue).

To follow up on recent changes check the changelog.md.

Example sites using nimibook

You are welcome to open a PR and add your site using nimibook here.

Features

  • table of contents in a collapsible sidebar
  • five themes (Light, Rust, Coal, Navy, Ayu)
  • buttons to next/previous pages
  • build multiple files in parallel
  • (optional) latex content with katex
  • (optional) link to github repo
  • (optional) link to track analytics with plausible analytics

Installation

To install Nimibook: nimble install nimibook

How to setup your book with nimibook

Nimibook does not (yet) provides an executable to manage your book, but it provides the basic building blocks to write your own.

1. example nbook.nim: in a folder of your choice create a nbook.nim file with the following content:

import nimibook

var book = initBookWithToc:
  entry("Preface", "preface.md", numbered = false)
  entry("Introduction", "intro.md")
  section("Chapter 1", "chapter1/index.nim"):
    entry("Content", "content.nim")
    draft("Nothing yet")
    section("Sub chapter", "no_ext"):
      entry("and some more content", "more.md")

nimibookCli(book)

2. write a TOC: modify nbook.nim to specify the planned Table of Content (TOC) for your book.

3. nbook init: running nim r nbook init (or compile nbook and run nbook init) will set up the book with:

  • a nimib.toml that contains the default configuration for the book
  • a book folder that contains sources for all chapters mentioned in the TOC. Note that .nim files already contain default nimib content to be used in nimibook.
  • a docs folder that contains static assets for the book and that will contain the built book

4. nbook build: run nim r nbook build to build the book. Open any .html file in docs folder to navigate your book.

5. create your content and enjoy!: now you are ready to start creating content in your sources and publish your book.

See nimibook documentation for more details.

Contribute

You are more than welcome to contribute!

  • We usually have some open issues of stuff we need to fix or we would like to do.
  • You have an overview of the code base in src/readme.md
  • The CI is setup to run tests and publish a document PR preview (click on details on the Netlify preview task once it's green), so that we can all check the changes directly from the PR.
  • You should also test and build the book locally, there are nimble tasks to help with that (run nimble tasks for the list).
  • If the feature can be tested with a unit test, make sure to add one.
  • Once you make a change, remember to document your changes in the appropriate place in the docs.
  • If you add a module, remember to update the code guide.
  • bump the version (usually a patch increment) so that we can immediately tag and release your contribution.
  • Make sure that the title of your PR is clear and edit the initial message with a few short sentences that will be added to the changelog once we release.

Analytics

This website is tracking analytics with plausible.io, a lightweight and open-source website analytics tool with no cookies and fully compliant with GDPR, CCPA and PECR. Analytics for this website are publicly available here. You can opt out from analytics tracking with standard ad-blocking or typing localStorage.plausible_ignore=true in browser console.

nimibook's People

Contributors

beef331 avatar clonkk avatar dsrw avatar hugogranstrom avatar moigagoo avatar philippmdoerner avatar pietroppeter 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

nimibook's Issues

add path option to cli

a path option to cli would allow to restrict command such as build or clean to a specific folder.
we could actually go further and be able to support wildcard (only book/myfolder/files_that_start_like_these*).

for discussion generating this see #20

[RFC] How to deploy Nimibook ?

How to deploy Nimibook ?

Basically how to deal with 2 scenarios :

  • I have existing documentation I want to migrate.
  • I want to create a new book from scratch.

Some possible solutions :

  • Create a new repo using the template feature of github. This requires creating a new repository "from scratch" and do not work outside of Github.
  • Copy & Paste File. This means future evolution of the docs folders (js, fonts, FontAwesome, css) and the mustache files will have to be updated manually.
  • Have a proc generateEmptyBook that copy latest docs folder and mustache files from latest Nimibook version. This requires to deploy docs and book with Nimble meaning we'll probably need to flatten the repository (or Nimble will complain) and the proc itself will probably differ between OS's (so added maintenance complexity ?).

So far, I don't see an "ideal" solution.

What do you think ?

Suggestions

I've used nimibook for a project recently (frogcap.com) and I liked it quite a bit.

I had a few ideas that I think could be valuable additions. I'd be happy to try and work on some of these at some point if any of these ideas would be accepted.

  1. Have the option to hide the numbers in the table of contents.
  2. Have the option to not generate a page for a given section heading or maybe even do this by default if some content or argument is missing.
  3. Easier custom favicon or better documentation if one exists. I gave up figuring out how to add a custom favicon.
  4. Have more control over the window titles. Especially the index.html files.
  5. Be able to insert the TOC with links into pages. Like this https://github.com/badboy/mdbook-toc
  6. Translate links to other pages into a valid link in the html output. Be able to do something like [Link](./relative-path).

document recent changes and release 0.3

document recent changes done in #50:

  • add latex support with latex as in nimib
  • document changes
    • refactoring and code structure (review)
    • templates
    • book.json
    • new nb/doc object in Book
    • blocks context in document.mustache
    • refactored Book.book_title into Book.title. Overrides previously existing Book.title which was supposed to be used for the Chapter title
    • cfg stuff
    • note that changes also fix #48 (you should be able to change name of book folder)
    • removed book.path_to_root (it is a document/chapter thing)
    • remove rootfolder in toc and path field in Toc
    • improved init
    • remove default parameters and allow to pass parameters to build
  • after nimib 0.3 is released, change nimib dep and release this as 0.3

other improvements (next version):

  • add nim code highlighting when starting from md file?
  • improve clean? (maybe open an issue)
    • add a dry-run option
    • add keepSrc, keepOut, keepSrcDefaults, keepOutDefaults
  • support part title in toc
  • support SUMMARY.md
    • a default summary.md should be initialized
  • provide nbook binary!
  • dumped book.json (now a public api) should not contain cfgDir and it should only contain relative dirs
  • quit failures for check and build should be only in cli? (useful for test?)

notes:

  • cfgDir should be set as currentDir of nbook
  • do I need also a srcDirRel and homeDirRel?
  • I am removing srcDir from all entry paths
  • srcDir and homeDir always assumed to be relative to cfgDir and always used as string. (maybe nimib should be like that)
  • srcDir and homeDir should really be relative strings...
  • decided indeed that srcDir and homeDir kept as string relative to cfgDir
  • starting to call use outDir instead of homeDir more and more often... (should I change in nimib?)

Cannot Open Markdown Files

After looking at the nimibook documentation I would expect this to work:

I have a project directory that looks like this:

├── book
│   └── index.md
├── nbook
└── nbook.nim

The nbook.nim file looks like this:

import nimibook

var book = newBookFromToc("nimibook", "book"):
  entry("Introduction", "index.md")

nimibookCli(book)

When I try to build this, I get this error: Error: unhandled exception: cannot open: book/page.md [IOError]

This seems like it might be a bug or like it would be helpful to explain in the documentation.

[NimiBoost] Can't compile files individually because of `book.json`

When trying to get individual pages of a NimiBook to run in preview mode in NimiBoost I stumbled upon this problem: here in useNimibook it loads book.json which doesn't unless run using the publishing mechanics of NimiBook's CLI. It is on top of that removed after generating the book so reusing it after a first run isn't possible either:

cleanjson book

The idea of the preview mode is to focus on the content more than the layout so it doesn't really need any NimiBook functionality to run at all. It can just show every page as the default Nimib theme. So for me yet another commandline switch to disable all NimiBook functionality would work for me (I think). It's just a matter of inserting a when not defined(skipNimibook) in nbUseNimibook.

What do you think? Is there another way to do it?

provide a nbook/nimibook binary

  • this library when installed should also build a binary (called either nbook or nimibook)
  • the binary provides all the functionalities needed to build your book
  • this feature depends on the support of SUMMARY.md, see #62

Indentation of entries in sidebar in generated HTML is incorrect after sub-sections

Given this nbook:

import nimibook

var book = initBookWithToc:
  entry("Should Be 1.", "book/bla.nim")
  section("Should be 2", "book/internals.nim"):    
    section("Should be 2.1", "internals/adders.nim"):
      entry("Should be 2.1.1", "adders/one_adder.nim")

  entry("Should be 3.", "CONTRIBUTING.md")
nimibookCli(book)

Running these commands:

nimble install -y nimib@#head nimibook@#head
nim c -d:release --mm:refc nbook.nim
./nbook init
./nbook build

Generates this Sidebar:
image

The numbering is correct, but the indentation isn't.
The indentation implies that "Should be 3" is a sub-entry of the section "Should be 3" instead of a sibling entry.

I assume the logic that generates HTML only goes back one indentation level instead of determining the correct indentation level.

feature: a show source button or similar

  • not a feature that is present in original mdbook but it is something which makes a lot of sense: the idea is to have a way to directly show the source code of the page as we do in nimib
  • since this is not native in mdbook what needs to be decided is how this elements should appear in the interface: a button? where?

IOError during nbook build, search for html file in docs instead of book

I am trying to build a single-page book.

Error output (truncated log)

nim c -r -d:release nbook.nim build
[...]
[nimib] current directory: /home/kolmogorov/Documents/dev/algoMathBroRemy
[nimib] saving file: book/LogisticSequenceAndChaos.html
entries.nim(14)          check
Error: unhandled exception: Error finding docs/LogisticSequenceAndChaos.html : no such file or directory [IOError]
Error: execution of an external program failed: '/home/kolmogorov/Documents/dev/algoMathBroRemy/nbook build'

My machine

OS: Archlinux

nim -v
Nim Compiler Version 1.7.3 [Linux: amd64]
Compiled at 2022-10-01
Copyright (c) 2006-2022 by Andreas Rumpf

git hash: 96c5586d030a97d9da2f08b2faacad8d34ebd2e4
active boot switches: -d:release
nimble list -i --ver
nimib  [0.3.1, 0.3.2, #head]
nimibook  [0.2.1, #head]

Book index

import nimibook

var book = newBookFromToc("Nim for mathematical problems", "book"):
  # section("Dummy", "index"): 
  entry("Logistic Sequences And Chaos", "LogisticSequenceAndChaos.nim")

# access to nimibook cli which will allow to build the book
nimibookCli(book)

Book page ("LogisticSequenceAndChaos.nim")

import std/[strutils, sequtils, strformat]
import nimib, nimibook
import plotly
import chroma

nbInit(theme = useNimibook)

nbText:"""
# Logistic Sequences and Chaos
"""

nbCode:
  var colors = @[Color(r:0.9, g:0.4, b:0.0, a: 1.0),
                 Color(r:0.9, g:0.4, b:0.2, a: 1.0),
                 Color(r:0.2, g:0.9, b:0.2, a: 1.0),
                 Color(r:0.1, g:0.7, b:0.1, a: 1.0),
                 Color(r:0.0, g:0.5, b:0.1, a: 1.0)]
  var d = Trace[int](mode: PlotMode.LinesMarkers, `type`: PlotType.Scatter)
  var size = @[16.int]
  d.marker =Marker[int](size:size, color: colors)
  d.xs = @[1, 2, 3, 4, 5]
  d.ys = @[1, 2, 1, 9, 5]
  d.text = @["hello", "data-point", "third", "highest", "<b>bold</b>"]

  var layout = Layout(title: "testing", width: 1200, height: 400,
                      xaxis: Axis(title:"my x-axis"),
                      yaxis:Axis(title: "y-axis too"), autosize:false)
  var p = Plot[int](layout:layout, traces: @[d])
  # p.show()

nbSave

Additionnal informations / remarks

This is not very minimal as a MWE (Minimal non Working Example), but I'll reduce the code size when I have more clue why the html has not been generated under the docs folder.

Debug builds

As it is now nimiBook will always run the files in -d:release mode (

args = ["r", "-d:release", "-f", "--verbosity:0", "--hints:off", entry.path]
), but it also means that if a program fails to run we don't get any useful stacktraces or debugging information. This is especially cumbersome in a CI where it just tells you that it has failed, but not what have failed. So having the option to build in debug-mode would be very useful. My current workaround is changing the linked line manually on my local installation, but that's not a feasible solution.

Proposed solutions:

  • Add a buildDebug cmd argument to the CLI. (in addition to init, build, clean etc)
  • If the CLI itself is compiled with -d:debug, then the files it compiles should also be compiled with -d:debug.

Any thoughts on this?

CI broken, nimble file is not updated

not sure why but nimble file is not updated correctly in CI.
to be sure I added a cat nimibook.nimble in CI and the nimble file it is different from the one in main branch.
this leads to a failure since the new jsony dependence is not installed.

GitHub repo icon missing

Not sure why, but we lost the GitHub repo icon. At a first look code looks fine: repo url is set in nbook, should be dumped in book.json, should be loaded in useNimibook and put in the context.

Book.json as a build output

Book.json I think should be moved as an output to docs and I think it should be kept as a build output (not cleaned at the end of build, committed in gh-pages). It can be thought as a static api for the whole book. Thoughts?

rename nimiBook to nimibook

this is a small thing but it kind of bothers me. the name was nimiBook as a calque of mdBook, but then I do not like that I have nimiBook.nimble files, hence the renaming. I guess this might be a bit bothering since we will have to change the remoteUrl of git repo (not sure what happens to the forks), so I figure I ask before proceeding. Thoughts @Clonkk, @HugoGranstrom?

release 0.1

I guess it makes sense to wait a moment for other small bugs/changes before tagging the 0.1.

improve clean command

in recent PR #56 clean command has been reduced to only clean the output folder.
it could still use some improvements:

  • add a dry-run option
  • how to cleanup automatically logs?
  • support the keep parameter taking values from nimibook config (so that we can avoid cleaning specific files in output folder
  • should we reintroduce an option to perform again cleaning of source folder? (we would need keep to support source folder also)

book.json should only contain relative dirs

now that book.json is in docs (so it is published with the book and represents a static api) we should make sure that no absolute dirs are present inside. They should all be relative to cfgDir

next/previous

should be rather straightforward to implement:

  • looking at document.mustache starting from this line but also in a later section we need to provide (if relevant) a next or previous object with a link field inside the context (or maybe we can simplify and provide next and previous fields directly as link, do not see why the need for a more complex object).
  • this next and previous links must be generated in nimibook.docs while processing the toc

Allow embedding a nim file as an nbCode block

This came to me while writing on the owlkettle nimibook.

Owlkettle has a bunch of example.nim files for example applications for individual widgets.
I would love to be able to embed those inside of the owlkettle nimibook instead of linking to the files.

The idea would be something like:

import nimib, nimibook

nbInit(theme = useNimibook)

nbText: """
## Example
Look at this very cool example of a scale widget
"""

nbCode(file = "owlkettle/examples/widget/scale.nim")

nbText: """
As you can see it does wonderful things etc. etc.
"""
...

This is just an example to demonstrate what I mean, what the Syntax for it looks like exactly isn't all that important.

highlight nim code in pages with markdown sources

see also pietroppeter/nimib#68 (where there is the discussion for other languages than nim, which also should be in scope here)
the feature should likely be implemented first in nimib and then used here.

support directly markdown files

a normal markdown file (with no need to run nim code) could generate an html directly.

The change should be in nimibook.publish and we could thus support the following

let toc = newToc("Example", "book"):
  entry("Introduction (only markdown)", "index.md")  # this will create a page starting from the plan markdown
  entry("Another chapter (with nim code)", "chapter.nim")

Improve docs of toc srcDir homeDir

Conversation in discord app dev about a potential use of nimibook with owlkettle made me realize that:

  • in the toc chapter of docs I am not specifying that section command uses the section folder path implicitly in all entries inside the section!
  • also I should make very explicit that the logic is: relative path wrt to srcDir as source is translated to relative path wrt to homeDir (put this in configuration chapter, under folder structure)
    • there is also typo "wit GitHub pages"
    • warn about .. source paths
    • warn about relative assets path (owlkettle use case)
    • I mention also outDir instead of homeDir. Fix that too!

logging cli actions

  • clean should log what is being removed

others stuff that we should log in the cli?

refactor check to return number of failures

currently the check command quits on failure. we could refactor it to actually return the number of failures.
It should be the CLI that quits when failing. An advantage would be able to easily create tests that assert on expected number of failures.

Allow sections to be collapsed/expanded with a chevron-icon button

The Feature Suggestion

Allow the entries in the sidebar to be "folded in" and "out".

Motivation for this feature

Take this sidebar:
image

This is likely to grow in the future, making visibility of points below "internals" (and future longer sections) difficult.

It would be nice if I could "fold in" entries of the sidebar so that it can look more like this:
image

I would suggest this provide the following features:

1. Expand/Collapse on click icon - button

Every section is not just a hyperlink. To the left or right of the section entry in the sidebar should be an icon-button that a user could click on to expand/collapse a section of entries. For a consistent design language, the icons used should likely be chevron icons to indicate that it is currently collapsed (chevron-up) or expanded (chevron down).

The button should highlight on hover separate from the section-hyperlink.

2. Automatically expand section when user is in an entry of that section

In this example: If I am on the page "Build Hook", I would expect the section "Internals" and "Hooks" to be expanded, but not "Adders"

3. Side-consideration: Remove sections having their own pages and make their sole purpose to expand/collapse sections

It may be worth considering maybe making sections no longer their own page but only buttons to expand/collapse sections of a sidebar. That would be a breaking change.

Alternatively, it could be considered to keep section as is and introduce a new grouping mechanism going by the name of group, that you just pass the name it should have on the sidebar and whether the group should be expanded/collapsed initially.

Possible issue in parallel builds when two file have the same name

I have multiple files named index.nim in my nimiBook in nimiSlides. And I have gotten two errors in the C-compiler/linker regarding this: link to job And I suspect that it might be due to them using the same filenames in nimcache. This is problematic as you typically have multiple index.nim files in a book (one for each section).

A possible solution to this would be to only allow a single file of each filename to be built at the same time. So if a index.nim file is already being built, and another index.nim file is about to be built as well, it will be put aside until the other file has finished.

I think this could be done using a global HashSet[string] and adding a condition here that checks if the current filename is already in the set or not.

Licensing of embedded assets

I am currently working on fulfilling the legal prerequisites for merging can-lehmann/owlkettle#34. As discussed before on Discord, I would like to compile a list of licenses for the assets redistributed as part of the resulting website. So far I primarily looked at the files in the assets folder. The following is the section I plan to include in owlkettles docs.

We use nimibook to build this documentation. Nimibook is licensed under the MIT license.

When building a website using nimibook, various assets (code, fonts, styles) are redistributed as part of the website. Here are the licenses for the assets distributed as part of this website. Click on one of the assets to view its license. Note that these licenses only apply to the indicated assets redistributed as part of this website, not to owlkettle or its documentation text.

It would be great if you could double check that I didn't miss anything.

I also have a specific question regarding the licensing of book.js. I assumed that is licensed under MPL-2.0, since it seems to come from mdBook, which itself is MPL-2.0. Is that correct?

The assumption is based on Section 3.1 of the MPL which states that:

All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License.

Note that I am not a lawyer, my understanding of software licenses is quite limited, so take all of this with a grain of salt 😃

[RFC] nimibook cli design proposal

The following is my design idea for a cli-generating template nimibookCli that will allow to support deploy mechanism (see discussions in #12, #19).

nbook.nim

main file for managing a nimibook project should be a nbook.nim (renamed genbook since it will do more) with the following structure:

import nimibook

var book = newBookFromToc("My book", "book"):
  entry("Introduction", "index")
  # other entries
  
book.git_repository_url = # ...
# other book configurations

nimibookCli # a template provided by nimibook library

Note that the cli should be a real cli and not based on compile time switches as currently is. This means in particular that unless the toc or book configuration change, there is no need to recompile.

The user starting from an empty repository and adding a file with the above content, should be able to call the following commands with the generated cli (after calling nim c nbook or calling directly nim r nbook <command>).

nbook init

On first call it will create the initial folder structure:

.
├── book              # source of the book
│      ├── index.nim  # basic structure for nimibook nim file
│      └── ...        # other nimibook documents and folders needed for the toc
├── docs              # build location for the book
│      └── assets     # css, js, fonts, ...
├── templates         # mustache templates
├── nbook.nim         # source for toc, book configuration and cli
├── .gitignore
├── config.nims
└── README.md

Inside book folder it will create appropriate nim and md files reflecting current toc.
On subsequent call it will not overwrite existing files. So if init is already called once it will likely only add new files if they have been added to the toc. If you provide a folder or file it will restrict the init operation to that specific folder or file.

nbook check

It will check that current folder structure reflects book toc, configuration (and the internal nimibook assets). It will also lists any other files that are not reflected in current structure.
You should be able to provide a path (folder or file) and the check operation should be restricted to that folder or file.

nbook clean

It will remove all files that should not be represented by current structure. It will also remove outputs of build process (e.g. book.json and html files). It should have a mechanism to protect specific files or folders (some api that you put in nimibook? something like book.keep = @["somefolder", "some/file.nim", ...]). You should be able to provide a path (folder or file) and the clean operation should be restricted to that folder (or file).

nbook build

It will build the book output starting from the toc and generating all files. If you provide a folder or a file it will restrict the build operation only to that folder or file.

nbook update

Same as init but it will overwrite the content instead of doing nothing in the case that a file exists.

templates should be used as in-memory partials

instead of copying them in book folder while building docs, templates should be used as in-memory partials. if one wants to use a custom head.mustache, then he should commit in book folder (or maybe better we should make docs folder the one where nimib goes looking for templates) and this would provide the ovveride.

useLatex as a book config

  • currently in order to add latex functionalities to a document you need to add nb.useLatex to each document
  • we could add a useLatex configuration option in the book that activates this for the whole book

should be a rather easy implementation, in particular:

  • add a new field (with documentation comment) in BookConfig type (in types.nim)
  • a corresponding line should be added in useNimibook proc (in themes.nim)
  • document change in book/content.nim (and should be auto documented in configuration)

Use different "book" directory

Can you change the value "book" in the newBookFromToc() call? I run into errors when changing it to anything else. If it is designed to be changed, then some sort of error is occurring here.

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.