Giter VIP home page Giter VIP logo

typst-preview.nvim's Introduction

✨ Typst Preview for Neovim ✨

The Neovim plugin for Enter-tainer/typst-preview.

trimmed.mp4

💪 Features

  • Low latency preview: preview your document instantly on type. The incremental rendering technique makes the preview latency as low as possible.
  • Cross jump between code and preview. You can click on the preview to jump to the corresponding code location and have the preview follow your cursor in Neovim.

📦 Installation

Lazy.nvim:

{
  'chomosuke/typst-preview.nvim',
  lazy = false, -- or ft = 'typst'
  version = '0.3.*',
  build = function() require 'typst-preview'.update() end,
}

Packer.nvim:

use {
  'chomosuke/typst-preview.nvim',
  tag = 'v0.3.*',
  run = function() require 'typst-preview'.update() end,
}

vim-plug:

Plug 'chomosuke/typst-preview.nvim', {'tag': 'v0.3.*', do: ':TypstPreviewUpdate'}

🚀 Usage

Commands / Functions:

  • :TypstPreviewUpdate or require 'typst-preview'.update():
    • Download the necessary binaries to vim.fn.fnamemodify(vim.fn.stdpath 'data' .. '/typst-preview/', ':p').
    • This must be run before any other commands can be run.
      • If you followed the installation instructions, your package manager should automatically run this for you.
  • :TypstPreview:
    • Start the preview. Optionally, the desired preview mode can be specified: :TypstPreview document (default) or :TypstPreview slide for slide mode.
  • :TypstPreviewStop:
    • Stop the preview.
  • :TypstPreviewToggle:
    • Toggle the preview.
  • :TypstPreviewFollowCursor or require 'typst-preview'.set_follow_cursor(true):
    • Scroll preview as cursor moves.
    • This is on by default.
  • :TypstPreviewNoFollowCursor or require 'typst-preview'.set_follow_cursor(false):
    • Don't scroll preview as cursor moves.
  • :TypstPreviewFollowCursorToggle or require 'typst-preview'.set_follow_cursor(not init.get_follow_cursor()).
  • :TypstPreviewSyncCursor or require 'typst-preview'.sync_with_cursor():
    • Scroll preview to the current cursor position. This can be used in combination with :TypstPreviewNoFollowCursor so that the preview only scroll to the current cursor position when you want it to.

⚙️ Configuration

This plugin should work out of the box with no configuration. Call to setup() is not required.

Default

require 'typst-preview'.setup {
  -- Setting this true will enable printing debug information with print()
  debug = false,

  -- Custom format string to open the output link provided with %s
  -- Example: open_cmd = 'firefox %s -P typst-preview --class typst-preview'
  open_cmd = nil,

  -- Setting this to 'always' will invert black and white in the preview
  -- Setting this to 'auto' will invert depending if the browser has enable
  -- dark mode
  invert_colors = 'never',

  -- Whether the preview will follow the cursor in the source file
  follow_cursor = true,

  -- Provide the path to binaries for dependencies.
  -- Setting this will skip the download of the binary by the plugin.
  -- Warning: Be aware that your version might be older than the one
  -- required.
  dependencies_bin = {
    -- if you are using tinymist, just set ['typst-preview'] = "tinymist".
    ['typst-preview'] = nil,
    ['websocat'] = nil
  },

  -- This function will be called to determine the root of the typst project
  get_root = function(path_of_main_file)
    return vim.fn.fnamemodify(path_of_main_file, ':p:h')
  end,

  -- This function will be called to determine the main file of the typst
  -- project.
  get_main_file = function(path_of_buffer)
    return path_of_buffer
  end,
}

❓ Comparison with other tools

The author of Enter-tainer/typst-preview wrote a good comparison here.

  • niuiic/typst-preview.nvim: Since niuiic/typst-preview.nvim uses typst-lsp, it has similar advantages and disadvantages of typst-lsp mentioned here:
    • Higher latency due to the PDF reader having a delay.
    • Does not support cross jump between code and preview.

💻 Contribution

All PRs are welcome.

Credit

This plugin wouldn't be possible without the work of Enter-tainer/typst-preview. If you like this plugin enough to star it, please consider starring Enter-tainer/typst-preview as well.

typst-preview.nvim's People

Contributors

axiomofchoices avatar calebeby avatar chomosuke avatar fr4nk1incs avatar lamprospitsillos avatar m4cey avatar nino avatar parsifa1 avatar venhance avatar voxelmc avatar wisp3rwind 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

typst-preview.nvim's Issues

Feature Request: Add command to toggle "invert_colors"

