confluence-publisher / confluence-publisher Goto Github PK
View Code? Open in Web Editor NEWMaven plugin and Docker image to convert AsciiDoc and publish it to Confluence
License: Apache License 2.0
Maven plugin and Docker image to convert AsciiDoc and publish it to Confluence
License: Apache License 2.0
It would be helpful to have the possibility to merge documentations from different location into one consolidated documentation (i.e. when one want to split the documentation per sub-module and publish it as one consolidated documentation).
Official Confluence Publisher documentation should be published in Confluence, not only as AsciiDoc in GitHub. Publishing on Atlassian Cloud seems to be the simplest solution.
Referenced images that are outside of the publishing root are not found when publishing.
In generated html snippets (and afterwise in Confluence) all special characters are broken.
Pull requests from forks fail due to security restrictions with secret variables (see https://docs.travis-ci.com/user/pull-requests/#Pull-Requests-and-Security-Restrictions).
Integration tests and artifact signing rely on secret variables and thus must be disabled for builds on pull requests from forks.
Provide a Docker image with environment variables for all required and optional configuration parameters and allow publishing by executing Docker image.
This allows publishing documentation as part of a build pipeline without any dependency to the Confluence Publisher and Maven in the documentation project itself.
The Confluence Publisher currently uses the platform default encoding when reading AsciiDoc pages. This might lead to encoding issues (see #49). The encoding to be used by Confluence Publisher should be configurable, with UTF-8 as default.
As for now the target space must already exist in confluence. It would be helpful in some cases when the space would be created automatically.
The use of :toc:
in AsciiDoc could be translated to the table of contents macro of confluence.
hello,
i have a problem with a file include. I want to include a json file which contains a regex:
"instanceVersionDate": {
"type": "string",
"pattern": "[0-9][0-9]\.[0-9][0-9]\.[0-9]{4}$",
"optional": false
}
now the publishing to confluence fails with the following exception:
Caused by: org.apache.maven.plugin.MojoExecutionException: Publishing to Confluence failed at org.sahli.asciidoc.confluence.publisher.maven.plugin.AsciidocConfluencePublisherMojo.execute(AsciidocConfluencePublisherMojo.java:75) at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207) ... 20 more Caused by: java.lang.RuntimeException: Could not convert asciidoc pages at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluenceConverter.convert(AsciidocConfluenceConverter.java:85) at org.sahli.asciidoc.confluence.publisher.maven.plugin.AsciidocConfluencePublisherMojo.execute(AsciidocConfluencePublisherMojo.java:67) ... 22 more Caused by: java.lang.IllegalArgumentException: Illegal group reference at java.util.regex.Matcher.appendReplacement(Matcher.java:857) at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.replaceAll(AsciidocConfluencePage.java:146) at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.lambda$unescapeCdataHtmlContent$1(AsciidocConfluencePage.java:127) at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.lambda$postProcessContent$4(AsciidocConfluencePage.java:156) at java.util.stream.ReduceOps$1ReducingSink.accept(ReduceOps.java:80) at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:484) at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.postProcessContent(AsciidocConfluencePage.java:156) at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.convertedContent(AsciidocConfluencePage.java:117) at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.newAsciidocConfluencePage(AsciidocConfluencePage.java:101) at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluenceConverter.lambda$buildPageTree$0(AsciidocConfluenceConverter.java:97) at java.util.ArrayList.forEach(ArrayList.java:1249) at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluenceConverter.buildPageTree(AsciidocConfluenceConverter.java:92) at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluenceConverter.convert(AsciidocConfluenceConverter.java:76) ... 23 more
In case of an exception (e.g. while publishing content to Confluence), no proper error logging is performed (instead, message is printed to standard out). Use Maven logger to log error, re-throw exception for support of Maven debug flag.
In case no ancestorId is defined in Maven plugin configuration, publishing any documentation results to all existing Confluence pages not contained in documentation to be deleted.
Allowing to publish documentation without ancestorId seems to be too risky and not adding enough value. As a consequence, the ancestorId should be changed to mandatory.
Also document how to allow the Confluence Publisher to manage all pages of a space (i.e. how to get to the "space ancestor id").
As for now attachment are downloaded in order to compare their checksum (to find out if the attachment must be updated or not). It would be better to store the checksum as a comment (or property if possible) on the attachment itself. This would save a lot of bandwidth during the publication process.
Environment: Windows - Git Bash - Graphiz 2.38 -Confluence: 5.5.7
My configuration file (pom.xml) (I only added the required parameters for the confluence page
<plugin>
<groupId>org.sahli.asciidoc.confluence.publisher</groupId>
<artifactId>asciidoc-confluence-publisher-maven-plugin</artifactId>
<version>1.8</version>
<configuration>
<asciidocRootFolder>test</asciidocRootFolder>
<rootConfluenceUrl>https://xxxxxx</rootConfluenceUrl>
<spaceKey>ASCI</spaceKey>
<ancestorId>8388631</ancestorId>
<username>xxx</username> <!-- or read from property -->
<password>xxxx</password> <!-- or read from property -->
</configuration>
</plugin>
I cloned the latest version from git and ran mvn clean package to publish the .adoc files
Looked at the attached log
log.txt
The adoc file is a simple test file without any special forms
In case updating an already uploaded page fails (e.g. due to invalid markup), subsequent uploads lead to an exception stating "No content property found with key: content-hash", as the content hash property is deleted before uploading the page content, and again set only after the upload succeeded.
As a consequence, the existing page needs to be deleted in Confluence, and afterwards uploaded again.
Not all attributes supported by Asciidoctor are recognized (E.g. docname
).
And (maybe a 2nd issue?) there is no possibility to define custom attributes like it is in Asciidoc:
<configuration>
[...]
<attributes>
<my-own-foo>${foo}</my-own-foo>
</attributes>
</configuration>
Dot is required to be installed on the local machine running the Confluence Publisher build, otherwise a test is failing due to PlantUML generating an error message image with different dimensions than expected (see #47)
Currently, the Maven Plugin component contains not only the specifics to Maven, but also the logic for traversing the documentation root folder, building up the metadata and configuring the Confluence Publisher client. This renders it almost impossible to integrate the Confluence Publisher into other build tools, e.g. Gradle or SBT.
When working with feature branches it would be helpful to be able to define page title prefix or suffix to avoid page title collisions (page titles must be unique).
When using XML in listings, XML tags are not displayed properly:
[source,xml]
----
<version>1.0.0</version>
----
is displayed as
<version>1.0.0</version>
http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#images
block images can be used successfully with image::
but it seems inline images (using image:
) are not supported
[ERROR] Failed to execute goal org.sahli.asciidoc.confluence.publisher:asciidoc-confluence-publisher-maven-plugin:0.1.0:publish (default-cli) on project XXXX: Publishing to Confluence failed: 400 Bad Request PUT https://confluence.XXXX.net/rest/api/content/13271515 {"statusCode":400,"data":{"authorized":false,"valid":true,"errors":[],"successful":false},"message":"Error parsing xhtml: Unexpected close tag </span>; expected </img>.\n at [row,col {unknown-source}]: [20,329]"} -> [Help 1]
On master (on Windows cmd and cygwin):
$ mvn clean install
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Asciidoc Confluence Publisher Converter 0.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ asciidoc-confluence-publisher-converter ---
[INFO] Deleting G:\code\projects\confluence-publisher\asciidoc-confluence-publisher-converter\target
[INFO]
[INFO] --- jacoco-maven-plugin:0.7.5.201505241946:prepare-agent (prepare-agent) @ asciidoc-confluence-publisher-converter ---
[INFO] argLine set to -javaagent:C:\\Users\\Megaport\\.m2\\repository\\org\\jacoco\\org.jacoco.agent\\0.7.5.201505241946\\org.jacoco.agent-0.7.5.201505241946-runtime.jar=destfile=G:\\code\\projects\\confluence-publisher\\asciidoc-confluence
coco.exec
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ asciidoc-confluence-publisher-converter ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 10 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ asciidoc-confluence-publisher-converter ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to G:\code\projects\confluence-publisher\asciidoc-confluence-publisher-converter\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ asciidoc-confluence-publisher-converter ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 8 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ asciidoc-confluence-publisher-converter ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to G:\code\projects\confluence-publisher\asciidoc-confluence-publisher-converter\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.19.1:test (default-test) @ asciidoc-confluence-publisher-converter ---
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePageTest
/usr/bin/stty: Standardeingabe: Inappropriate ioctl for device
Tests run: 48, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 63.613 sec <<< FAILURE! - in org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePageTest
renderConfluencePage_asciiDocWithEmbeddedPlantUmlDiagram_returnsConfluencePageWithLinkToGeneratedPlantUmlImage(org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePageTest) Time elapsed: 0.9 sec <<< FAILURE!
java.lang.AssertionError:
Expected: a string containing "<ac:image ac:height=\"175\" ac:width=\"57\"><ri:attachment ri:filename=\"embedded-diagram.png\"></ri:attachment></ac:image>"
but: was "<ac:image ac:height="225" ac:width="274"><ri:attachment ri:filename="embedded-diagram.png"></ri:attachment></ac:image>"
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePageTest.renderConfluencePage_asciiDocWithEmbeddedPlantUmlDiagram_returnsConfluencePageWithLinkToGeneratedPlantUmlImage(AsciidocConfluencePageTest.java:712)
renderConfluencePage_asciiDocWithIncludedPlantUmlFile_returnsConfluencePageWithLinkToGeneratedPlantUmlImage(org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePageTest) Time elapsed: 0.084 sec <<< FAILURE!
java.lang.AssertionError:
Expected: a string containing "<ac:image ac:height=\"175\" ac:width=\"57\"><ri:attachment ri:filename=\"included-diagram.png\"></ri:attachment></ac:image>"
but: was "<ac:image ac:height="225" ac:width="274"><ri:attachment ri:filename="included-diagram.png"></ri:attachment></ac:image>"
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePageTest.renderConfluencePage_asciiDocWithIncludedPlantUmlFile_returnsConfluencePageWithLinkToGeneratedPlantUmlImage(AsciidocConfluencePageTest.java:727)
Results :
Failed tests:
AsciidocConfluencePageTest.renderConfluencePage_asciiDocWithEmbeddedPlantUmlDiagram_returnsConfluencePageWithLinkToGeneratedPlantUmlImage:712
Expected: a string containing "<ac:image ac:height=\"175\" ac:width=\"57\"><ri:attachment ri:filename=\"embedded-diagram.png\"></ri:attachment></ac:image>"
but: was "<ac:image ac:height="225" ac:width="274"><ri:attachment ri:filename="embedded-diagram.png"></ri:attachment></ac:image>"
AsciidocConfluencePageTest.renderConfluencePage_asciiDocWithIncludedPlantUmlFile_returnsConfluencePageWithLinkToGeneratedPlantUmlImage:727
Expected: a string containing "<ac:image ac:height=\"175\" ac:width=\"57\"><ri:attachment ri:filename=\"included-diagram.png\"></ri:attachment></ac:image>"
but: was "<ac:image ac:height="225" ac:width="274"><ri:attachment ri:filename="included-diagram.png"></ri:attachment></ac:image>"
Tests run: 48, Failures: 2, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:06 min
[INFO] Finished at: 2017-06-07T19:03:05+02:00
[INFO] Final Memory: 24M/249M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test (default-test) on project asciidoc-confluence-publisher-converter: There are test failures.
[ERROR]
[ERROR] Please refer to G:\code\projects\confluence-publisher\asciidoc-confluence-publisher-converter\target\surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
Lists with checkboxes could be pushed to Confluence as ac:task
.
Support URL as image source.
default: number of pages created, updated and deleted
verbose: list of all pages created, updated and deleted
The current API is rather low-level and forces build tools to instantiate and link all the required components (ConfluenceRestClient
, ConfluencePublisher
and AsciidocConfluenceConverter
).
Ideally tools should only provide a AsciidocPagesStructureProvider
and a configuration object.
Currently, when publishing documentation under the configured ancestor id, all existing pages under the child tree of the ancestor id get removed, if not existing in the published set of pages anymore.
Alternative publishing strategies would allow for other scenarios, e.g.
Maybe more than one strategy might be needed, e.g. for separating the aspect of how to deal with the ancestor page itself (replacing the content vs. appending to the content) from the aspect of how to deal with non-existing child pages (removing vs. keeping).
In order to ensure all integration tests are successful before merge pull requests from forks into the master (as pull request builds for forks cannot execute integration tests due to secret variables being used), a contributions branch should be used as a "staging area":
As for now the credentials are "hardcoded" in the pom.xml
. One should find a way to externalize those to avoid them to be committed in the VCS. This can already be done by using the settings.xml of maven.
Currently, the master build fails with:
The command "if ( [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] ) || [ -n "$TRAVIS_TAG" ]; then ./mvnw -s .settings.xml jar:jar source:jar javadoc:jar gpg:sign nexus-staging:deploy -Possrh -nsu; fi" exited with 1.
[ERROR] Failed to execute goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.7:deploy (default-cli) on project asciidoc-confluence-publisher-doc: Failed to update metadata org.sahli.asciidoc.confluence.publisher/maven-metadata.xml: null: RepositoryException: NullPointerException -> [Help 1]
Builds for feature branches and pull requests are not affected.
Provide a solution for adding context information on pages. Ideally one could define some dynamic text that's added in the footer of every page (i.e. GIT hash or version).
As for now the pages are ordered as per page creation order. It would be good to have a way to define the order of the pages.
Note: this could be difficult as the REST API of Confluence does not provide a way to reorder pages.
The snapshot version 1.0.0-SNAPSHOT is a left-over from the "old" release approach. New snapshots are always uploaded as 0.0.0-SNAPSHOT, indicating that the version in the POM is only relevant during release builds (and is automatically replaced by the corresponding tag).
The higher version 1.0.0-SNAPSHOT might imply that it represents the more up-to-date software version, which is in fact not the case. Therefore, it should be removed from the snapshot repository.
During publication one could find out which pages where updated and automatically create a changelog page listing all the changes and linking them to diff view of confluence
One should create a documentation how to use the confluence publisher. Ideally this documentation would be written using Asciidoc and published in a running confluence.
Confluence also has an macro of type "tip". Currently asciidoc admonitions of type "TIP" are mapped to the confluence macro "info". This should be changed.
Some existing HTML backend templates (e.g. inline images) produce HTML, while Confluence is expecting XHTML. Using the XHTML backend would solve non-closing tags issues.
Support referencing users when writing @username
.
When confluence root URL contains a context path, the authentication headers are not set and publishing fails with status code 403.
Hi,
I get this error, can you fix that?
Regards Stefan
[ERROR] Failed to execute goal org.sahli.asciidoc.confluence.publisher:asciidoc-confluence-publisher-maven-plugin:0.2.0:publish (default-cli) on project plmapp-unity-plh-adapter: Publishing to Confluence failed: Could not convert asciidoc pages: named capturing group has 0 length name -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.sahli.asciidoc.confluence.publisher:asciidoc-confluence-publisher-maven-plugin:0.2.0:publish (default-cli) on project plmapp-unity-plh-adapter: Publishing to Confluence failed
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
at org.codehaus.classworlds.Launcher.main(Launcher.java:47)
Caused by: org.apache.maven.plugin.MojoExecutionException: Publishing to Confluence failed
at org.sahli.asciidoc.confluence.publisher.maven.plugin.AsciidocConfluencePublisherMojo.execute(AsciidocConfluencePublisherMojo.java:75)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
... 21 more
Caused by: java.lang.RuntimeException: Could not convert asciidoc pages
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluenceConverter.convert(AsciidocConfluenceConverter.java:85)
at org.sahli.asciidoc.confluence.publisher.maven.plugin.AsciidocConfluencePublisherMojo.execute(AsciidocConfluencePublisherMojo.java:67)
... 23 more
Caused by: java.lang.IllegalArgumentException: named capturing group has 0 length name
at java.util.regex.Matcher.appendReplacement(Matcher.java:838)
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.replaceAll(AsciidocConfluencePage.java:146)
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.lambda$unescapeCdataHtmlContent$1(AsciidocConfluencePage.java:127)
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.lambda$postProcessContent$4(AsciidocConfluencePage.java:156)
at java.util.stream.ReduceOps$1ReducingSink.accept(ReduceOps.java:80)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:484)
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.postProcessContent(AsciidocConfluencePage.java:156)
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.convertedContent(AsciidocConfluencePage.java:117)
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluencePage.newAsciidocConfluencePage(AsciidocConfluencePage.java:101)
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluenceConverter.lambda$buildPageTree$0(AsciidocConfluenceConverter.java:97)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluenceConverter.buildPageTree(AsciidocConfluenceConverter.java:92)
at org.sahli.asciidoc.confluence.publisher.converter.AsciidocConfluenceConverter.convert(AsciidocConfluenceConverter.java:76)
... 24 more
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.