Giter Club home page Giter Club logo

fox.jason.prismjs's Introduction

Prism-JS for DITA-OT

license DITA-OT 4.2 CI Coverage Status Quality Gate Status

This is a syntax highlighting DITA-OT Plug-in which integrates the flexible Prism-JS highlighting library into the DITA Open Toolkit engine. This enables the generation of documents including code snippets which are automatically colorized according to language syntax. The plug-in extends both static HTML and PDF transtypes.

▶️ Video from DITA-OT Day 2019

Table of Contents

Background

What is Prism-JS?

Prism is a lightweight, robust, elegant syntax highlighting library. It's a spin-off project from Dabblet.

  • Highlights embedded languages (e.g. CSS inside HTML, JavaScript inside HTML)
  • Highlights inline code (<codeph>) as well, not just code blocks (<codeblock>)
  • Highlights nested languages (CSS in HTML, JavaScript in HTML)
  • It doesn’t force you to use any Prism-specific markup

You can learn more on http://prismjs.com/.

Why another syntax highlighter?: http://lea.verou.me/2012/07/introducing-prism-an-awesome-new-syntax-highlighter/#more-1841


Install

The DITA-OT Prism-JS syntax highlighter has been tested against DITA-OT 3.x. It is recommended that you upgrade to the latest version.

Installing DITA-OT

The DITA-OT Prism-JS syntax highlighter is a plug-in for the DITA Open Toolkit.

  • Full installation instructions for downloading DITA-OT can be found here.

    1. Download the dita-ot-4.2.zip package from the project website at dita-ot.org/download
    2. Extract the contents of the package to the directory where you want to install DITA-OT.
    3. Optional: Add the absolute path for the bin directory to the PATH system variable.

    This defines the necessary environment variable to run the dita command from the command line.

curl -LO https://github.com/dita-ot/dita-ot/releases/download/4.2/dita-ot-4.2.zip
unzip -q dita-ot-4.2.zip
rm dita-ot-4.2.zip

Installing the Plug-in

  • Run the plug-in installation commands:
dita install https://github.com/jason-fox/fox.jason.extend.css/archive/master.zip
dita install https://github.com/jason-fox/fox.jason.prismjs/archive/master.zip

Installing Node.js

Due to the deprecation and removal of the Nashorn Engine in JDK11-14 JEP 335 any plug-in using JavaScript within <script> or <scriptdef> ANT tasks will start throwing warnings with Java 11 onwards and above. From Java 15 onwards, these plugins will no longer work. From DITA-OT 4.0 onward this step is mandatory

The DITA-OT Prism-JS syntax highlighter relies heavily the Prism-JS JavaScript library, and therefore has been updated to run using Node.js where present on a user's machine. Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine.

To download a copy follow the instructions on the Install Page.

apt-get update -q
export DEBIAN_FRONTEND=noninteractive
apt-get install -qy --no-install-recommends nodejs
nodejs -v

Usage

To highlight the syntax within codeblocks, add an outputclass attribute to any <codeph> or <codeblock> elements in your *.dita files. Alternatively add an outputclass attribute to the <body> element, and all <codeph> or <codeblock> will inherit from it.

With the default Prism-JS library the following languages can be highlighted

  • outputclass="language-markup" - HTML, XML etc.
  • outputclass="language-css" - Cascading Style Sheet highlighting
  • outputclass="language-clike" - C-language family highlighting
  • outputclass="language-javascript" - JavaScript highlighting ... etc.

e.g.:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE topic PUBLIC "-//OASIS//DTD DITA Topic//EN" "topic.dtd">
<topic id="examples">
  <title>Examples</title>
  <body  outputclass="language-markup">

  <p>The Prism source, highlighted with Prism:</p>
  <codeblock outputclass="language-javascript">
    <coderef href="../src/prism.js"/>
  </codeblock>

  <p>This page’s CSS code, highlighted with Prism:</p>
  <codeblock outputclass="language-css">
    <coderef href="../src/style.css"/>
  </codeblock>

  <p>This page’s HTML, highlighted with Prism:</p>
  <codeblock outputclass="language-html">
    <coderef href="../src/index.html"/>
  </codeblock>

  <p>This page’s logo (SVG), highlighted with Prism:</p>
  <codeblock outputclass="language-markup">
    <coderef href="../src/logo.svg"/>
  </codeblock>
  </body>