Normally I want to use the 'auto' mode to invert colors. On some occasions I would like to toggle the active state (inverted/not inverted) manually.
Currently I only see the option to edit the configuration or switch the dark mode of the browser and restart nvim/the preview.

A command or similar solution to dynamically switch the inversion state at runtime would be helpful.

Add `get_main_file` function

We have a project tree:

project_root
├── master.typ
├── subfile_1.typ
├── subfile_2.typ
├── ...
└── template.typ

Currently, one has to enter the main file of a project, run :TypstPreview and open the included subfile in order to edit it and preview the project. However, if one opens a subfile (that does not import template, etc.), it just previews it, not the whole project, which contains all the contents, template...

Ideally, there should be a get_main_file function, similar to get_root, that is user-defined and returns the file that should be preview, so that each user can decide what the main file of a project is. That way, when :TypstPreview or alternative commands are used, they create the preview of the whole project, as it is based on the master file that includes the subfiles.

Other version of typst-preview binary

First of all, thank you for your execellent plugin.

I recently find this plugin dosen't work with my typst file. But the vscode plugin works fine.

Then I came up with a hack, which is replacing the one in vim.fn.stdpath 'data' .. '/typst-preview/ by the vscode one. And it works.

I wounder if it can be possible to add a configuration option in setup() to set the path of typst-preview cli program?

Vim Plug E121: Undefined variable: do

Adding Plug 'chomosuke/typst-preview.nvim', {'tag': 'v0.3.*', do: ':TypstPreviewUpdate'} to my config causes:

E121: Undefined variable: do
E116: Invalid arguments for function plug#

My solution was to do Plug 'chomosuke/typst-preview.nvim', {'tag': 'v0.3.*'} instead and manually call ':TypstPreview

Instalation on Windows doesn't work

Hi, I am trying to install the plugin on windows, but it is failing all the time.

I've noticed that it is installing the plugin on the wrong directory

On this image, the directory on is suposed to be installed doesn't exists:

imagen

The reso of pluggins are installed on this directory:

imagen

I hope you can solve this problem, I would love to try this plugin!

Browser only produces a grey screen when running `TypstPreview`

Everything seems to be installed correctly:

Screenshot 2023-12-28 at 10 07 44 PM

When I run TypstPreview I get the following in my browser (Thorium & Firefox):

Screenshot 2023-12-28 at 10 05 15 PM

Any thoughts on what is going wrong? I'm on an M1 Mac. If there's more helpful info I can get for you all, please let me know how. I'm happy to do so.

Thank you for your work on this project!

Stuck on an old Typst-version

The newest features of Typst, such as table.cell breaks my preview. As far as I can tell from reading the merged PRs, typst 0.11.0 should work, which is where this element was added. Both my Mason and Packer are up to date (called PackerSync and updated in Mason).
My nvim config is here: nvim-config
Any help or clarifications would be much appreciated!

Choose which browser to open the preview's page

Hi, thanks for this plugin, pretty easy to setup.

There are these lines of code in the plugin's files:

local open_cmd
if M.is_macos() then
  open_cmd = 'open'
elseif M.is_windows() then
  open_cmd = 'explorer.exe'
elseif M.is_wsl() then
  open_cmd = '/mnt/c/Windows/explorer.exe'
else
  open_cmd = 'xdg-open'
end

In my case, xdg-open is used, which makes the preview open through the mime-type of my main internet browser, but I wish to open it with another browser (thus specify which command to use, instead of xdg-open).

Could you add a configuration option to use a custom command instead?

Not updating when using WSL

Hey there! I'm interested in using Typst and am a neovim user, so I found your plugin. I love the idea, but when I run TypstPreview, I get the preview but it doesn't update as I type or even when I write the changes. I can get an updated version by toggling the preview off and back on. I'm not sure if this has anything to do with me running the plugin on WSL... it's an Arch Linux install, but I also use nix. I see that the typst-preview-linux-x64 is dynamically linked, so maybe that's part of the issue.

Error in TypstPreview when writing in non-latin script

After running the command TypstPreview the system said:

Error executing vim.schedule lua callback: ...typst-preview.nvim/lua/typst-preview/servers/factory.
lua:166: attempt to perform arithmetic on local 's' (a nil value)
stack traceback:
        ...typst-preview.nvim/lua/typst-preview/servers/factory.lua:166: in function ''
        vim/_editor.lua: in function ''
        vim/_editor.lua: in function <vim/_editor.lua:0>

with a multiple stack of

Error executing vim.schedule lua callback: Vim:E474: Unidentified byte: <9a>การเกิดปฏิกิริยาเคมี","span"
:"1a00000018","position":{"page_no":165,"x":75.0,"y":70.0},"children":[]}]},{"title":"กลไกการเกิดปฏิกิ
ริยา","span":"1a00000018","position":{"page_no":166,"x":0.0,"y":0.0},"children":[{"title":"ปฏิกิริยาอาจ
มีขั้นตอน","span":"1a00000018","position":{"page_no":167,"x":75.0,"y":70.0},"children":[]},{"title":"ตั
วอย่างปฏิกิริยา","span":"1a00000018","position":{"page_no":174,"x":75.0,"y":70.0},"children":[]},{"titl
e":"ตัวอย่างปฏิกิริยา","span":"1a00000018","position":{"page_no":177,"x":75.0,"y":70.0},"children":[]},{
"title":"ตัวอย่างปฏิกิริยา","span":"1a00000018","position":{"page_no":178,"x":75.0,"y":70.0},"children":
[]},{"title":"พลังงานกับกลไกการเกิดปฏิกิริยาเคมี","span":"1
stack traceback:
        [C]: in function 'json_decode'
        ...typst-preview.nvim/lua/typst-preview/servers/factory.lua:166: in function ''
        vim/_editor.lua: in function ''
        vim/_editor.lua: in function <vim/_editor.lua:0>

How I can solve this ?

Preview stops updating on typing for large enough files

I have been writing course notes for myself and a few days ago I noticed that the preview stopped updating when I was typing, and only updated when I saved the file.

I managed to recreate a simple test case, create a new file named preview_test.typ, and add in 10905 lines of the word "Test".
Removing lines in this file still shows up in the preview with no issues, but now adding a 10906th line with the word "Test" breaks the preview, it stops updating completely.

I am not sure if this is an issue with the neovim plugin specifically or with the upstream server, could even be an issue with typst.ts. I'll keep testing to see if I can get more info. So far I only know that comments do seem to count towards the size 'threshold' and that threshold is suspiciously close to 2^16 Bytes.

Error when jumping from preview to code with line ending

Steps to reproduce:

  1. Open typst file with contents
2+2

d
d
  1. Use :TypstPreview
  2. Press line with d's in preview

Neovim gives an error, and does not move the cursor. See below for error.

My linux distribution is Arch Linux
Neovim v0.10.0
Package is installed using Lazy.nvim
Preview runs in Firefox

Config (debug=true does not change behaviour):

return {
  'chomosuke/typst-preview.nvim',
  lazy = false, -- or ft = 'typst'
  version = '0.3.*',
  config = function()
    require('typst-preview').setup { debug = true }
  end,
  build = function()
    require('typst-preview').update()
  end,
}

Full output of :mes

:mes                                                                                                                                        
[2024-05-20T20:36:28Z INFO  typst_preview] Arguments: CliArguments {                                                                        
        preview: PreviewArgs {                                                                                                              
            data_plane_host: "127.0.0.1:0",                                                                                                 
            control_plane_host: "127.0.0.1:0",                                                                                              
            enable_partial_rendering: true,                                                                                                 
            invert_colors: "never",                                                                                                         
        },                                                                                                                                  
        preview_mode: Document,                                                                                                             
[2024-05-20T20:36:28Z INFO  typst_ts_compiler::service::diag::console] /typing.typ: Compilation succeeded in 3.52758ms                      
                                                                                                                                            
Setting link                                                                                                                                
[2024-05-20T20:36:28Z INFO  typst_preview] Static file server listening on: 127.0.0.1:38629                                                 
Opening preview with command: xdg-open http://127.0.0.1:38629                                                                               
[2024-05-20T20:36:28Z DEBUG typst_ts_compiler::service::compile] CompileActor: fs event incoming Some(Update(FileChangeSet { removes: [], in
g.typ", FileSnapshot { mtime: SystemTime { tv_sec: 1716237063, tv_nsec: 642787329 }, content: FileContent { len: 9 } })] }))                
[2024-05-20T20:36:28Z INFO  typst_ts_compiler::service::diag::console] /typing.typ: compiling ...                                           
                                                                                                                                            
[2024-05-20T20:36:28Z INFO  typst_ts_compiler::service::diag::console] /typing.typ: Compilation succeeded in 60.309µs                       
                                                                                                                                            
[2024-05-20T20:36:28Z INFO  typst_preview] Peer address: 127.0.0.1:46536                                                                    
[2024-05-20T20:36:28Z INFO  typst_preview] New WebSocket connection: 127.0.0.1:46536                                                        
websocat said: {"event":"syncEditorChanges"}                                                                                                
{"event":"compileStatus","kind":"Compiling"}                                                                                                
{"event":"compileStatus","kind":"CompileSuccess"}                                                                                           
{"event":"compileStatus","kind":"Compiling"}                                                                                                
{"event":"compileStatus","kind":"CompileSuccess"}                                                                                           
[2024-05-20T20:36:28Z INFO  typst_preview] Serve frontend: Document                                                                         
[2024-05-20T20:36:29Z INFO  typst_preview] Peer address: 127.0.0.1:54812                                                                    
[2024-05-20T20:36:29Z INFO  typst_preview] New WebSocket connection: 127.0.0.1:54812                                                        
[2024-05-20T20:36:29Z DEBUG typst_preview::actor::render] OutlineRenderActor: waiting for message                                           
[2024-05-20T20:36:29Z DEBUG typst_preview::actor::render] RenderActor: waiting for message                                                  
[2024-05-20T20:36:29Z DEBUG typst_preview::actor::render] RenderActor: has_full_render: true                                                
[2024-05-20T20:36:29Z DEBUG typst_preview::actor::render] OutlineRenderActor: received message: RenderFullLatest                            
[2024-05-20T20:36:29Z DEBUG typst_preview::actor::render] OutlineRenderActor: sending outline                                               
[2024-05-20T20:36:29Z DEBUG typst_preview::actor::render] OutlineRenderActor: waiting for message                                           
websocat said: {"event":"outline","items":[]}                                                                                               
[2024-05-20T20:36:29Z DEBUG typst_preview::actor::render] RenderActor: waiting for message                                                  
[2024-05-20T20:36:31Z INFO  typst_preview::actor::render] RenderActor: resolving span: [ElementPoint { kind: 4, index: 0, fingerprint: "" },
ngerprint: "" }, ElementPoint { kind: 0, index: 1, fingerprint: "" }, ElementPoint { kind: 5, index: 3, fingerprint: "" }]                  
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] lazy spans are initializing                                              
[2024-05-20T20:36:31Z DEBUG typst_preview::actor::render] OutlineRenderActor: received message: ResolveSpan(ResolveSpanRequest([ElementPoint
 }, ElementPoint { kind: 1, index: 0, fingerprint: "" }, ElementPoint { kind: 0, index: 1, fingerprint: "" }, ElementPoint { kind: 5, index:
[2024-05-20T20:36:31Z DEBUG typst_preview::actor::render] OutlineRenderActor: sending outline                                               
[2024-05-20T20:36:31Z DEBUG typst_preview::actor::render] OutlineRenderActor: waiting for message                                           
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] pass check remote path([ElementPoint { kind: 4, index: 0, fingerprint: ""
 fingerprint: "" }, ElementPoint { kind: 0, index: 1, fingerprint: "" }, ElementPoint { kind: 5, index: 3, fingerprint: "" }])              
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] pass check remote(4, 0) => Page { region: 2 }                            
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] pass check remote(1, 0) => Group { region: 3 }                           
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] pass check remote(0, 1) => Text([(Span(351843720888320), 0), (Span(371949
), 0)])52), 0), (Span(392054431846984                                                                                                       
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] pass check remote_char_index(5, 3) => Some([(Span(351843720888320), 0), (
[2024-05-20T20:36:29Z DEBUG typst_preview::actor::render] OutlineRenderActor: received message: RenderFullLatest                            
[2024-05-20T20:36:29Z DEBUG typst_preview::actor::render] OutlineRenderActor: sending outline                                               
[2024-05-20T20:36:29Z DEBUG typst_preview::actor::render] OutlineRenderActor: waiting for message                                           
websocat said: {"event":"outline","items":[]}                                                                                               
[2024-05-20T20:36:29Z DEBUG typst_preview::actor::render] RenderActor: waiting for message                                                  
[2024-05-20T20:36:31Z INFO  typst_preview::actor::render] RenderActor: resolving span: [ElementPoint { kind: 4, index: 0, fingerprint: "" },
ngerprint: "" }, ElementPoint { kind: 0, index: 1, fingerprint: "" }, ElementPoint { kind: 5, index: 3, fingerprint: "" }]                  
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] lazy spans are initializing                                              
[2024-05-20T20:36:31Z DEBUG typst_preview::actor::render] OutlineRenderActor: received message: ResolveSpan(ResolveSpanRequest([ElementPoint
 }, ElementPoint { kind: 1, index: 0, fingerprint: "" }, ElementPoint { kind: 0, index: 1, fingerprint: "" }, ElementPoint { kind: 5, index:
[2024-05-20T20:36:31Z DEBUG typst_preview::actor::render] OutlineRenderActor: sending outline                                               
[2024-05-20T20:36:31Z DEBUG typst_preview::actor::render] OutlineRenderActor: waiting for message                                           
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] pass check remote path([ElementPoint { kind: 4, index: 0, fingerprint: ""
 fingerprint: "" }, ElementPoint { kind: 0, index: 1, fingerprint: "" }, ElementPoint { kind: 5, index: 3, fingerprint: "" }])              
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] pass check remote(4, 0) => Page { region: 2 }                            
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] pass check remote(1, 0) => Group { region: 3 }                           
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] pass check remote(0, 1) => Text([(Span(351843720888320), 0), (Span(371949
), 0)])
[2024-05-20T20:36:31Z INFO  typst_ts_core::vector::pass::span2vec] pass check remote_char_index(5, 3) => Some([(Span(351843720888320), 0), (
54431846984), 0)])                                                                                                                          
[2024-05-20T20:36:31Z INFO  typst_preview::actor::render] RenderActor: resolved span: Some((SourceSpanOffset { span: Span(351843720888320), 
 Span(392054431846984), offset: 0 }))                                                                                                       