</topic>

A test document including HTML, CSS and JavaScript code snippets can be found within the plug-in at: PATH_TO_DITA_OT/plugins/fox.jason.prismjs/sample

Line numbering

To display line numbers in codeblocks in HTML and PDF, add the show-line-numbers outputclass to the <codeblock>

<codeblock outputclass="language-javascript show-line-numbers">
  <coderef href="../src/prism.js"/>
</codeblock>

Invocation from the command line

The Plug-in extends the existing PDF and HTML transforms

  • to create a PDF with highlighted code snippets run:
PATH-TO-DITA-OT/bin/dita -f pdf -i document.ditamap  -o out

Result

  • to create static HTML with highlighted code snippets run:
PATH-TO-DITA-OT/bin/dita -f html5 -i document.ditamap  -o out

Result

Parameter Reference

  • prism.default - Specifies the default Prism language
  • prism.use.theme - Specifies which of the three included themes to use.
  • prism.css.theme - Specifies the location of a custom color theme file relative to the output directory.

Customizing the output

Prism-JS is easily extended to other languages since it purely relies on regular expressions. Additional languages are loaded dynamically during processing. A large number of additional languages are supported - just look at the list on https://github.com/PrismJS/prism/tree/master/components

Altering the CSS theme colors

Three included prism themes are included. Each theme supports the prefers-color-scheme css media query and uses CSS variables to offer separate "light" and_"dark"_ modes.

A custom theme can be also be altered by setting the prism.css.theme parameter, a separate

Altering the static HTML look and feel

For more extensive modifications, extend with an additional plug-in which overrides, the default prismjs.css.file property and amend a copy of the css/style.css file to alter the look-and-feel of the rendered HTML

plugin.xml Configuration
<plugin id="com.example.prismjs-theme">
  <feature extension="ant.import" file="theme.xml"/>
  <require plugin="fox.jason.extend.css"/>
  <require plugin="fox.jason.prismjs"/>
  <feature extension="extend.css.process.pre" value="prismjs.override.css"/>
</plugin>
ANT Build file: theme.xml
<project name="com.example.prismjs-theme">
  <target name="prismjs.override.css">
    <property name="prismjs.css.file" value="${dita.plugin.com.example.prismjs-theme.dir}/resource/style.css"/>
  </target>
</project>

A working example can be found in the Dark Theme CSS DITA-OT plug-in

Altering the PDF look and feel

The cfg/fo/attrs/prismjs-attr.xsl provides the colors for the PDF output. The names of the attributes match the CSS file, copy and amend the prismjs-attr.xsl file in your own plug-in.

plugin.xml Configuration
<plugin id="com.example.prismjs-theme">
  <require plugin="fox.jason.prismjs"/>
  <feature extension="dita.xsl.xslfo" value="xsl/xslfo.xsl" type="file"/>
</plugin>
xsl/xslfo.xsl XSL Stylesheet

Override the <xsl:template match="*[contains(@class,' topic/ph ') and contains(@outputclass, 'token')]"> template as shown:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:param name="PRISM-THEME" select="'com.example.prismjs-theme'"/>

    <xsl:include href="../cfg/fo/attrs/prismjs-attr.xsl"/>

    <xsl:template match="*[contains(@class,' topic/ph ') and contains(@outputclass, 'token')]">
      <fo:inline xsl:use-attribute-sets="__codeph__language__">
        <xsl:call-template name="commonattributes"/>
        <xsl:call-template name="processPrismAttrSetReflection">
          <xsl:with-param name="attrSet"
            select="replace(@outputclass,'token ','__token__')"/>
          <xsl:with-param name="path" select="concat('../../', concat($PRISM-THEME, '/cfg/fo/attrs/prismjs-attr.xsl'))"/>
        </xsl:call-template>
        <xsl:apply-templates/>
      </fo:inline>
  </xsl:template>
</xsl:stylesheet>

A working example can be found in the Dark Theme CSS DITA-OT plug-in

License

Apache 2.0 © 2018 - 2024 Jason Fox

The Program includes the following additional software components which were obtained under license:

fox.jason.prismjs's People

Contributors

actions-user avatar dependabot[bot] avatar jason-fox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fox.jason.prismjs's Issues

Regex exception and other problems on Windows but not on Linux

HTML (Warnings, Exception, no output at all)

When I try to build any html output on a Windows machine I get some warnings and an exception that ends the process. The only file that is written to the output is the css file.

Exception: Error: java.util.regex.PatternSyntaxException: Illegal/unsupported escape sequence near index 3
Warnings: Mostly Warning about missing files or misspelled file names

PDF (Warnings, missing styles in output)

When I try a pdf production, it will run through with basically the same Warnings (files) but without the Regex exception. But in the pdf output, the styled codes are black-and-white only. But there is a difference between codeblock with and without the output-class attribute

This is the output on Windows

c:\projects\apps\DITA_OT_Prism_POC\dita-ot-3.6.1\plugins\fox.jason.prismjs\sample>dita -i document.ditamap -o out -f html5 [filter] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/document.ditamap:4:80: [DOTJ083E][ERROR] The resource referenced as file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/prism.dita is capitalized differently on disk, using file:/C:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/prism.dita. [filter] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/document.ditamap:5:89: [DOTJ083E][ERROR] The resource referenced as file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/examples.dita is capitalized differently on disk, using file:/C:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/examples.dita. [filter] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/document.ditamap:6:94: [DOTJ083E][ERROR] The resource referenced as file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/features-full.dita is capitalized differently on disk, using file:/C:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/features-full.dita. [filter] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/document.ditamap:7:95: [DOTJ083E][ERROR] The resource referenced as file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/basic-usage.dita is capitalized differently on disk, using file:/C:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/basic-usage.dita. [filter] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/examples.dita:9:38: [DOTJ083E][ERROR] The resource referenced as file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/src/prism.js is capitalized differently on disk, using file:/C:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/src/prism.js. [filter] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/examples.dita:14:39: [DOTJ083E][ERROR] The resource referenced as file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/src/style.css is capitalized differently on disk, using file:/C:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/src/style.css. [filter] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/examples.dita:19:40: [DOTJ083E][ERROR] The resource referenced as file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/src/index.html is capitalized differently on disk, using file:/C:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/src/index.html. [filter] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/topics/examples.dita:24:38: [DOTJ083E][ERROR] The resource referenced as file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/src/logo.svg is capitalized differently on disk, using file:/C:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/src/logo.svg. [move-meta] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/document.ditamap:4:80: [DOTX026W][WARN]: Unable to retrieve linktext from target: 'document.ditamap'. Using navigation title as fallback. [move-meta] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/document.ditamap:5:89: [DOTX026W][WARN]: Unable to retrieve linktext from target: 'document.ditamap'. Using navigation title as fallback. [move-meta] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/document.ditamap:6:94: [DOTX026W][WARN]: Unable to retrieve linktext from target: 'document.ditamap'. Using navigation title as fallback. [move-meta] file:/c:/projects/apps/DITA_OT_Prism_POC/dita-ot-3.6.1/plugins/fox.jason.prismjs/sample/document.ditamap:7:95: [DOTX026W][WARN]: Unable to retrieve linktext from target: 'document.ditamap'. Using navigation title as fallback. Error: java.util.regex.PatternSyntaxException: Illegal/unsupported escape sequence near index 3

For testing purposes I used the demo content from dita-ot-3.6.1\plugins\fox.jason.prismjs\sample

I used the following components

On Windows (10pro)

Java:

  • openjdk 11.0.11 2021-04-20
  • OpenJDK Runtime Environment AdoptOpenJDK-11.0.11+9 (build 11.0.11+9)
    DITA-OT:
  • DITA-OT version 3.6.1
    Node:
  • v12.16.0
    PlugIn
    Master version on 10.06.2021

On Linux (Ubuntu 20.04LTS)

Java:

  • openjdk 11.0.11 2021-04-20
  • OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.20.04)
    DITA-OT:
  • DITA-OT version 3.6.1
    Node:
  • v10.19.0
    PlugIn
    Master version on 10.06.2021

Using codeblocks with dita-ot 3.7.2 raises error messages