[2024-05-20T20:36:31Z DEBUG typst_preview::actor::render] RenderActor: has_full_render: false                                               
websocat said: {"event":"outline","items":[]}                                                                                               
[2024-05-20T20:36:31Z DEBUG typst_preview::actor::typst] TypstActor: processing doc2src: (SourceSpanOffset { span: Span(351843720888320), of
pan(392054431846984), offset: 0 })                                                                                                          
[2024-05-20T20:36:31Z DEBUG typst_ts_compiler::service::compile] CompileActor: execute task                                                 
[2024-05-20T20:36:31Z DEBUG typst_ts_compiler::service::compile] CompileActor: execute task                                                 
[2024-05-20T20:36:31Z DEBUG typst_preview::actor::render] RenderActor: waiting for message                                                  
[2024-05-20T20:36:31Z DEBUG typst_ts_compiler::service::compile] CompileActor: execute task                                                 
websocat said: {"event":"editorScrollTo","filepath":"/home/jacob/Documents/typing.typ","start":[3,0],"end":[3,0]}                           
Error executing vim.schedule lua callback: ...y/typst-preview.nvim/lua/typst-preview/events/server.lua:13: Column value outside range       
stack traceback:                                                                                                                            
        [C]: in function 'nvim_win_set_cursor'                                                                                              
        ...y/typst-preview.nvim/lua/typst-preview/events/server.lua:13: in function 'editorScrollTo'                                        
        ...y/typst-preview.nvim/lua/typst-preview/events/server.lua:26: in function 'listener'                                              
        ...azy/typst-preview.nvim/lua/typst-preview/server/init.lua:83: in function 'listener'                                              
        .../typst-preview.nvim/lua/typst-preview/server/factory.lua:166: in function ''                                                     
        vim/_editor.lua: in function ''                                                                                                     
        vim/_editor.lua: in function <vim/_editor.lua:0>                                                                                    
3 0

Bug(?): Scroll doesn't always follow cursor

Havent sufficiently debugged this just yet, but wondering if it is normal for, e.g., the preview page not to scroll when I type gg to go to the top of the buffer. Sometimes I have to type something to get it to scroll, and sometimes even that doesn't work—I might have to go back into normal mode and type something again for it to finally scroll. Is this a known issue?

Live preview isn't working

The first render works, however:

  • I can't get live preview to work.
  • Scrolling in the browser does nothing in the editor.

To test:

  • I create a file with 1 in it.
  • Run :TypstPreview. This opens up a browser tab.
  • Change the 1 to 2 and save.
  • The live preview doesn't change.

I also tried to have this plugin as my only Lazy plugin, but the same thing occurs.

My config:

return {
  'chomosuke/typst-preview.nvim',
  lazy = false,
  version = '0.1.*',
  opts = {
    debug = true,
  },
  build = function() require 'typst-preview'.update() end,
}

My messages.

the first buffer autocommands not registered

when starting a new neovim instance on a typst filetype, the buffer autocmds aren't created for that file.
but the next time I open a file in that same neovim instance, things work as expected. however the first buffer is still without autocmds.
I can manually refresh things with :set filetype=typst as a workaround.

I was able to reproduce this on a clean configuration with lazy.nvim and no other plugins.

`invert_colors` setting overrides tinymist

It seems the invert_colors settings overrides the invertColors setting of tinymist.
This happen even when using the default setting.

Or maybe the issue is on tinymist side (ie. the invertColors setting is not applied).

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.