Whenever i use a highlighted codeblock

            <codeblock outputclass="language-cpp">  int main() { Test codeblock; }
             </codeblock>

in a dita topic i get the error
[pipeline] An error occurred matching pattern {element()[Q{http://dita-ot.sourceforge.net/ns/201007/dita-ot}matches-searchtitle-class(exactly-one((attribute::attribute(Q{}class)) treat as attribute(Q{}class)))]}: An empty sequence is not allowed as the first argument of dita-ot:matches-searchtitle-class()
several times when doing a pdf output.

The pdf itself however does not seem to have issues.

Add validation to check if file exist

Logs:
highlight: File file:/C:/test/content/authoring/fht1600964327060.dita not found [mkdir] Created dir: C:\test\output\pdf\agw1600983740990\temp\code\6a2d1d117e2bbc05d2e2d9f8a10834fffa9991f0.dita [add-code-id] Processing C:\test\output\pdf\agw1600983740990\temp\6a2d1d117e2bbc05d2e2d9f8a10834fffa9991f0.dita to C:\test\output\pdf\agw1600983740990\temp\null1209384693 [add-code-id] Loading stylesheet C:\test\dita-ot-3.6\plugins\fox.jason.prismjs\xsl\add-code-id.xsl [copy] Copying 1 file to C:\test\output\pdf\agw1600983740990\temp [mkdir] Created dir: C:\test\output\pdf\agw1600983740990\temp\code\6c3101787579d7391d35046d96ee15652f4d0448.dita [add-code-id] Processing C:\test\output\pdf\agw1600983740990\temp\6c3101787579d7391d35046d96ee15652f4d0448.dita to C:\test\output\pdf\agw1600983740990\temp\null1095678966 [add-code-id] Loading stylesheet C:\test\dita-ot-3.6\plugins\fox.jason.prismjs\xsl\add-code-id.xsl [copy] Copying 1 file to C:\test\output\pdf\agw1600983740990\temp [mkdir] Created dir: C:\test\output\pdf\agw1600983740990\temp\code\7945d282ecb24c73121a3dea48f9848bafbf69be.xml [add-code-id] Processing C:\test\output\pdf\agw1600983740990\temp\7945d282ecb24c73121a3dea48f9848bafbf69be.xml to C:\test\output\pdf\agw1600983740990\temp\null988992216 [add-code-id] Loading stylesheet C:\test\dita-ot-3.6\plugins\fox.jason.prismjs\xsl\add-code-id.xsl [copy] Copying 1 file to C:\test\output\pdf\agw1600983740990\temp [mkdir] Created dir: C:\test\output\pdf\agw1600983740990\temp\code\afc34bcc0d413352fb10fb5fa0cda06e742970d9.dita [add-code-id] Processing C:\test\output\pdf\agw1600983740990\temp\afc34bcc0d413352fb10fb5fa0cda06e742970d9.dita to C:\test\output\pdf\agw1600983740990\temp\null171970911 [add-code-id] Loading stylesheet C:\test\dita-ot-3.6\plugins\fox.jason.prismjs\xsl\add-code-id.xsl [copy] Copying 1 file to C:\test\output\pdf\agw1600983740990\temp [mkdir] Created dir: C:\test\output\pdf\agw1600983740990\temp\code\ike1591695086339.xml [add-code-id] Processing C:\test\content\published\en-us\uvy1582744299765.ditamap_23\ike1591695086339.xml to C:\test\output\pdf\agw1600983740990\temp\null892913150 [add-code-id] Loading stylesheet C:\test\dita-ot-3.6\plugins\fox.jason.prismjs\xsl\add-code-id.xsl [add-code-id] : Error! I/O error reported by XML parser processing file:/C:/test/content/published/en-us/uvy1582744299765.ditamap_23/ike1591695086339.xml: C:\test\content\published\en-us\uvy1582744299765.ditamap_23\InfineonDitabase.dtd (The system cannot find the file specified) Cause: java.io.FileNotFoundException: C:\test\content\published\en-us\uvy1582744299765.ditamap_23\InfineonDitabase.dtd (The system cannot find the file specified) [add-code-id] Failed to process C:\test\content\published\en-us\uvy1582744299765.ditamap_23\ike1591695086339.xml

Is it possible to add validation to check if a file exists? Or prevent it from failing or stopping the output generation, maybe a warning would suffice.

Highlighting is applied by default not only when outputclass is set

A content with <codeph> without an outputclass is highlighted by default. Is it the normal behavior? Is it possible to highlight only when the outputclass="language-xxxx" is present in element or ancestor element (like body)?

sample codeph:
<codeph>&lt;amount&gt;</codeph>

sample output:
image

java.lang.StackOverflowError

Processing too many files will throw java.lang.StackOverflowError. Is there a limit to the number of files?

Error log snippet:
Error: The following error occurred while executing this line: D:\Ixiasoft\OutputGenerator\prod-01\data\dita-ot-3.6\plugins\fox.jason.prismjs\process_prismjs.xml:169: The following error occurred while executing this line: D:\Ixiasoft\OutputGenerator\prod-01\data\dita-ot-3.6\plugins\fox.jason.prismjs\process_prismjs.xml:170: The following error occurred while executing this line: D:\Ixiasoft\OutputGenerator\prod-01\data\dita-ot-3.6\plugins\fox.jason.prismjs\resource\antlib.xml:307: java.lang.StackOverflowError

Leading `..` is removed from relative paths

This seems to have been introduced with b404f8a. We keep all our dita files in subdirs, so URLs when linking a stylesheet or xref-ing another dita file will always start with ../. As of b404f8a, these seem to be removed on pages containing code (other pages are fine).

Customize font size in PDF output

I have trouble customizing the font size in highlighted codeblocks using this plugin.

Default size seems to be too small,

compared to the other font we use,
so i tried to increase the "font-size" in style.css to 2em, but did not see any difference in PDF output.

CSS sounds also only affecting HTML output to me.
Our non-highlighted codeblocks can be customized via

<xsl:attribute-set name="codeblock"/>
in pr-domain-attr.xsl successfully however.

Any hint would be appreciated.

See screenshot:


Screenshot_20220622_151625


Weird characters appearing instead of highlighted codes

Tested with the sample content provided by the plugin and dita-ot 3.6. Please see attached pdf.
document.pdf

It seems related to the last change, it looks like the converted path is the same through out the process. It is evident in the temporary code directory, all temporary files created intended for another content were all stored in the same directory.

Can't handle space in folder name

When the ditafiles is in a directory that contains a space (e.g "Export RFM"), prismjs failed to handle this and cause an error. Please see log below.

highlight:
[mkdir] Created dir: D:\Ixiasoft\OutputGenerator\prod-02\temp\Export RFM.OutGenClient.34.1646397635622\temp\code\axh1613482060411.xml
Error: The following error occurred while executing this line:
D:\Ixiasoft\OutputGenerator\prod-02\data\dita-ot-3.6\plugins\fox.jason.prismjs\process_prismjs.xml:93: The following error occurred while executing this line:
D:\Ixiasoft\OutputGenerator\prod-02\data\dita-ot-3.6\plugins\fox.jason.prismjs\resource\antlib.xml:241: input file D:\Ixiasoft\OutputGenerator\prod-02\temp\Export%20RFM.OutGenClient.34.1646397635622\temp\axh1613482060411.xml does not exist
2022-03-04T13:41:03,768 ERROR org.apache.tools.ant.taskdefs.ExecTask Result: 1

java.net.MalformedURLException

I am getting this malformed url error when dita file contains codeblock/codeph. Did I missed some configurations?
Posted below is the error log.

\dita-ot-3.6\plugins\fox.jason.prismjs\xsl\add-code-id.xsl:65:89: Fatal Error! Resolved URL is malformed Cause: java.net.MalformedURLException: unknown protocol: d

Tested with the sample content provided by the plugin and dita-ot 3.6.

Preprocess2 becoming OT default

Hi @jason-fox,

Jarno is working on making preprocess2 map-first processing the default. I mentioned in the monthly contributor call that I'd reach out to you about your various plugins and if they'd be affected by such a switch-over. Roger Sheen mentioned that you stay on top of OT changes, but this one is a major refactoring and may affect existing OT plugins potentially. We rely on the passthrough plugin in several places and are going to evaluate the prismjs plugin as well.

Best Regards,

John

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.