├── .gitignore ├── .gitmodules ├── LICENSE.md ├── README.md ├── ipynb-quicklook.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── tino.xcuserdatad │ └── xcschemes │ ├── ipynb-quicklook.xcscheme │ └── xcschememanagement.plist ├── ipynb-quicklook ├── .gitignore ├── GeneratePreviewForURL.m ├── GenerateThumbnailForURL.m ├── HTMLPreviewBuilder.h ├── HTMLPreviewBuilder.m ├── Info.plist ├── main.c └── template.html.in └── nbviewer.js ├── .github └── workflows │ └── test.yaml ├── .gitignore ├── LICENSE ├── README.md ├── cmd ├── README.md ├── build.sh └── stub.go ├── lib ├── nbv.js └── scaffold.html ├── preview.gif ├── tests ├── notebooks │ ├── cell-source-null.html │ ├── cell-source-null.ipynb │ ├── empty-source.html │ ├── empty-source.ipynb │ ├── headings.html │ ├── headings.ipynb │ ├── image-no-dimensions.html │ ├── image-no-dimensions.ipynb │ ├── pyout-html.html │ ├── pyout-html.ipynb │ ├── pyout-metadata.html │ ├── pyout-metadata.ipynb │ ├── pyout-svg-output.html │ ├── pyout-svg-output.ipynb │ ├── raw-cell-type.html │ ├── raw-cell-type.ipynb │ ├── repro-pr46.html │ ├── repro-pr46.ipynb │ ├── repro-pr47.html │ └── repro-pr47.ipynb ├── package.json └── test.js └── viewer.html /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.swp 3 | 4 | build/ 5 | xcuserdata/ 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxu/ipynb-quicklook/6d0f8ed50896ba769ff8a24fd4320b8d37f8475a/.gitmodules -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright © 2017 Tino Wagner 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the “Software”), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ipynb-quicklook 2 | 3 | **Note**: This plugin has now been integrated into a native macOS app, [Jupyter 4 | Notebook Viewer](https://github.com/tuxu/nbviewer-app). This is the recommended 5 | way to install the QuickLook generator. 6 | 7 | A stand-alone [Quick Look](https://en.wikipedia.org/wiki/Quick_Look) generator 8 | for [Jupyter](https://jupyter.org/)/[IPython](https://ipython.org/) notebooks on 9 | macOS. Contents are rendered on-the-fly using 10 | [nbviewer.js](https://github.com/kokes/nbviewer.js). 11 | 12 | ## Getting started 13 | 14 | - Download `ipynb-quicklook.qlgenerator` 15 | ([Releases](https://github.com/tuxu/ipynb-quicklook/releases)) 16 | - The generator is unsigned and not notarized by Apple. You need to remove the 17 | quarantine attribute like this on macOS Catalina and later 18 | ([#6](https://github.com/tuxu/ipynb-quicklook/issues/6)): 19 | ```sh 20 | xattr -d com.apple.quarantine ipynb-quicklook.qlgenerator 21 | ``` 22 | - Move the generator into `/Library/QuickLook` [^1]. You may need to run `qlmanage 23 | -r` to reset the Quick Look server and caches. 24 | - Press space whenever you encounter a `.ipynb` file. Enjoy 👍 25 | 26 | [^1]: Note that the generator must be installed globally. Installation to 27 | `~/Library/QuickLook/` is not sufficient (see 28 | [#4](https://github.com/tuxu/ipynb-quicklook/issues/4)). 29 | 30 | ## Similar projects 31 | 32 | - [jupyter-notebook-quick-look](https://github.com/jendas1/jupyter-notebook-quick-look): 33 | renders using the `nbconvert` utility. 34 | 35 | ## Acknowledgments 36 | 37 | - Ondrej Kokes for [nbviewer.js](https://github.com/kokes/nbviewer.js) 38 | 39 | ## License 40 | 41 | This project is licensed under the MIT license. See [LICENSE.md](LICENSE.md) for 42 | details. 43 | 44 | © 2017 [Tino Wagner](http://www.tinowagner.com/) 45 | -------------------------------------------------------------------------------- /ipynb-quicklook.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 219F67471E37F49800CA4392 /* GenerateThumbnailForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 219F67461E37F49800CA4392 /* GenerateThumbnailForURL.m */; }; 11 | 219F67491E37F49800CA4392 /* GeneratePreviewForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 219F67481E37F49800CA4392 /* GeneratePreviewForURL.m */; }; 12 | 219F674B1E37F49800CA4392 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 219F674A1E37F49800CA4392 /* main.c */; }; 13 | 219F67541E3AC7E100CA4392 /* HTMLPreviewBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 219F67521E3AC7E100CA4392 /* HTMLPreviewBuilder.h */; }; 14 | 219F67551E3AC7E100CA4392 /* HTMLPreviewBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 219F67531E3AC7E100CA4392 /* HTMLPreviewBuilder.m */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXFileReference section */ 18 | 219F67431E37F49800CA4392 /* ipynb-quicklook.qlgenerator */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ipynb-quicklook.qlgenerator"; sourceTree = BUILT_PRODUCTS_DIR; }; 19 | 219F67461E37F49800CA4392 /* GenerateThumbnailForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GenerateThumbnailForURL.m; sourceTree = ""; }; 20 | 219F67481E37F49800CA4392 /* GeneratePreviewForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GeneratePreviewForURL.m; sourceTree = ""; }; 21 | 219F674A1E37F49800CA4392 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 22 | 219F674C1E37F49800CA4392 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 23 | 219F67521E3AC7E100CA4392 /* HTMLPreviewBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLPreviewBuilder.h; sourceTree = ""; }; 24 | 219F67531E3AC7E100CA4392 /* HTMLPreviewBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLPreviewBuilder.m; sourceTree = ""; wrapsLines = 1; }; 25 | 40DA4F1927FF9B5100890202 /* template.html.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = template.html.in; sourceTree = ""; }; 26 | /* End PBXFileReference section */ 27 | 28 | /* Begin PBXFrameworksBuildPhase section */ 29 | 219F673F1E37F49800CA4392 /* Frameworks */ = { 30 | isa = PBXFrameworksBuildPhase; 31 | buildActionMask = 2147483647; 32 | files = ( 33 | ); 34 | runOnlyForDeploymentPostprocessing = 0; 35 | }; 36 | /* End PBXFrameworksBuildPhase section */ 37 | 38 | /* Begin PBXGroup section */ 39 | 219F67391E37F49800CA4392 = { 40 | isa = PBXGroup; 41 | children = ( 42 | 219F67451E37F49800CA4392 /* ipynb-quicklook */, 43 | 219F67441E37F49800CA4392 /* Products */, 44 | ); 45 | sourceTree = ""; 46 | }; 47 | 219F67441E37F49800CA4392 /* Products */ = { 48 | isa = PBXGroup; 49 | children = ( 50 | 219F67431E37F49800CA4392 /* ipynb-quicklook.qlgenerator */, 51 | ); 52 | name = Products; 53 | sourceTree = ""; 54 | }; 55 | 219F67451E37F49800CA4392 /* ipynb-quicklook */ = { 56 | isa = PBXGroup; 57 | children = ( 58 | 40DA4F1927FF9B5100890202 /* template.html.in */, 59 | 219F67461E37F49800CA4392 /* GenerateThumbnailForURL.m */, 60 | 219F67521E3AC7E100CA4392 /* HTMLPreviewBuilder.h */, 61 | 219F67531E3AC7E100CA4392 /* HTMLPreviewBuilder.m */, 62 | 219F67481E37F49800CA4392 /* GeneratePreviewForURL.m */, 63 | 219F674A1E37F49800CA4392 /* main.c */, 64 | 219F674C1E37F49800CA4392 /* Info.plist */, 65 | ); 66 | path = "ipynb-quicklook"; 67 | sourceTree = ""; 68 | }; 69 | /* End PBXGroup section */ 70 | 71 | /* Begin PBXHeadersBuildPhase section */ 72 | 219F67401E37F49800CA4392 /* Headers */ = { 73 | isa = PBXHeadersBuildPhase; 74 | buildActionMask = 2147483647; 75 | files = ( 76 | 219F67541E3AC7E100CA4392 /* HTMLPreviewBuilder.h in Headers */, 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | /* End PBXHeadersBuildPhase section */ 81 | 82 | /* Begin PBXNativeTarget section */ 83 | 219F67421E37F49800CA4392 /* ipynb-quicklook */ = { 84 | isa = PBXNativeTarget; 85 | buildConfigurationList = 219F674F1E37F49800CA4392 /* Build configuration list for PBXNativeTarget "ipynb-quicklook" */; 86 | buildPhases = ( 87 | 219F673E1E37F49800CA4392 /* Sources */, 88 | 219F673F1E37F49800CA4392 /* Frameworks */, 89 | 219F67401E37F49800CA4392 /* Headers */, 90 | 219F67411E37F49800CA4392 /* Resources */, 91 | 40DA4F1827FF9AC600890202 /* Run Script */, 92 | ); 93 | buildRules = ( 94 | ); 95 | dependencies = ( 96 | ); 97 | name = "ipynb-quicklook"; 98 | productName = "ipynb-quicklook"; 99 | productReference = 219F67431E37F49800CA4392 /* ipynb-quicklook.qlgenerator */; 100 | productType = "com.apple.product-type.bundle"; 101 | }; 102 | /* End PBXNativeTarget section */ 103 | 104 | /* Begin PBXProject section */ 105 | 219F673A1E37F49800CA4392 /* Project object */ = { 106 | isa = PBXProject; 107 | attributes = { 108 | BuildIndependentTargetsInParallel = YES; 109 | LastUpgradeCheck = 1500; 110 | ORGANIZATIONNAME = "Tino Wagner"; 111 | TargetAttributes = { 112 | 219F67421E37F49800CA4392 = { 113 | CreatedOnToolsVersion = 8.2.1; 114 | }; 115 | }; 116 | }; 117 | buildConfigurationList = 219F673D1E37F49800CA4392 /* Build configuration list for PBXProject "ipynb-quicklook" */; 118 | compatibilityVersion = "Xcode 3.2"; 119 | developmentRegion = en; 120 | hasScannedForEncodings = 0; 121 | knownRegions = ( 122 | en, 123 | Base, 124 | ); 125 | mainGroup = 219F67391E37F49800CA4392; 126 | productRefGroup = 219F67441E37F49800CA4392 /* Products */; 127 | projectDirPath = ""; 128 | projectRoot = ""; 129 | targets = ( 130 | 219F67421E37F49800CA4392 /* ipynb-quicklook */, 131 | ); 132 | }; 133 | /* End PBXProject section */ 134 | 135 | /* Begin PBXResourcesBuildPhase section */ 136 | 219F67411E37F49800CA4392 /* Resources */ = { 137 | isa = PBXResourcesBuildPhase; 138 | buildActionMask = 2147483647; 139 | files = ( 140 | ); 141 | runOnlyForDeploymentPostprocessing = 0; 142 | }; 143 | /* End PBXResourcesBuildPhase section */ 144 | 145 | /* Begin PBXShellScriptBuildPhase section */ 146 | 40DA4F1827FF9AC600890202 /* Run Script */ = { 147 | isa = PBXShellScriptBuildPhase; 148 | alwaysOutOfDate = 1; 149 | buildActionMask = 2147483647; 150 | files = ( 151 | ); 152 | inputFileListPaths = ( 153 | ); 154 | inputPaths = ( 155 | "$(SRCROOT)/ipynb-quicklook/template.html.in", 156 | ); 157 | name = "Run Script"; 158 | outputFileListPaths = ( 159 | ); 160 | outputPaths = ( 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | shellPath = /bin/sh; 164 | shellScript = "# needs: npm install -g inliner\nexport PATH=/opt/homebrew/bin:$PATH\necho \"Inlining JS + CSS dependencies ...\"\nset -ex\noutput_dir=\"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}\"\nmkdir -p $output_dir\noutput=\"$output_dir/template.html\"\ninliner -V\ncp \"$SRCROOT/nbviewer.js/lib/nbv.js\" \"$(dirname \"$SCRIPT_INPUT_FILE_0\")/\"\ncmdline=\"inliner -m \\\"$SCRIPT_INPUT_FILE_0\\\" > \\\"$output\\\"\"\nscript -q -t0 /dev/null sh -c \"$cmdline\"\n"; 165 | }; 166 | /* End PBXShellScriptBuildPhase section */ 167 | 168 | /* Begin PBXSourcesBuildPhase section */ 169 | 219F673E1E37F49800CA4392 /* Sources */ = { 170 | isa = PBXSourcesBuildPhase; 171 | buildActionMask = 2147483647; 172 | files = ( 173 | 219F67471E37F49800CA4392 /* GenerateThumbnailForURL.m in Sources */, 174 | 219F67551E3AC7E100CA4392 /* HTMLPreviewBuilder.m in Sources */, 175 | 219F67491E37F49800CA4392 /* GeneratePreviewForURL.m in Sources */, 176 | 219F674B1E37F49800CA4392 /* main.c in Sources */, 177 | ); 178 | runOnlyForDeploymentPostprocessing = 0; 179 | }; 180 | /* End PBXSourcesBuildPhase section */ 181 | 182 | /* Begin XCBuildConfiguration section */ 183 | 219F674D1E37F49800CA4392 /* Debug */ = { 184 | isa = XCBuildConfiguration; 185 | buildSettings = { 186 | ALWAYS_SEARCH_USER_PATHS = NO; 187 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 188 | CLANG_ANALYZER_NONNULL = YES; 189 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 190 | CLANG_CXX_LIBRARY = "libc++"; 191 | CLANG_ENABLE_MODULES = YES; 192 | CLANG_ENABLE_OBJC_ARC = YES; 193 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 194 | CLANG_WARN_BOOL_CONVERSION = YES; 195 | CLANG_WARN_COMMA = YES; 196 | CLANG_WARN_CONSTANT_CONVERSION = YES; 197 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 198 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 199 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 200 | CLANG_WARN_EMPTY_BODY = YES; 201 | CLANG_WARN_ENUM_CONVERSION = YES; 202 | CLANG_WARN_INFINITE_RECURSION = YES; 203 | CLANG_WARN_INT_CONVERSION = YES; 204 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 205 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 206 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 207 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 208 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 209 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 210 | CLANG_WARN_STRICT_PROTOTYPES = YES; 211 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 212 | CLANG_WARN_UNREACHABLE_CODE = YES; 213 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 214 | CODE_SIGN_IDENTITY = "-"; 215 | CODE_SIGN_INJECT_BASE_ENTITLEMENTS = YES; 216 | COPY_PHASE_STRIP = NO; 217 | DEAD_CODE_STRIPPING = YES; 218 | DEBUG_INFORMATION_FORMAT = dwarf; 219 | ENABLE_STRICT_OBJC_MSGSEND = YES; 220 | ENABLE_TESTABILITY = YES; 221 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 222 | GCC_C_LANGUAGE_STANDARD = gnu99; 223 | GCC_DYNAMIC_NO_PIC = NO; 224 | GCC_NO_COMMON_BLOCKS = YES; 225 | GCC_OPTIMIZATION_LEVEL = 0; 226 | GCC_PREPROCESSOR_DEFINITIONS = ( 227 | "DEBUG=1", 228 | "$(inherited)", 229 | ); 230 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 231 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 232 | GCC_WARN_UNDECLARED_SELECTOR = YES; 233 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 234 | GCC_WARN_UNUSED_FUNCTION = YES; 235 | GCC_WARN_UNUSED_VARIABLE = YES; 236 | MACOSX_DEPLOYMENT_TARGET = 10.13; 237 | MTL_ENABLE_DEBUG_INFO = YES; 238 | ONLY_ACTIVE_ARCH = YES; 239 | SDKROOT = macosx; 240 | }; 241 | name = Debug; 242 | }; 243 | 219F674E1E37F49800CA4392 /* Release */ = { 244 | isa = XCBuildConfiguration; 245 | buildSettings = { 246 | ALWAYS_SEARCH_USER_PATHS = NO; 247 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 248 | CLANG_ANALYZER_NONNULL = YES; 249 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 250 | CLANG_CXX_LIBRARY = "libc++"; 251 | CLANG_ENABLE_MODULES = YES; 252 | CLANG_ENABLE_OBJC_ARC = YES; 253 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 254 | CLANG_WARN_BOOL_CONVERSION = YES; 255 | CLANG_WARN_COMMA = YES; 256 | CLANG_WARN_CONSTANT_CONVERSION = YES; 257 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 258 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 259 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 260 | CLANG_WARN_EMPTY_BODY = YES; 261 | CLANG_WARN_ENUM_CONVERSION = YES; 262 | CLANG_WARN_INFINITE_RECURSION = YES; 263 | CLANG_WARN_INT_CONVERSION = YES; 264 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 265 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 266 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 267 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 268 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 269 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 270 | CLANG_WARN_STRICT_PROTOTYPES = YES; 271 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 272 | CLANG_WARN_UNREACHABLE_CODE = YES; 273 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 274 | CODE_SIGN_IDENTITY = "-"; 275 | CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; 276 | COPY_PHASE_STRIP = NO; 277 | DEAD_CODE_STRIPPING = YES; 278 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 279 | ENABLE_NS_ASSERTIONS = NO; 280 | ENABLE_STRICT_OBJC_MSGSEND = YES; 281 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 282 | GCC_C_LANGUAGE_STANDARD = gnu99; 283 | GCC_NO_COMMON_BLOCKS = YES; 284 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 285 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 286 | GCC_WARN_UNDECLARED_SELECTOR = YES; 287 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 288 | GCC_WARN_UNUSED_FUNCTION = YES; 289 | GCC_WARN_UNUSED_VARIABLE = YES; 290 | MACOSX_DEPLOYMENT_TARGET = 10.13; 291 | MTL_ENABLE_DEBUG_INFO = NO; 292 | SDKROOT = macosx; 293 | }; 294 | name = Release; 295 | }; 296 | 219F67501E37F49800CA4392 /* Debug */ = { 297 | isa = XCBuildConfiguration; 298 | buildSettings = { 299 | CODE_SIGN_STYLE = Manual; 300 | COMBINE_HIDPI_IMAGES = YES; 301 | DEAD_CODE_STRIPPING = YES; 302 | DEVELOPMENT_TEAM = ""; 303 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 304 | INFOPLIST_FILE = "ipynb-quicklook/Info.plist"; 305 | INSTALL_PATH = /Library/QuickLook; 306 | MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; 307 | PRODUCT_BUNDLE_IDENTIFIER = "com.tinowagner.ipynb-quicklook"; 308 | PRODUCT_NAME = "$(TARGET_NAME)"; 309 | PROVISIONING_PROFILE_SPECIFIER = ""; 310 | WRAPPER_EXTENSION = qlgenerator; 311 | }; 312 | name = Debug; 313 | }; 314 | 219F67511E37F49800CA4392 /* Release */ = { 315 | isa = XCBuildConfiguration; 316 | buildSettings = { 317 | CODE_SIGN_STYLE = Manual; 318 | COMBINE_HIDPI_IMAGES = YES; 319 | DEAD_CODE_STRIPPING = YES; 320 | DEVELOPMENT_TEAM = ""; 321 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 322 | INFOPLIST_FILE = "ipynb-quicklook/Info.plist"; 323 | INSTALL_PATH = /Library/QuickLook; 324 | MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; 325 | PRODUCT_BUNDLE_IDENTIFIER = "com.tinowagner.ipynb-quicklook"; 326 | PRODUCT_NAME = "$(TARGET_NAME)"; 327 | PROVISIONING_PROFILE_SPECIFIER = ""; 328 | WRAPPER_EXTENSION = qlgenerator; 329 | }; 330 | name = Release; 331 | }; 332 | /* End XCBuildConfiguration section */ 333 | 334 | /* Begin XCConfigurationList section */ 335 | 219F673D1E37F49800CA4392 /* Build configuration list for PBXProject "ipynb-quicklook" */ = { 336 | isa = XCConfigurationList; 337 | buildConfigurations = ( 338 | 219F674D1E37F49800CA4392 /* Debug */, 339 | 219F674E1E37F49800CA4392 /* Release */, 340 | ); 341 | defaultConfigurationIsVisible = 0; 342 | defaultConfigurationName = Release; 343 | }; 344 | 219F674F1E37F49800CA4392 /* Build configuration list for PBXNativeTarget "ipynb-quicklook" */ = { 345 | isa = XCConfigurationList; 346 | buildConfigurations = ( 347 | 219F67501E37F49800CA4392 /* Debug */, 348 | 219F67511E37F49800CA4392 /* Release */, 349 | ); 350 | defaultConfigurationIsVisible = 0; 351 | defaultConfigurationName = Release; 352 | }; 353 | /* End XCConfigurationList section */ 354 | }; 355 | rootObject = 219F673A1E37F49800CA4392 /* Project object */; 356 | } 357 | -------------------------------------------------------------------------------- /ipynb-quicklook.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ipynb-quicklook.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ipynb-quicklook.xcodeproj/xcuserdata/tino.xcuserdatad/xcschemes/ipynb-quicklook.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /ipynb-quicklook.xcodeproj/xcuserdata/tino.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ipynb-quicklook.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 219F67421E37F49800CA4392 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ipynb-quicklook/.gitignore: -------------------------------------------------------------------------------- 1 | nbv.js 2 | -------------------------------------------------------------------------------- /ipynb-quicklook/GeneratePreviewForURL.m: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import QuickLook; 3 | 4 | #include "HTMLPreviewBuilder.h" 5 | 6 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); 7 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); 8 | 9 | /* ----------------------------------------------------------------------------- 10 | Generate a preview for file 11 | 12 | This function's job is to create preview for designated file 13 | ----------------------------------------------------------------------------- */ 14 | 15 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) 16 | { 17 | @autoreleasepool { 18 | // Load file contents 19 | NSURL *nsurl = (__bridge NSURL *)url; 20 | NSData *data = [NSData dataWithContentsOfURL:nsurl]; 21 | 22 | if (!data) { 23 | return ioErr; 24 | } 25 | 26 | // Aborted already? 27 | if (QLPreviewRequestIsCancelled(preview)) { 28 | return noErr; 29 | } 30 | 31 | // Build HTML preview 32 | HTMLPreviewBuilder *builder = [[HTMLPreviewBuilder alloc] init]; 33 | NSString *html = [builder previewForNotebookData: data]; 34 | 35 | QLPreviewRequestSetDataRepresentation(preview, 36 | (__bridge CFDataRef)[html dataUsingEncoding:NSUTF8StringEncoding], 37 | kUTTypeHTML, 38 | NULL); 39 | } 40 | return noErr; 41 | } 42 | 43 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview) 44 | { 45 | // Implement only if supported 46 | } 47 | -------------------------------------------------------------------------------- /ipynb-quicklook/GenerateThumbnailForURL.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); 6 | void CancelThumbnailGeneration(void *thisInterface, QLThumbnailRequestRef thumbnail); 7 | 8 | /* ----------------------------------------------------------------------------- 9 | Generate a thumbnail for file 10 | 11 | This function's job is to create thumbnail for designated file as fast as possible 12 | ----------------------------------------------------------------------------- */ 13 | 14 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize) 15 | { 16 | // To complete your generator please implement the function GenerateThumbnailForURL in GenerateThumbnailForURL.c 17 | return noErr; 18 | } 19 | 20 | void CancelThumbnailGeneration(void *thisInterface, QLThumbnailRequestRef thumbnail) 21 | { 22 | // Implement only if supported 23 | } 24 | -------------------------------------------------------------------------------- /ipynb-quicklook/HTMLPreviewBuilder.h: -------------------------------------------------------------------------------- 1 | // 2 | // HTMLPreviewBuilder.h 3 | // ipynb-quicklook 4 | // 5 | // Created by Tino Wagner on 27.01.17. 6 | // Copyright © 2017 Tino Wagner. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HTMLPreviewBuilder : NSObject 12 | 13 | - (NSString *)previewForNotebookData: (NSData*) data; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ipynb-quicklook/HTMLPreviewBuilder.m: -------------------------------------------------------------------------------- 1 | // 2 | // HTMLPreviewBuilder.m 3 | // ipynb-quicklook 4 | // 5 | // Created by Tino Wagner on 27.01.17. 6 | // Copyright © 2017 Tino Wagner. All rights reserved. 7 | // 8 | 9 | #import "HTMLPreviewBuilder.h" 10 | 11 | @implementation HTMLPreviewBuilder 12 | 13 | - (NSString *)previewForNotebookData: (NSData*) data { 14 | NSError *error; 15 | 16 | NSBundle *bundle = [NSBundle bundleForClass:[HTMLPreviewBuilder class]]; 17 | NSURL *templateFile = [bundle URLForResource:@"template" withExtension:@"html"]; 18 | NSString *template = [[NSString alloc] initWithContentsOfURL:templateFile 19 | encoding:NSUTF8StringEncoding 20 | error:&error]; 21 | if (template == nil) { 22 | return @"Error loading template"; 23 | } 24 | 25 | // Make sure we have valid JSON data 26 | id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; 27 | if (json == nil) { 28 | return @"Invalid JSON data"; 29 | } 30 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:json options:0 error:&error]; 31 | NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 32 | 33 | NSMutableString *html = [[NSMutableString alloc] initWithString:template]; 34 | [html replaceOccurrencesOfString:@"%notebook-json%" 35 | withString:jsonString 36 | options:NSLiteralSearch 37 | range:NSMakeRange(0, html.length)]; 38 | return html; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /ipynb-quicklook/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDocumentTypes 8 | 9 | 10 | CFBundleTypeRole 11 | QLGenerator 12 | LSItemContentTypes 13 | 14 | org.jupyter.ipynb 15 | 16 | 17 | 18 | CFBundleExecutable 19 | $(EXECUTABLE_NAME) 20 | CFBundleIdentifier 21 | $(PRODUCT_BUNDLE_IDENTIFIER) 22 | CFBundleInfoDictionaryVersion 23 | 6.0 24 | CFBundleName 25 | $(PRODUCT_NAME) 26 | CFBundleShortVersionString 27 | 0.1.5 28 | CFBundleVersion 29 | 1 30 | CFPlugInDynamicRegisterFunction 31 | 32 | CFPlugInDynamicRegistration 33 | NO 34 | CFPlugInFactories 35 | 36 | 0FED579A-300A-4930-9A2F-C163A43D3DD4 37 | QuickLookGeneratorPluginFactory 38 | 39 | CFPlugInTypes 40 | 41 | 5E2D9680-5022-40FA-B806-43349622E5B9 42 | 43 | 0FED579A-300A-4930-9A2F-C163A43D3DD4 44 | 45 | 46 | CFPlugInUnloadFunction 47 | 48 | NSHumanReadableCopyright 49 | Copyright © 2017 Tino Wagner. All rights reserved. 50 | QLNeedsToBeRunInMainThread 51 | 52 | QLPreviewHeight 53 | 600 54 | QLPreviewWidth 55 | 800 56 | QLSupportsConcurrentRequests 57 | 58 | QLThumbnailMinimumSize 59 | 17 60 | UTImportedTypeDeclarations 61 | 62 | 63 | UTTypeConformsTo 64 | 65 | public.json 66 | public.text 67 | 68 | UTTypeDescription 69 | Jupyter Notebook Document 70 | UTTypeIdentifier 71 | org.jupyter.ipynb 72 | UTTypeReferenceURL 73 | http://jupyter.org/ 74 | UTTypeTagSpecification 75 | 76 | public.filename-extension 77 | ipynb 78 | public.mime-type 79 | application/x-ipynb+json 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /ipynb-quicklook/main.c: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | // 3 | // DO NO MODIFY THE CONTENT OF THIS FILE 4 | // 5 | // This file contains the generic CFPlug-in code necessary for your generator 6 | // To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c 7 | // 8 | //============================================================================== 9 | 10 | 11 | 12 | 13 | 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | // ----------------------------------------------------------------------------- 21 | // constants 22 | // ----------------------------------------------------------------------------- 23 | 24 | // Don't modify this line 25 | #define PLUGIN_ID "0FED579A-300A-4930-9A2F-C163A43D3DD4" 26 | 27 | // 28 | // Below is the generic glue code for all plug-ins. 29 | // 30 | // You should not have to modify this code aside from changing 31 | // names if you decide to change the names defined in the Info.plist 32 | // 33 | 34 | 35 | // ----------------------------------------------------------------------------- 36 | // typedefs 37 | // ----------------------------------------------------------------------------- 38 | 39 | // The thumbnail generation function to be implemented in GenerateThumbnailForURL.c 40 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); 41 | void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail); 42 | 43 | // The preview generation function to be implemented in GeneratePreviewForURL.c 44 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); 45 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); 46 | 47 | // The layout for an instance of QuickLookGeneratorPlugIn 48 | typedef struct __QuickLookGeneratorPluginType 49 | { 50 | void *conduitInterface; 51 | CFUUIDRef factoryID; 52 | UInt32 refCount; 53 | } QuickLookGeneratorPluginType; 54 | 55 | // ----------------------------------------------------------------------------- 56 | // prototypes 57 | // ----------------------------------------------------------------------------- 58 | // Forward declaration for the IUnknown implementation. 59 | // 60 | 61 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID); 62 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance); 63 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); 64 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); 65 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance); 66 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance); 67 | 68 | // ----------------------------------------------------------------------------- 69 | // myInterfaceFtbl definition 70 | // ----------------------------------------------------------------------------- 71 | // The QLGeneratorInterfaceStruct function table. 72 | // 73 | static QLGeneratorInterfaceStruct myInterfaceFtbl = { 74 | NULL, 75 | QuickLookGeneratorQueryInterface, 76 | QuickLookGeneratorPluginAddRef, 77 | QuickLookGeneratorPluginRelease, 78 | NULL, 79 | NULL, 80 | NULL, 81 | NULL 82 | }; 83 | 84 | 85 | // ----------------------------------------------------------------------------- 86 | // AllocQuickLookGeneratorPluginType 87 | // ----------------------------------------------------------------------------- 88 | // Utility function that allocates a new instance. 89 | // You can do some initial setup for the generator here if you wish 90 | // like allocating globals etc... 91 | // 92 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID) 93 | { 94 | QuickLookGeneratorPluginType *theNewInstance; 95 | 96 | theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType)); 97 | memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType)); 98 | 99 | /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */ 100 | theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct)); 101 | memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct)); 102 | 103 | /* Retain and keep an open instance refcount for each factory. */ 104 | theNewInstance->factoryID = CFRetain(inFactoryID); 105 | CFPlugInAddInstanceForFactory(inFactoryID); 106 | 107 | /* This function returns the IUnknown interface so set the refCount to one. */ 108 | theNewInstance->refCount = 1; 109 | return theNewInstance; 110 | } 111 | 112 | // ----------------------------------------------------------------------------- 113 | // DeallocQuickLookGeneratorPluginType 114 | // ----------------------------------------------------------------------------- 115 | // Utility function that deallocates the instance when 116 | // the refCount goes to zero. 117 | // In the current implementation generator interfaces are never deallocated 118 | // but implement this as this might change in the future 119 | // 120 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance) 121 | { 122 | CFUUIDRef theFactoryID; 123 | 124 | theFactoryID = thisInstance->factoryID; 125 | /* Free the conduitInterface table up */ 126 | free(thisInstance->conduitInterface); 127 | 128 | /* Free the instance structure */ 129 | free(thisInstance); 130 | if (theFactoryID){ 131 | CFPlugInRemoveInstanceForFactory(theFactoryID); 132 | CFRelease(theFactoryID); 133 | } 134 | } 135 | 136 | // ----------------------------------------------------------------------------- 137 | // QuickLookGeneratorQueryInterface 138 | // ----------------------------------------------------------------------------- 139 | // Implementation of the IUnknown QueryInterface function. 140 | // 141 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) 142 | { 143 | CFUUIDRef interfaceID; 144 | 145 | interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); 146 | 147 | if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){ 148 | /* If the Right interface was requested, bump the ref count, 149 | * set the ppv parameter equal to the instance, and 150 | * return good status. 151 | */ 152 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL; 153 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration; 154 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL; 155 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration; 156 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance); 157 | *ppv = thisInstance; 158 | CFRelease(interfaceID); 159 | return S_OK; 160 | }else{ 161 | /* Requested interface unknown, bail with error. */ 162 | *ppv = NULL; 163 | CFRelease(interfaceID); 164 | return E_NOINTERFACE; 165 | } 166 | } 167 | 168 | // ----------------------------------------------------------------------------- 169 | // QuickLookGeneratorPluginAddRef 170 | // ----------------------------------------------------------------------------- 171 | // Implementation of reference counting for this type. Whenever an interface 172 | // is requested, bump the refCount for the instance. NOTE: returning the 173 | // refcount is a convention but is not required so don't rely on it. 174 | // 175 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance) 176 | { 177 | ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1; 178 | return ((QuickLookGeneratorPluginType*) thisInstance)->refCount; 179 | } 180 | 181 | // ----------------------------------------------------------------------------- 182 | // QuickLookGeneratorPluginRelease 183 | // ----------------------------------------------------------------------------- 184 | // When an interface is released, decrement the refCount. 185 | // If the refCount goes to zero, deallocate the instance. 186 | // 187 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance) 188 | { 189 | ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1; 190 | if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){ 191 | DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance ); 192 | return 0; 193 | }else{ 194 | return ((QuickLookGeneratorPluginType*) thisInstance )->refCount; 195 | } 196 | } 197 | 198 | // ----------------------------------------------------------------------------- 199 | // QuickLookGeneratorPluginFactory 200 | // ----------------------------------------------------------------------------- 201 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) 202 | { 203 | QuickLookGeneratorPluginType *result; 204 | CFUUIDRef uuid; 205 | 206 | /* If correct type is being requested, allocate an 207 | * instance of kQLGeneratorTypeID and return the IUnknown interface. 208 | */ 209 | if (CFEqual(typeID,kQLGeneratorTypeID)){ 210 | uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); 211 | result = AllocQuickLookGeneratorPluginType(uuid); 212 | CFRelease(uuid); 213 | return result; 214 | } 215 | /* If the requested type is incorrect, return NULL. */ 216 | return NULL; 217 | } 218 | 219 | -------------------------------------------------------------------------------- /ipynb-quicklook/template.html.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 |
23 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /nbviewer.js/.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Testing 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | matrix: 11 | node-version: [10.x, 12.x, 14.x, 15.x] 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Use Node.js ${{ matrix.node-version }} 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: ${{ matrix.node-version }} 19 | - name: Install dependencies 20 | run: npm install --prefix tests/ 21 | - name: Render notebooks 22 | run: node tests/test.js tests/notebooks/ 23 | -------------------------------------------------------------------------------- /nbviewer.js/.gitignore: -------------------------------------------------------------------------------- 1 | archive/* 2 | sample-notebooks/* 3 | *.swp 4 | vendor/ 5 | TODO.txt 6 | wip/* 7 | .DS_Store 8 | dist/* 9 | node_modules 10 | tmp 11 | -------------------------------------------------------------------------------- /nbviewer.js/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Ondrej Kokes 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /nbviewer.js/README.md: -------------------------------------------------------------------------------- 1 | ### client side rendering of jupyter notebooks 2 | 3 | *tl;dr: Render Jupyter notebooks straight in the browser, without a back end converter. Can be used as a library. Or if you're on macOS, you can even fire it up in Quick Look, see [ipynb-quicklook](https://github.com/tuxu/ipynb-quicklook).* 4 | 5 | I often want to read through my Jupyter notebooks, but I rarely have my Jupyter instances running in the right folders. I can't quite use the [online nbviewer](http://nbviewer.jupyter.org/), because I don't have a public URL for these, so I resort to running dummy Jupyter instances or uploading my file as a one-time gist on Github (one I have to delete thereafter). One last possibility is `nbconvert` in the command line. 6 | 7 | I thought it could be easier and more lightweight. So I hacked together this client side rendering of Jupyter notebooks. All you need is a browser that renders an HTML file (dependent on some JavaScript and CSS, both of which can be inlined). You simply drag and drop an `.ipynb` file and it renders. It's rather fast and it supports most notebook features. I tried supporting the previous version (v3), since there are tons of examples in this version out there. 8 | 9 | [**Try a live demo**](https://kokes.github.io/nbviewer.js/viewer.html) 10 | 11 | #### NEW: Rendering Github notebooks 12 | 13 | You can now render notebooks hosted on Github. You can copy and paste their URL in the viewer, linked above, or you can save this following link as a bookmark: 14 | 15 | ``` 16 | javascript:(function(){location.href="https://kokes.github.io/nbviewer.js/viewer.html#"+btoa(location.href);})(); 17 | ``` 18 | 19 | Clicking this while on Github, looking at a notebook, will launch our nbviewer with this notebook rendered here instead. You'll also get a permanent link for you to share. 20 | 21 | #### Usage 22 | 23 | There are two ways one can use this. You can use the library itself, there is just a single public method, you call `nbv.render(data, target)`, where `data` is the JSON representation of your Jupyter notebook and `target` is the node where the notebook is to be rendered. 24 | 25 | Or you can use [the demo](https://kokes.github.io/nbviewer.js/viewer.html) (or a local copy), which is just a simple wrapper of the library, with dropzones and other basic features. There is no data being transferred anywhere, so feel free to bookmark it and use it. 26 | 27 | ### Tech details 28 | It's rather simple at this point, all the DOM manipulation is written in vanilla JavaScript, Markdown rendering goes through [marked.js](https://github.com/chjj/marked), syntax highlighting is administered by [Prism.js](http://prismjs.com/). The example implementation leverages a few goodies from modern web design, like File API or drag&drops, so a fairly modern browser is necessary. 29 | 30 | #### Showcase 31 | 32 | ![screencast](https://raw.githubusercontent.com/kokes/nbviewer.js/master/preview.gif) 33 | 34 | 35 | #### Contact 36 | 37 | Drop me an email (ondrej.kokes@gmail.com) or tweet at me ([@pndrej](https://twitter.com/pndrej)) if you have any questions or suggestions. Contributions welcome. 38 | -------------------------------------------------------------------------------- /nbviewer.js/cmd/README.md: -------------------------------------------------------------------------------- 1 | Render a notebook upon a double click. **Currently extremely experimental.** 2 | 3 | You'll need `bash` and a working `Go` environment. Then just launch the build script, `./build.sh`, and you're good to go. You may want to comment out some of the cross compilation lines. 4 | 5 | TODO: 6 | - figure out a way to launch it as default on a mac/unix 7 | - add link to repo at the end of the HTML, so people know where to complain (also that this is a pre-alpha thing) -------------------------------------------------------------------------------- /nbviewer.js/cmd/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | js=`cat ../lib/nbv.js | base64 -w 0` 3 | html=`cat ../lib/scaffold.html | base64 -w 0` 4 | 5 | cat stub.go | sed "s|%js%|$js|g" | sed "s|%html%|$html|g" > nbview.go 6 | 7 | mkdir ../dist 8 | 9 | GOOS=windows GOARCH=amd64 go build -ldflags -w -o ../dist/nbview.exe nbview.go 10 | GOOS=darwin GOARCH=amd64 go build -ldflags -w -o ../dist/nbview_darwin nbview.go 11 | GOOS=linux GOARCH=amd64 go build -ldflags -w -o ../dist/nbview_linux nbview.go 12 | 13 | rm nbview.go 14 | -------------------------------------------------------------------------------- /nbviewer.js/cmd/stub.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/base64" 5 | "io/ioutil" 6 | "log" 7 | "os" 8 | "os/exec" 9 | "path/filepath" 10 | "runtime" 11 | ) 12 | 13 | func main() { 14 | if len(os.Args) != 2 { 15 | log.Fatal("Not supplied a filename") 16 | } 17 | 18 | // read input notebook 19 | fn := os.Args[1] 20 | cn, err := ioutil.ReadFile(fn) 21 | if err != nil { 22 | log.Fatal(err) 23 | } 24 | 25 | tdir, err := ioutil.TempDir("", "nb_") 26 | if err != nil { 27 | log.Fatal(err) 28 | } 29 | 30 | dt := map[string][]byte{ 31 | "index.html": []byte(`%html%`), 32 | "nbv.js": []byte(`%js%`), 33 | } 34 | 35 | for fn, vl := range dt { 36 | pt, _ := base64.StdEncoding.DecodeString(string(vl)) 37 | if err := ioutil.WriteFile(filepath.Join(tdir, fn), pt, 0666); err != nil { 38 | log.Fatal(err) 39 | } 40 | } 41 | if err := ioutil.WriteFile(filepath.Join(tdir, "notebook.js"), append([]byte("var nb = "), cn...), 0666); err != nil { 42 | log.Fatal(err) 43 | } 44 | 45 | // launch browser 46 | tfn := filepath.Join(tdir, "index.html") 47 | 48 | var eerr error 49 | switch runtime.GOOS { 50 | case "windows": 51 | eerr = exec.Command("cmd", "/c", "start", tfn).Start() 52 | case "darwin": 53 | eerr = exec.Command("open", tfn).Start() 54 | case "linux", "freebsd", "netbsd", "openbsd": 55 | eerr = exec.Command("xdg-open", tfn).Start() 56 | default: 57 | log.Fatalf("%s not supported", runtime.GOOS) 58 | } 59 | if eerr != nil { 60 | log.Fatal(eerr) 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /nbviewer.js/lib/nbv.js: -------------------------------------------------------------------------------- 1 | const nbv_constructor = (function(document, deps) { 2 | "use strict"; 3 | 4 | var d = document; 5 | var st = {}; // settings 6 | 7 | function render_ipynb(obj, target, settings) { 8 | st = settings || {}; 9 | 10 | st.nbformat = obj.nbformat; 11 | if (st.nbformat < 3) { 12 | throw new Error('Format of the notebook too old'); 13 | } 14 | 15 | if (st.nbformat > 3) { 16 | st.lang = (obj.metadata.kernelspec || {'language': null}).language; 17 | } 18 | 19 | // wipe all inner elements of our target 20 | while (target.firstChild) { 21 | target.removeChild(target.firstChild); 22 | } 23 | var t = d.createElement('div'); 24 | t.setAttribute('style', [ 25 | 'max-width: 960px', 26 | 'border: 1px solid #ccc', 27 | 'margin: 1em auto', 28 | 'padding: 1.5em 1.5em 1.5em 7em', 29 | 'background-color: white', 30 | 'box-shadow: 0 0 10px #ccc' 31 | ].join(';')); 32 | target.appendChild(t); 33 | st.target = t; 34 | 35 | // v4 has cells directly in the object, v3 had a list of 36 | // worksheets, each with a list of cells 37 | var cells = obj.cells || function() { 38 | var ret = []; 39 | for (var j=0; j < obj.worksheets.length; j++) { 40 | ret = ret.concat(obj.worksheets[j].cells); 41 | } 42 | return ret; 43 | }(); 44 | 45 | for (var j=0; j < cells.length; j++) { 46 | var tc = cells[j]; 47 | 48 | var cell = d.createElement('div'); 49 | cell.setAttribute('style', 'padding-bottom: .5em;'); 50 | 51 | var dm = d.createElement('div'); // empty div as a fallback 52 | 53 | switch (tc.cell_type) { 54 | case 'code': 55 | dm = handle_code(tc); 56 | break; 57 | case 'markdown': 58 | dm = handle_mdown(tc.source); 59 | break; 60 | // TODO: is this v3 only or not? 61 | case 'heading': 62 | let md = "#".repeat(tc.level); 63 | md += " " + handle_multiline_strings(tc.source); 64 | dm = handle_mdown(md); 65 | break; 66 | case 'raw': 67 | dm.appendChild(document.createTextNode(handle_multiline_strings(tc.source))); 68 | break; 69 | default: 70 | throw new Error('Unsupported cell type: ' + tc.cell_type); 71 | } 72 | cell.appendChild(dm); 73 | t.appendChild(cell); 74 | } 75 | 76 | // style all dataframes 77 | // hint: https://davidwalsh.name/add-rules-stylesheets 78 | var sheet = (function() { 79 | var style = document.createElement('style'); 80 | document.head.appendChild(style); 81 | return style.sheet; 82 | })(); 83 | sheet.insertRule('table.dataframe { border-collapse: collapse; }') 84 | sheet.insertRule('table.dataframe, table.dataframe td, table.dataframe th { border: none; }') 85 | sheet.insertRule('table.dataframe th { font-weight: bold; }') 86 | sheet.insertRule('table.dataframe th, table.dataframe td { padding: .4em .5em; }') 87 | sheet.insertRule('table.dataframe tbody { border-top: 1px solid #4c4c4c; }') 88 | sheet.insertRule('table.dataframe tbody th { text-align: right; }') 89 | sheet.insertRule('table.dataframe tbody tr:nth-child(odd) { background-color: #f5f5f5; }') 90 | } 91 | 92 | function excount(cell, tin) { 93 | var cc = d.createElement('span'); 94 | cc.setAttribute('style', [ 95 | 'display: block', 96 | 'position: absolute', 97 | 'top: ' + (tin ? '5px' : '0 !important'), 98 | 'left: -7.5em', 99 | 'width: 7em', 100 | 'font-family: monospace', 101 | 'text-align: right', 102 | 'color: ' + (tin ? '#303fba' : '#de4815') 103 | ].join(';')); 104 | cc.textContent = (tin ? 'In': 'Out') + ' [' + 105 | ((!cell.execution_count && !cell.prompt_number) ? ' ' : 106 | (cell.execution_count || cell.prompt_number)) + ']:'; 107 | return cc; 108 | } 109 | 110 | // receives cell, outputs DOM 111 | function handle_code(cell) { 112 | var el = d.createElement('div'); // container for it all 113 | el.style.position = 'relative'; // for excount positioning 114 | 115 | el.appendChild(excount(cell, true)); 116 | 117 | var pre = d.createElement('pre'); 118 | // because code may also be within markdown: 119 | pre.setAttribute('style', [ 120 | 'background: #f7f7f7', 121 | 'border: 1px solid #cfcfcf', 122 | 'padding: .4em', 123 | 'margin-bottom: 0', 124 | 'margin-top: 0', 125 | 'border-radius: 2px', 126 | 'min-height: .85em' 127 | ].join(';')); 128 | var code = d.createElement('code'); 129 | 130 | // if (st.hasOwnProperty('lang')) 131 | code.setAttribute('class', 'language-' + st.lang || cell.language); 132 | 133 | // no need to join on '\n' - newlines are in the code already (but let's be cautious) 134 | // .source for v4, .input for v3 135 | var raw_source = (cell.source || cell.input); 136 | code.textContent = handle_multiline_strings(raw_source); 137 | 138 | pre.appendChild(code); 139 | el.appendChild(pre); 140 | deps.prism.highlightElement(code); 141 | 142 | // outputs now 143 | var outp = d.createElement('div'); 144 | outp.style.margin = '1em 0 .5em 0'; 145 | 146 | for (var j=0; j < cell.outputs.length; j++) { 147 | var dm = d.createElement('div'); // wrapper 148 | dm.style.position = 'relative'; // for excount positioning 149 | var dt = cell.outputs[j]; 150 | if (dt.output_type == 'execute_result') 151 | dm.appendChild(excount(dt, false)); 152 | 153 | switch (dt.output_type) { 154 | case 'execute_result': 155 | dm.appendChild(handle_cell_output(dt)); 156 | break; 157 | case 'stream': 158 | dm.appendChild(handle_stream_output(dt)); 159 | break; 160 | case 'pyerr': // v3 161 | case 'error': // v4 162 | dm.appendChild(handle_error_cell(dt)); 163 | break; 164 | case 'display_data': 165 | if (st.nbformat > 3) { 166 | dm.appendChild(handle_cell_output(dt)); 167 | break; 168 | } 169 | // if 3, fall through to pyout 170 | case 'pyout': 171 | // legacy (v3) 172 | dm.appendChild(handle_pyout(dt)); 173 | break; 174 | default: 175 | throw new Error('Not supported output_type: ' + 176 | cell.outputs[j].output_type); 177 | } 178 | 179 | outp.appendChild(dm); 180 | } 181 | el.appendChild(outp); 182 | 183 | return el; 184 | } 185 | 186 | function handle_cell_output(dt) { 187 | var el = d.createElement('div'); 188 | el.style.minHeight = '1em'; 189 | 190 | // taken from https://github.com/jupyter/nbconvert/blob/master/nbconvert/utils/base.py 191 | // var format_priority = ['text/html', 'application/pdf', 'text/latex', 'image/svg+xml', 'image/png', 'image/jpeg', 'text/markdown', 'text/plain']; 192 | // filtering only those that are currently supported (excluding pdf, latex, markdown) 193 | var format_priority = ['text/html', 'image/svg+xml', 'image/png', 'image/jpeg', 'text/plain']; 194 | 195 | var fmt = null; 196 | for (var tfmt of format_priority) { 197 | if (dt.data.hasOwnProperty(tfmt)) { 198 | fmt = tfmt; 199 | break; 200 | } 201 | } 202 | if (!fmt) { 203 | // TODO: migrate to exceptions? Or is this not a hard fail? 204 | // throw new Error('No valid data format: ' + Object.keys(dt.data)) 205 | console.error('No valid data format: ' + Object.keys(dt.data)); 206 | return d.createElement('div'); // empty div, just so that it can be appended 207 | } 208 | 209 | var dm = d.createElement('div'); 210 | var source = handle_multiline_strings(dt.data[fmt]); 211 | switch (fmt) { 212 | case 'text/plain': 213 | dm = d.createElement('pre'); 214 | dm.style.margin = 0; 215 | dm.style.whiteSpace = 'pre-wrap'; 216 | dm.textContent = source; 217 | break; 218 | 219 | case 'text/html': 220 | dm.innerHTML = source; 221 | 222 | // we may have generated some HTML tables we need to style 223 | var dfs = dm.getElementsByClassName('dataframe'); 224 | for (var k = 0; k < dfs.length; k++) { 225 | if (dfs[k].classList.contains('dataframe')) { 226 | continue; // we style dataframes separately 227 | } 228 | dfs[k].setAttribute('style', [ 229 | 'border-collapse: collapse', 230 | 'text-align: left' 231 | // 'margin-top: 1em' 232 | ].join(';')); 233 | 234 | // let's style individual cells as well 235 | var cl = dfs[k].querySelectorAll('td, th'); 236 | for (var l=0; l < cl.length; l++) { 237 | cl[l].style.padding = '3px'; 238 | } 239 | 240 | } 241 | break; 242 | 243 | case 'image/svg+xml': 244 | dm.innerHTML = source; 245 | break; 246 | 247 | default: 248 | if (fmt.startsWith('image/')) { 249 | dm = d.createElement('img'); 250 | dm.setAttribute('src', 'data:' + fmt + ';base64,' + source); 251 | dm.setAttribute('style', 'max-width: 100%'); // avoid overflow 252 | // use width and height attributes supplied in metadata 253 | if (fmt in (dt.metadata || {})) { 254 | var metadata = dt.metadata[fmt]; 255 | if ('width' in metadata) { 256 | dm.setAttribute('width', metadata.width); 257 | } 258 | if ('height' in metadata) { 259 | dm.setAttribute('height', metadata.height); 260 | } 261 | } 262 | break; 263 | } 264 | throw new Error('Valid, but unsupported format: ' + fmt); 265 | } 266 | el.appendChild(dm); 267 | 268 | return el; 269 | } 270 | 271 | function handle_error_cell(dt) { 272 | var cn = d.createElement('pre'); 273 | var txt = handle_multiline_strings(dt.traceback); 274 | // stripping ANSI colours for now https://github.com/chalk/ansi-regex/blob/master/index.js#L3 275 | // could use a full library at some point https://github.com/drudru/ansi_up 276 | txt = txt.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, ''); 277 | cn.textContent = txt; 278 | 279 | return cn; 280 | } 281 | 282 | // inspired by Microsoft's fork: 283 | // https://github.com/Azure/ipynb-renderer/blob/82806a1ec5a19aefae9d1c8f3a87496cb0574e81/scripts/nbv.js#L316-L330 284 | function handle_multiline_strings(dt) { 285 | if (dt === undefined || dt === null) { 286 | return ""; 287 | } 288 | if (Array.isArray(dt)) { 289 | return dt.join(""); 290 | } 291 | if (typeof dt === "string") { 292 | return dt; 293 | } 294 | console.log(dt) 295 | 296 | return dt.toString(); 297 | } 298 | 299 | function handle_stream_output(dt) { 300 | // name in v4, stream in v3 301 | var outt = dt.name || dt.stream; // v4 || v3; contains 'stdout' or 'stderr' 302 | 303 | if (!dt.hasOwnProperty('text')) 304 | throw new Error('data for stream missing'); 305 | 306 | var cn = d.createElement('pre'); 307 | // stderr red background, stdout is plain white 308 | if (outt === 'stderr') { 309 | cn.setAttribute('style', 'background-color: #fdd; padding: .5em; white-space: pre-wrap'); 310 | } 311 | cn.textContent = handle_multiline_strings(dt.text); 312 | 313 | return cn; 314 | } 315 | 316 | function latexer(isDisplayMode) { 317 | return function replacer(match, m1, offset, string) { 318 | return deps.katex.renderToString(m1, { 319 | displayMode: isDisplayMode, 320 | throwOnError: false, // we do not want to stop rendering because of bad LaTeX 321 | }); 322 | } 323 | } 324 | 325 | function handle_mdown(source) { 326 | var el = d.createElement('div'); 327 | var source = handle_multiline_strings(source); 328 | var latexed = source.replace(/\$\$([\s\S]+?)\$\$/g, latexer(true)); // block-based math 329 | latexed = latexed.replace(/\$(.+?)\$/g, latexer(false)); // inline math 330 | el.innerHTML = deps.marked(latexed); 331 | 332 | return el; 333 | } 334 | 335 | // handling legacy notebooks (v3) 336 | function handle_pyout(cell) { 337 | var el = d.createElement('div'); 338 | 339 | if (cell.hasOwnProperty('prompt_number')) 340 | el.appendChild(excount(cell, false)); 341 | 342 | // var ks = Object.keys(cell) 343 | // text, png, jpeg, html -- supported 344 | // svg, latex, javascript, json, pdf, metadata -- not yet 345 | Object.keys(cell).forEach(function(k) { 346 | // TODO: are metadata in any way useful? 347 | if (['output_type', 'prompt_number', 'metadata'].indexOf(k) > -1) 348 | return; 349 | var p = d.createElement('span'); // if errs 350 | switch (k) { 351 | case 'text': 352 | p = d.createElement('pre'); 353 | p.style.margin = 0; 354 | p.textContent = handle_multiline_strings(cell[k]); 355 | break; 356 | case 'html': 357 | case 'svg': 358 | p = d.createElement('div'); 359 | // guessing here, haven't seen a v3 HTML element (TODO: remove it and test against our big dataset) 360 | p.innerHTML = handle_multiline_strings(cell[k]); 361 | break; 362 | case 'png': 363 | case 'jpeg': 364 | p = d.createElement('img'); 365 | p.setAttribute('src', 'data:' + k + ';base64,' + cell[k]); 366 | p.setAttribute('style', 'max-width: 100%'); // avoid overflow 367 | 368 | break; 369 | 370 | default: 371 | throw new Error('unsupported pyout format: ' + k); 372 | } 373 | el.appendChild(p); 374 | }); 375 | 376 | return el; 377 | } 378 | 379 | return { 380 | render: render_ipynb 381 | }; 382 | 383 | }); 384 | 385 | if (typeof module !== "undefined") { 386 | module.exports = { 387 | nbv_constructor: nbv_constructor, 388 | } 389 | } 390 | -------------------------------------------------------------------------------- /nbviewer.js/lib/scaffold.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | nbviewer.js 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 |
28 | 29 | 30 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /nbviewer.js/preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuxu/ipynb-quicklook/6d0f8ed50896ba769ff8a24fd4320b8d37f8475a/nbviewer.js/preview.gif -------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/cell-source-null.html: -------------------------------------------------------------------------------- 1 |
In [ ]:
import os 
  2 | from scipy import ndimage
  3 | from subprocess import check_output
  4 | 
  5 | import cv2
  6 | import numpy as np
  7 | from matplotlib import pyplot as plt
  8 | %matplotlib inline
In [ ]:
img_rows, img_cols= 720, 1280
  9 | im_array = cv2.imread('../input/train/LAG/img_02236.jpg',0)
 10 | template = np.zeros([ img_rows, img_cols], dtype='uint8') # initialisation of the template
 11 | template[:, :] = im_array[:,:] # I try multiple times to find the correct rectangle. 
 12 | #template /= 255.
 13 | max_d = 5
 14 | blur_d = 10
 15 | min_d = 1
 16 | 
 17 | tg_d = min_d
 18 | tg_wt = (2*tg_d+1)*(2*tg_d+1)
 19 | 
 20 | for i in range(tg_d, img_rows - tg_d - 1):
 21 |     for j in range(tg_d, img_cols - tg_d -1):
 22 |         #print(np.max(im_array[(i-d):(i+d), (j-d):(j+d)]))
 23 |         template[i, j] = np.sum(im_array[(i-tg_d):(i+tg_d), (j-tg_d):(j+tg_d)])/tg_wt
 24 |         #template[i, j] = np.max(im_array[(i-max_d):(i+max_d), (j-max_d):(j+max_d)]) - np.max(im_array[(i-min_d):(i+min_d), (j-min_d):(j+min_d)])
 25 | 
 26 | for i in range(max_d, img_rows - max_d - 1):
 27 |     for j in range(max_d, img_cols - max_d -1):
 28 |         #print(np.max(im_array[(i-d):(i+d), (j-d):(j+d)]))
 29 |         #template[i, j] = np.sum(im_array[(i-tg_d):(i+tg_d), (j-tg_d):(j+tg_d)])/tg_wt
 30 |         maxc = np.max(template[(i-max_d):(i+max_d), (j-max_d):(j+max_d)])
 31 |         minc = np.min(template[(i-min_d):(i+min_d), (j-min_d):(j+min_d)])
 32 |         template[i, j] =  (maxc-minc)*255.0/maxc
 33 |         #template[i, j] = np.max(template[(i-max_d):(i+max_d), (j-max_d):(j+max_d)]) - template[i, j]
 34 | plt.subplots(figsize=(100, 70))
 35 | plt.subplot(121),plt.imshow(template, cmap='gray') 
 36 | plt.subplot(122), plt.imshow(im_array, cmap='gray')
In [ ]:

 37 | file_name = '../input/train/LAG/img_01512.jpg' # img_00176,img_02758, img_01512
 38 | img = cv2.imread(file_name,0) 
 39 | img2 = img
 40 | w, h = template.shape[::-1]
 41 | 
 42 | # All the 6 methods for comparison in a list
 43 | methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
 44 |             'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
 45 | 
 46 | for meth in methods:
 47 |      img = img2
 48 |      method = eval(meth)
 49 |  
 50 |      # Apply template Matching
 51 |      res = cv2.matchTemplate(img,template,method)
 52 |      min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
 53 |  
 54 |      # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
 55 |      if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
 56 |          top_left = min_loc
 57 |      else:
 58 |          top_left = max_loc
 59 |      bottom_right = (top_left[0] + w, top_left[1] + h)
 60 |  
 61 |      cv2.rectangle(img,top_left, bottom_right, 255, 2)
 62 |      fig, ax = plt.subplots(figsize=(12, 7))
 63 |      plt.subplot(121),plt.imshow(res,cmap = 'gray')
 64 |      plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
 65 |      plt.subplot(122),plt.imshow(img,cmap = 'gray') #,aspect='auto'
 66 |      plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
 67 |      plt.suptitle(meth)
 68 |  
 69 |      plt.show()
In [ ]:

 70 | method = eval('cv2.TM_CCOEFF')
 71 | indexes=[1,30,40,5]
 72 | 
 73 | train_path = "../input/train/"
 74 | sub_folders = check_output(["ls", train_path]).decode("utf8").strip().split('\n')
 75 | for sub_folder in sub_folders:
 76 |     file_names = check_output(["ls", train_path+sub_folder]).decode("utf8").strip().split('\n')
 77 |     k=0
 78 |     _, ax = plt.subplots(2,2,figsize=(10, 7))
 79 |     for file_name in [file_names[x] for x in indexes]: # I take only 4 images of each group. 
 80 |         img = cv2.imread(train_path+sub_folder+"/"+file_name,0)
 81 |         img2 = img
 82 |         w, h = template.shape[::-1]
 83 |         # Apply template Matching
 84 |         res = cv2.matchTemplate(img,template,method)
 85 |         min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
 86 |         top_left = max_loc
 87 |         bottom_right = (top_left[0] + w, top_left[1] + h)
 88 |  
 89 |         cv2.rectangle(img,top_left, bottom_right, 255, 2)
 90 |         if k==0 : 
 91 |             ax[0,0].imshow(img,cmap = 'gray')
 92 |             plt.xticks([]), plt.yticks([])
 93 |         if k==1 : 
 94 |             ax[0,1].imshow(img,cmap = 'gray')
 95 |             plt.xticks([]), plt.yticks([])
 96 |         if k==2 : 
 97 |             ax[1,0].imshow(img,cmap = 'gray')
 98 |             plt.xticks([]), plt.yticks([])
 99 |         if k==3 : 
100 |             ax[1,1].imshow(img,cmap = 'gray')
101 |             plt.xticks([]), plt.yticks([])
102 |         k=k+1
103 |     plt.suptitle(sub_folder)
104 |     plt.show()

Remark :

105 |

As we can see, with a LAG template, we almost find all the LAG fish. This is good point. 106 | The other good point is that we don't find in our rectangle the other fish. Now the idea is to create the other template and do it for all the images.

107 |

Part 2

108 |

Soon....

109 |

On the same way, the goal is to detect the fish in an image.

110 |

There exist a method to find Shapes in an image. (tutorial)

111 |
In [ ]:
-------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/cell-source-null.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "kernelspec": { 4 | "display_name": "Python 3", 5 | "language": "python", 6 | "name": "python3" 7 | }, 8 | "language_info": { 9 | "codemirror_mode": { 10 | "name": "ipython", 11 | "version": 3 12 | }, 13 | "file_extension": ".py", 14 | "mimetype": "text/x-python", 15 | "name": "python", 16 | "nbconvert_exporter": "python", 17 | "pygments_lexer": "ipython3", 18 | "version": "3.5.2" 19 | } 20 | }, 21 | "nbformat": 4, 22 | "nbformat_minor": 0, 23 | "cells": [ 24 | { 25 | "cell_type": "markdown", 26 | "metadata": { 27 | "_cell_guid": "773c200f-8737-f0ec-8237-2ac523e397e5", 28 | "_active": false 29 | }, 30 | "source": null, 31 | "execution_count": null, 32 | "outputs": [], 33 | "execution_state": "idle" 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": { 39 | "_cell_guid": "ca94656a-3ee7-5d87-912d-dce3ae832a93", 40 | "_active": true 41 | }, 42 | "outputs": [], 43 | "source": "import os \nfrom scipy import ndimage\nfrom subprocess import check_output\n\nimport cv2\nimport numpy as np\nfrom matplotlib import pyplot as plt\n%matplotlib inline", 44 | "execution_state": "idle" 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": { 49 | "_cell_guid": "8db5c77b-b702-cf61-6012-458589371d1c", 50 | "_active": false 51 | }, 52 | "source": null, 53 | "execution_count": null, 54 | "outputs": [], 55 | "execution_state": "idle" 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": { 61 | "_cell_guid": "94a6bdb6-b685-330a-1a83-9f3f2d1af12b", 62 | "_active": false 63 | }, 64 | "outputs": [], 65 | "source": "img_rows, img_cols= 720, 1280\nim_array = cv2.imread('../input/train/LAG/img_02236.jpg',0)\ntemplate = np.zeros([ img_rows, img_cols], dtype='uint8') # initialisation of the template\ntemplate[:, :] = im_array[:,:] # I try multiple times to find the correct rectangle. \n#template /= 255.\nmax_d = 5\nblur_d = 10\nmin_d = 1\n\ntg_d = min_d\ntg_wt = (2*tg_d+1)*(2*tg_d+1)\n\nfor i in range(tg_d, img_rows - tg_d - 1):\n for j in range(tg_d, img_cols - tg_d -1):\n #print(np.max(im_array[(i-d):(i+d), (j-d):(j+d)]))\n template[i, j] = np.sum(im_array[(i-tg_d):(i+tg_d), (j-tg_d):(j+tg_d)])/tg_wt\n #template[i, j] = np.max(im_array[(i-max_d):(i+max_d), (j-max_d):(j+max_d)]) - np.max(im_array[(i-min_d):(i+min_d), (j-min_d):(j+min_d)])\n\nfor i in range(max_d, img_rows - max_d - 1):\n for j in range(max_d, img_cols - max_d -1):\n #print(np.max(im_array[(i-d):(i+d), (j-d):(j+d)]))\n #template[i, j] = np.sum(im_array[(i-tg_d):(i+tg_d), (j-tg_d):(j+tg_d)])/tg_wt\n maxc = np.max(template[(i-max_d):(i+max_d), (j-max_d):(j+max_d)])\n minc = np.min(template[(i-min_d):(i+min_d), (j-min_d):(j+min_d)])\n template[i, j] = (maxc-minc)*255.0/maxc\n #template[i, j] = np.max(template[(i-max_d):(i+max_d), (j-max_d):(j+max_d)]) - template[i, j]\nplt.subplots(figsize=(100, 70))\nplt.subplot(121),plt.imshow(template, cmap='gray') \nplt.subplot(122), plt.imshow(im_array, cmap='gray')", 66 | "execution_state": "idle" 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": { 71 | "_cell_guid": "21fbe05f-2175-72d7-32b2-a1d5606ac391", 72 | "_active": false 73 | }, 74 | "source": null, 75 | "execution_count": null, 76 | "outputs": [], 77 | "execution_state": "idle" 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": null, 82 | "metadata": { 83 | "_cell_guid": "894dfaaa-b673-6f85-cec5-447379ec59e1", 84 | "_active": false 85 | }, 86 | "outputs": [], 87 | "source": "\nfile_name = '../input/train/LAG/img_01512.jpg' # img_00176,img_02758, img_01512\nimg = cv2.imread(file_name,0) \nimg2 = img\nw, h = template.shape[::-1]\n\n# All the 6 methods for comparison in a list\nmethods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',\n 'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']\n\nfor meth in methods:\n img = img2\n method = eval(meth)\n \n # Apply template Matching\n res = cv2.matchTemplate(img,template,method)\n min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)\n \n # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum\n if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:\n top_left = min_loc\n else:\n top_left = max_loc\n bottom_right = (top_left[0] + w, top_left[1] + h)\n \n cv2.rectangle(img,top_left, bottom_right, 255, 2)\n fig, ax = plt.subplots(figsize=(12, 7))\n plt.subplot(121),plt.imshow(res,cmap = 'gray')\n plt.title('Matching Result'), plt.xticks([]), plt.yticks([])\n plt.subplot(122),plt.imshow(img,cmap = 'gray') #,aspect='auto'\n plt.title('Detected Point'), plt.xticks([]), plt.yticks([])\n plt.suptitle(meth)\n \n plt.show()", 88 | "execution_state": "idle" 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": { 93 | "_cell_guid": "18f39ded-64d6-234c-10c9-c6a76250a5d9", 94 | "_active": false 95 | }, 96 | "source": null, 97 | "execution_count": null, 98 | "outputs": [], 99 | "execution_state": "idle" 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "metadata": { 105 | "_cell_guid": "7544c485-55fb-f259-3b39-ffae209830b6", 106 | "_active": false 107 | }, 108 | "outputs": [], 109 | "source": "\nmethod = eval('cv2.TM_CCOEFF')\nindexes=[1,30,40,5]\n\ntrain_path = \"../input/train/\"\nsub_folders = check_output([\"ls\", train_path]).decode(\"utf8\").strip().split('\\n')\nfor sub_folder in sub_folders:\n file_names = check_output([\"ls\", train_path+sub_folder]).decode(\"utf8\").strip().split('\\n')\n k=0\n _, ax = plt.subplots(2,2,figsize=(10, 7))\n for file_name in [file_names[x] for x in indexes]: # I take only 4 images of each group. \n img = cv2.imread(train_path+sub_folder+\"/\"+file_name,0)\n img2 = img\n w, h = template.shape[::-1]\n # Apply template Matching\n res = cv2.matchTemplate(img,template,method)\n min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)\n top_left = max_loc\n bottom_right = (top_left[0] + w, top_left[1] + h)\n \n cv2.rectangle(img,top_left, bottom_right, 255, 2)\n if k==0 : \n ax[0,0].imshow(img,cmap = 'gray')\n plt.xticks([]), plt.yticks([])\n if k==1 : \n ax[0,1].imshow(img,cmap = 'gray')\n plt.xticks([]), plt.yticks([])\n if k==2 : \n ax[1,0].imshow(img,cmap = 'gray')\n plt.xticks([]), plt.yticks([])\n if k==3 : \n ax[1,1].imshow(img,cmap = 'gray')\n plt.xticks([]), plt.yticks([])\n k=k+1\n plt.suptitle(sub_folder)\n plt.show()", 110 | "execution_state": "idle" 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": { 115 | "_cell_guid": "dfc3884a-6214-0ec9-6b0f-2671acbada7e", 116 | "_active": false 117 | }, 118 | "source": "### Remark :\nAs we can see, with a LAG template, we almost find all the LAG fish. This is good point. \nThe other good point is that we don't find in our rectangle the other fish. Now the idea is to create the other template and do it for all the images. ", 119 | "execution_count": null, 120 | "outputs": [], 121 | "execution_state": "idle" 122 | }, 123 | { 124 | "cell_type": "markdown", 125 | "metadata": { 126 | "_cell_guid": "66bda0fa-2612-23ff-dea5-5d3a149490c7", 127 | "_active": false 128 | }, 129 | "source": "# Part 2\n\n### Soon.... ", 130 | "execution_count": null, 131 | "outputs": [], 132 | "execution_state": "idle" 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": { 137 | "_cell_guid": "4409dd49-a99e-206a-ec1c-397ee7f475a1", 138 | "_active": false 139 | }, 140 | "source": "\nOn the same way, the goal is to detect the fish in an image. \n\nThere exist a method to find Shapes in an image. ([*tutorial*](http://www.pyimagesearch.com/2014/10/20/finding-shapes-images-using-python-opencv/))", 141 | "execution_count": null, 142 | "outputs": [], 143 | "execution_state": "idle" 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "metadata": { 149 | "_cell_guid": "e1e99324-d020-96d7-cd94-c038e858c542", 150 | "_active": false 151 | }, 152 | "outputs": [], 153 | "source": null, 154 | "execution_state": "idle" 155 | } 156 | ] 157 | } -------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/empty-source.html: -------------------------------------------------------------------------------- 1 |

Python 3 - Tic Tac Toe

2 |

Author : Arunpandian Murugan

3 |

Email ID : arunpandian.murugan@outlook.com

4 |

Display Board

5 |
In [7]:
def display_board(my_board_entry):
  6 |     print('     |     |    \n  {0}  |  {1}  |  {2}  \n     |     |    \n-----------------\n     |     |    \n  {3}  |  {4}  |  {5}  \n     |     |    \n-----------------\n     |     |    \n  {6}  |  {7}  |  {8}  \n     |     |    \n'.format(my_board_entry[0], my_board_entry[1], my_board_entry[2], my_board_entry[3], my_board_entry[4], my_board_entry[5], my_board_entry[6], my_board_entry[7], my_board_entry[8]))

Get User Input

7 |
In [ ]:
def get_user_input(player1, player2, int_turn_counter, list_board_entry):
  8 |     
  9 |     #Variable Initialisation
 10 |     list_player_symbol = []
 11 |     list_player_symbol.append(player1)
 12 |     list_player_symbol.append(player2)
 13 |     list_input = []
 14 |     flag_get_input = 'Y'
 15 |     
 16 |     while(flag_get_input.upper() == 'Y'):
 17 |         int_board_position = int(input('Player {} --> {}, Enter the valid position number...\t'.format((int_turn_counter%2)+1, list_player_symbol[int_turn_counter%2])))
 18 |         
 19 |         if((int_board_position > 0) and (int_board_position < 10)):
 20 |             #validation check
 21 |             if(list_board_entry[int_board_position - 1] == ' '):
 22 |                 list_input.append(int_board_position)
 23 |                 list_input.append(list_player_symbol[int_turn_counter%2])
 24 |                 return(list_input)
 25 |             else:
 26 |                 print('Entered position is already filled, so kindly provide some other free position...\n')
 27 |                 flag_get_input = input('Do want to continue ...[Y/N]\t ')
 28 |                 if(flag_get_input.upper() == 'N'):
 29 |                     list_input.append('End')
 30 |                     return(list_input)
 31 |         
 32 |         elif((int_board_position < 0) or (int_board_position > 10)):
 33 |             print('Invalid position number | kindly enter the position between 1 to 9...\n')
 34 |             flag_get_input = input('Do want to continue ...[Y/N]\t ')
 35 |             if(flag_get_input.upper() == 'N'):
 36 |                 list_input.append('End')
 37 |                 return(list_input)

Clear Cell

38 |
In [9]:
def clear_cell():
 39 |     from IPython.display import clear_output
 40 |     
 41 |     for i in range(2):
 42 |         clear_output()
 43 |         
 44 |     ##import time
 45 |     ##time.sleep(2) 

Core Algorithm

46 |
In [10]:
def core_algorithm(list_board_entry):
 47 |     #variable initialise
 48 |     temp_list_board_entry = list_board_entry.copy()
 49 | 
 50 |     if(temp_list_board_entry.count('X') >= 3):
 51 |         if(temp_list_board_entry[0:3].count('X') == 3 or temp_list_board_entry[3:6].count('X') == 3 or temp_list_board_entry[6:9].count('X') == 3 or (temp_list_board_entry[0] == 'X' and temp_list_board_entry[4] == 'X' and temp_list_board_entry[8] == 'X') or (temp_list_board_entry[2] == 'X' and temp_list_board_entry[4] == 'X' and temp_list_board_entry[6] == 'X') ):
 52 |             print('Hurrah!!! Player 1 Won...')
 53 |             return 'End'
 54 |         
 55 |     elif(temp_list_board_entry[0:3].count('O') == 3 or temp_list_board_entry[3:6].count('O') == 3 or temp_list_board_entry[6:9].count('O') == 3 or (temp_list_board_entry[0] == 'O' and temp_list_board_entry[4] == 'O' and temp_list_board_entry[8] == 'O') or (temp_list_board_entry[2] == 'O' and temp_list_board_entry[4] == 'O' and temp_list_board_entry[6] == 'O') ):
 56 |         if(tuple(temp_list) in dump_set):
 57 |             print('Hurrah!!! Player 2 Won...')
 58 |             return 'End'
 59 | 

Driver Code

60 |
In [11]:
def tic_tac_toe_main():
 61 |     
 62 |     #Initalise Flag
 63 |     continue_flag = 'Y'
 64 |     
 65 |     while(continue_flag.upper() == 'Y'):
 66 |         
 67 |         #Reset the Flag
 68 |         continue_flag = ''
 69 |         
 70 |         #Variable Initialisation
 71 |         int_turn_counter = 0
 72 |         list_board_entry = [" ", " ", " ", " ", " ", " ", " ", " ", " " ]
 73 |     
 74 |         print("Welcome to Arun's Tic Tac Toe Game using Python 3\n")
 75 |     
 76 |         #Select X or O
 77 |         player_choice = input('Player 1, do you want to be X or O...\t')
 78 |     
 79 |         if(player_choice.upper() == 'X'):
 80 |     
 81 |             #iterating through game
 82 |             print('Player 1 --> X \nPlayer 2 --> O')
 83 |             while(int_turn_counter < 9):
 84 |                 list_input = get_user_input('X', 'O', int_turn_counter, list_board_entry)
 85 |             
 86 |                 if(list_input[0] == 'End'):
 87 |                     break
 88 |                     
 89 |                 #Displaying the updated board...   
 90 |                 list_board_entry[int(list_input[0]) -1] = list_input[1]
 91 |                 clear_cell()
 92 |                 display_board(list_board_entry)
 93 |             
 94 |                 flag = core_algorithm(list_board_entry) 
 95 |                 if(flag == 'End'):
 96 |                     break
 97 |                 
 98 |                 int_turn_counter += 1 
 99 |          
100 |         elif(player_choice.upper() == 'O'):
101 |         
102 |             #iterating through game
103 |             print('Player 1 --> O \nPlayer 2 --> X')
104 |             while(int_turn_counter < 9):
105 |                 list_input = get_user_input('O', 'X', int_turn_counter, list_board_entry)
106 |                 
107 |                 if(list_input[0] == 'End'):
108 |                     break
109 |                     
110 |                 #Displaying the updated board...
111 |                 list_board_entry[int(list_input[0]) - 1] = list_input[1]
112 |                 clear_cell()
113 |                 display_board(list_board_entry)
114 |             
115 |                 flag = core_algorithm(list_board_entry) 
116 |                 if(flag == 'End'):
117 |                     break
118 |                 
119 |                 int_turn_counter += 1 
120 |             
121 |         else:
122 |             print('Invalid Symbol selection...Exiting')
123 |     
124 |         if(list_input[0] == 'End' or flag == 'End'):
125 |             continue_flag = 'N'
126 |         else:
127 |             continue_flag = input('Do want to continue ...[Y/N]\t ')
In [ ]:
tic_tac_toe_main()
     |     |    
128 |      |     |     
129 |      |     |    
130 | -----------------
131 |      |     |    
132 |      |  X  |  O  
133 |      |     |    
134 | -----------------
135 |      |     |    
136 |      |     |     
137 |      |     |    
138 | 
139 | 
In [ ]:
-------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/empty-source.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "metadata": {}, 5 | "cell_type": "markdown", 6 | "source": "# Python 3 - Tic Tac Toe\n\nAuthor : Arunpandian Murugan\n\nEmail ID : arunpandian.murugan@outlook.com" 7 | }, 8 | { 9 | "metadata": {}, 10 | "cell_type": "markdown", 11 | "source": "# Display Board" 12 | }, 13 | { 14 | "metadata": { 15 | "trusted": true 16 | }, 17 | "cell_type": "code", 18 | "source": "def display_board(my_board_entry):\n print(' | | \\n {0} | {1} | {2} \\n | | \\n-----------------\\n | | \\n {3} | {4} | {5} \\n | | \\n-----------------\\n | | \\n {6} | {7} | {8} \\n | | \\n'.format(my_board_entry[0], my_board_entry[1], my_board_entry[2], my_board_entry[3], my_board_entry[4], my_board_entry[5], my_board_entry[6], my_board_entry[7], my_board_entry[8]))", 19 | "execution_count": 7, 20 | "outputs": [] 21 | }, 22 | { 23 | "metadata": {}, 24 | "cell_type": "markdown", 25 | "source": "# Get User Input" 26 | }, 27 | { 28 | "metadata": { 29 | "trusted": true 30 | }, 31 | "cell_type": "code", 32 | "source": "def get_user_input(player1, player2, int_turn_counter, list_board_entry):\n \n #Variable Initialisation\n list_player_symbol = []\n list_player_symbol.append(player1)\n list_player_symbol.append(player2)\n list_input = []\n flag_get_input = 'Y'\n \n while(flag_get_input.upper() == 'Y'):\n int_board_position = int(input('Player {} --> {}, Enter the valid position number...\\t'.format((int_turn_counter%2)+1, list_player_symbol[int_turn_counter%2])))\n \n if((int_board_position > 0) and (int_board_position < 10)):\n #validation check\n if(list_board_entry[int_board_position - 1] == ' '):\n list_input.append(int_board_position)\n list_input.append(list_player_symbol[int_turn_counter%2])\n return(list_input)\n else:\n print('Entered position is already filled, so kindly provide some other free position...\\n')\n flag_get_input = input('Do want to continue ...[Y/N]\\t ')\n if(flag_get_input.upper() == 'N'):\n list_input.append('End')\n return(list_input)\n \n elif((int_board_position < 0) or (int_board_position > 10)):\n print('Invalid position number | kindly enter the position between 1 to 9...\\n')\n flag_get_input = input('Do want to continue ...[Y/N]\\t ')\n if(flag_get_input.upper() == 'N'):\n list_input.append('End')\n return(list_input)", 33 | "execution_count": null, 34 | "outputs": [] 35 | }, 36 | { 37 | "metadata": {}, 38 | "cell_type": "markdown", 39 | "source": "# Clear Cell" 40 | }, 41 | { 42 | "metadata": { 43 | "trusted": true 44 | }, 45 | "cell_type": "code", 46 | "source": "def clear_cell():\n from IPython.display import clear_output\n \n for i in range(2):\n clear_output()\n \n ##import time\n ##time.sleep(2) ", 47 | "execution_count": 9, 48 | "outputs": [] 49 | }, 50 | { 51 | "metadata": {}, 52 | "cell_type": "markdown", 53 | "source": "## Core Algorithm" 54 | }, 55 | { 56 | "metadata": { 57 | "trusted": true 58 | }, 59 | "cell_type": "code", 60 | "source": "def core_algorithm(list_board_entry):\n #variable initialise\n temp_list_board_entry = list_board_entry.copy()\n\n if(temp_list_board_entry.count('X') >= 3):\n if(temp_list_board_entry[0:3].count('X') == 3 or temp_list_board_entry[3:6].count('X') == 3 or temp_list_board_entry[6:9].count('X') == 3 or (temp_list_board_entry[0] == 'X' and temp_list_board_entry[4] == 'X' and temp_list_board_entry[8] == 'X') or (temp_list_board_entry[2] == 'X' and temp_list_board_entry[4] == 'X' and temp_list_board_entry[6] == 'X') ):\n print('Hurrah!!! Player 1 Won...')\n return 'End'\n \n elif(temp_list_board_entry[0:3].count('O') == 3 or temp_list_board_entry[3:6].count('O') == 3 or temp_list_board_entry[6:9].count('O') == 3 or (temp_list_board_entry[0] == 'O' and temp_list_board_entry[4] == 'O' and temp_list_board_entry[8] == 'O') or (temp_list_board_entry[2] == 'O' and temp_list_board_entry[4] == 'O' and temp_list_board_entry[6] == 'O') ):\n if(tuple(temp_list) in dump_set):\n print('Hurrah!!! Player 2 Won...')\n return 'End'\n", 61 | "execution_count": 10, 62 | "outputs": [] 63 | }, 64 | { 65 | "metadata": {}, 66 | "cell_type": "markdown", 67 | "source": "# Driver Code" 68 | }, 69 | { 70 | "metadata": { 71 | "trusted": true 72 | }, 73 | "cell_type": "code", 74 | "source": "def tic_tac_toe_main():\n \n #Initalise Flag\n continue_flag = 'Y'\n \n while(continue_flag.upper() == 'Y'):\n \n #Reset the Flag\n continue_flag = ''\n \n #Variable Initialisation\n int_turn_counter = 0\n list_board_entry = [\" \", \" \", \" \", \" \", \" \", \" \", \" \", \" \", \" \" ]\n \n print(\"Welcome to Arun's Tic Tac Toe Game using Python 3\\n\")\n \n #Select X or O\n player_choice = input('Player 1, do you want to be X or O...\\t')\n \n if(player_choice.upper() == 'X'):\n \n #iterating through game\n print('Player 1 --> X \\nPlayer 2 --> O')\n while(int_turn_counter < 9):\n list_input = get_user_input('X', 'O', int_turn_counter, list_board_entry)\n \n if(list_input[0] == 'End'):\n break\n \n #Displaying the updated board... \n list_board_entry[int(list_input[0]) -1] = list_input[1]\n clear_cell()\n display_board(list_board_entry)\n \n flag = core_algorithm(list_board_entry) \n if(flag == 'End'):\n break\n \n int_turn_counter += 1 \n \n elif(player_choice.upper() == 'O'):\n \n #iterating through game\n print('Player 1 --> O \\nPlayer 2 --> X')\n while(int_turn_counter < 9):\n list_input = get_user_input('O', 'X', int_turn_counter, list_board_entry)\n \n if(list_input[0] == 'End'):\n break\n \n #Displaying the updated board...\n list_board_entry[int(list_input[0]) - 1] = list_input[1]\n clear_cell()\n display_board(list_board_entry)\n \n flag = core_algorithm(list_board_entry) \n if(flag == 'End'):\n break\n \n int_turn_counter += 1 \n \n else:\n print('Invalid Symbol selection...Exiting')\n \n if(list_input[0] == 'End' or flag == 'End'):\n continue_flag = 'N'\n else:\n continue_flag = input('Do want to continue ...[Y/N]\\t ')", 75 | "execution_count": 11, 76 | "outputs": [] 77 | }, 78 | { 79 | "metadata": { 80 | "trusted": true 81 | }, 82 | "cell_type": "code", 83 | "source": "tic_tac_toe_main()", 84 | "execution_count": null, 85 | "outputs": [ 86 | { 87 | "output_type": "stream", 88 | "text": " | | \n | | \n | | \n-----------------\n | | \n | X | O \n | | \n-----------------\n | | \n | | \n | | \n\n", 89 | "name": "stdout" 90 | } 91 | ] 92 | }, 93 | { 94 | "metadata": { 95 | "trusted": true 96 | }, 97 | "cell_type": "code", 98 | "source": "", 99 | "execution_count": null, 100 | "outputs": [] 101 | } 102 | ], 103 | "metadata": { 104 | "kernelspec": { 105 | "name": "python3", 106 | "display_name": "Python 3", 107 | "language": "python" 108 | }, 109 | "language_info": { 110 | "mimetype": "text/x-python", 111 | "nbconvert_exporter": "python", 112 | "name": "python", 113 | "pygments_lexer": "ipython3", 114 | "version": "3.5.4", 115 | "file_extension": ".py", 116 | "codemirror_mode": { 117 | "version": 3, 118 | "name": "ipython" 119 | } 120 | } 121 | }, 122 | "nbformat": 4, 123 | "nbformat_minor": 1 124 | } -------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/headings.html: -------------------------------------------------------------------------------- 1 |

Tutorial Brief

2 |

This tutorial covers the basics of contrlling the layout of IPython widgets.

3 |

We will be using the following functions to do that.

4 |
    5 |
  • display()
  • 6 |
  • widget.add_class()
  • 7 |
  • widget.set_css()
  • 8 |
9 |

Video Tutorial:

10 |

https://www.youtube.com/watch?v=8v7gVQlHJ-g

11 |

Import the library

12 |
In [1]:
from IPython.html import widgets
13 | from IPython.display import display
Default Layout "vbox" class
14 |

By default a container will have a "vbox" css class added to it.

15 |
In [2]:
v_container = widgets.ContainerWidget()
16 | 
17 | # Define Widgets
18 | for counter in range(5):
19 |     wgt_check = widgets.CheckboxWidget()
20 |     wgt_text = widgets.TextWidget(description="Name")
21 |     wgt_select = widgets.DropdownWidget(values=["Guest", "User", "Admin"])
22 | 
23 |     # Add Widgets
24 |     v_container.children += (wgt_check, wgt_text, wgt_select)
25 | 
26 | wgt_button = widgets.ButtonWidget(description="Submit")
27 | v_container.children += (wgt_button,)
28 | 
29 | # Display the container
30 | display(v_container)

Horizontal Layout with "hbox" class

31 |
In [3]:
v_container = widgets.ContainerWidget()
32 | 
33 | # Display the container
34 | display(v_container)
35 | 
36 | # Define Widgets
37 | for counter in range(5):
38 |     wgt_check = widgets.CheckboxWidget()
39 |     wgt_text = widgets.TextWidget(description="Name")
40 |     wgt_select = widgets.DropdownWidget(values=["Guest", "User", "Admin"])
41 | 
42 |     # Add Widgets
43 |     h_container = widgets.ContainerWidget()
44 |     h_container.children += (wgt_check, wgt_text, wgt_select)
45 |     v_container.children += (h_container,)
46 |     
47 |     # Change css class of the container
48 |     h_container.remove_class('vbox')
49 |     h_container.add_class('hbox')
50 | 
51 | wgt_button = widgets.ButtonWidget(description="Submit")
52 | v_container.children += (wgt_button,)
-------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/headings.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "", 4 | "signature": "sha256:c05a3fedc7549d209ef933f31aef324d989659f8f1e3525e2d32fd0854902ed6" 5 | }, 6 | "nbformat": 3, 7 | "nbformat_minor": 0, 8 | "worksheets": [ 9 | { 10 | "cells": [ 11 | { 12 | "cell_type": "heading", 13 | "level": 1, 14 | "metadata": {}, 15 | "source": [ 16 | "Tutorial Brief" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "This tutorial covers the basics of contrlling the layout of IPython widgets.\n", 24 | "\n", 25 | "We will be using the following functions to do that.\n", 26 | "\n", 27 | "- display()\n", 28 | "- widget.add_class()\n", 29 | "- widget.set_css()\n", 30 | "\n", 31 | "Video Tutorial:\n", 32 | "\n", 33 | "https://www.youtube.com/watch?v=8v7gVQlHJ-g" 34 | ] 35 | }, 36 | { 37 | "cell_type": "heading", 38 | "level": 3, 39 | "metadata": {}, 40 | "source": [ 41 | "Import the library" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "collapsed": false, 47 | "input": [ 48 | "from IPython.html import widgets\n", 49 | "from IPython.display import display" 50 | ], 51 | "language": "python", 52 | "metadata": {}, 53 | "outputs": [], 54 | "prompt_number": 1 55 | }, 56 | { 57 | "cell_type": "heading", 58 | "level": 5, 59 | "metadata": {}, 60 | "source": [ 61 | "Default Layout `\"vbox\"` class" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "By default a container will have a `\"vbox\"` css class added to it." 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "collapsed": false, 74 | "input": [ 75 | "v_container = widgets.ContainerWidget()\n", 76 | "\n", 77 | "# Define Widgets\n", 78 | "for counter in range(5):\n", 79 | " wgt_check = widgets.CheckboxWidget()\n", 80 | " wgt_text = widgets.TextWidget(description=\"Name\")\n", 81 | " wgt_select = widgets.DropdownWidget(values=[\"Guest\", \"User\", \"Admin\"])\n", 82 | "\n", 83 | " # Add Widgets\n", 84 | " v_container.children += (wgt_check, wgt_text, wgt_select)\n", 85 | "\n", 86 | "wgt_button = widgets.ButtonWidget(description=\"Submit\")\n", 87 | "v_container.children += (wgt_button,)\n", 88 | "\n", 89 | "# Display the container\n", 90 | "display(v_container)" 91 | ], 92 | "language": "python", 93 | "metadata": {}, 94 | "outputs": [], 95 | "prompt_number": 2 96 | }, 97 | { 98 | "cell_type": "heading", 99 | "level": 3, 100 | "metadata": {}, 101 | "source": [ 102 | "Horizontal Layout with `\"hbox\"` class" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "collapsed": false, 108 | "input": [ 109 | "v_container = widgets.ContainerWidget()\n", 110 | "\n", 111 | "# Display the container\n", 112 | "display(v_container)\n", 113 | "\n", 114 | "# Define Widgets\n", 115 | "for counter in range(5):\n", 116 | " wgt_check = widgets.CheckboxWidget()\n", 117 | " wgt_text = widgets.TextWidget(description=\"Name\")\n", 118 | " wgt_select = widgets.DropdownWidget(values=[\"Guest\", \"User\", \"Admin\"])\n", 119 | "\n", 120 | " # Add Widgets\n", 121 | " h_container = widgets.ContainerWidget()\n", 122 | " h_container.children += (wgt_check, wgt_text, wgt_select)\n", 123 | " v_container.children += (h_container,)\n", 124 | " \n", 125 | " # Change css class of the container\n", 126 | " h_container.remove_class('vbox')\n", 127 | " h_container.add_class('hbox')\n", 128 | "\n", 129 | "wgt_button = widgets.ButtonWidget(description=\"Submit\")\n", 130 | "v_container.children += (wgt_button,)" 131 | ], 132 | "language": "python", 133 | "metadata": {}, 134 | "outputs": [], 135 | "prompt_number": 3 136 | } 137 | ], 138 | "metadata": {} 139 | } 140 | ] 141 | } 142 | -------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/image-no-dimensions.html: -------------------------------------------------------------------------------- 1 |

Basic Gradient Descent

2 |

Gradient descent is an important algorithm for minimizing a function. Having an algorithm to minimize a function is quite powerful: you can maximize a function ff by minimizing f-f and you can solve a system of equations f1=k1,f2=k2,fr=krf_1=k_1, f_2=k_2, \cdots f_r=k_r by minimizing (f1k1)2+(f2k2)2+(frkr)2(f_1-k_1)^2+(f_2-k_2)^2+\cdots (f_r-k_r)^2.

3 |

Here's an example, in one variable, implemented in python, from https://en.wikipedia.org/wiki/Gradient_descent#Computational_examples. The program finds the minimum of 4 | f(x)=x43x3+2. f(x) =x^4−3x^3+2.

5 |
In [8]:
fig = plt.figure()
6 | axes = fig.add_axes([0.1, 0.1, 0.9, 0.7])
7 | axes.scatter(x,y);
/ext/sage/sage-8.0/local/lib/python2.7/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.
8 |   warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')
9 | 
Out [ ]:
In [ ]:
-------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/image-no-dimensions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false 7 | }, 8 | "source": [ 9 | "# Basic Gradient Descent\n", 10 | "\n", 11 | "Gradient descent is an important algorithm for minimizing a function. Having an algorithm to minimize a function is quite powerful: you can maximize a function $f$ by minimizing $-f$ and you can solve a system of equations $f_1=k_1, f_2=k_2, \\cdots f_r=k_r$ by minimizing $(f_1-k_1)^2+(f_2-k_2)^2+\\cdots (f_r-k_r)^2$. \n", 12 | "\n", 13 | "Here's an example, in one variable, implemented in python, from https://en.wikipedia.org/wiki/Gradient_descent#Computational_examples. The program finds the minimum of\n", 14 | "$ f(x) =x^4−3x^3+2. $" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 8, 20 | "metadata": { 21 | "collapsed": false 22 | }, 23 | "outputs": [ 24 | { 25 | "name": "stderr", 26 | "output_type": "stream", 27 | "text": [ 28 | "/ext/sage/sage-8.0/local/lib/python2.7/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.\n", 29 | " warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')\n" 30 | ] 31 | }, 32 | { 33 | "data": { 34 | "image/png": "91c7d819db6c86eb915f9a64c03795d9218e738a" 35 | }, 36 | "output_type": "execute_result" 37 | } 38 | ], 39 | "source": [ 40 | "fig = plt.figure()\n", 41 | "axes = fig.add_axes([0.1, 0.1, 0.9, 0.7])\n", 42 | "axes.scatter(x,y);" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 0, 48 | "metadata": { 49 | "collapsed": false 50 | }, 51 | "outputs": [ 52 | ], 53 | "source": [ 54 | ] 55 | } 56 | ], 57 | "metadata": { 58 | "kernelspec": { 59 | "display_name": "Python 2 (SageMath)", 60 | "language": "python", 61 | "name": "python2" 62 | }, 63 | "language_info": { 64 | "codemirror_mode": { 65 | "name": "ipython", 66 | "version": 2 67 | }, 68 | "file_extension": ".py", 69 | "mimetype": "text/x-python", 70 | "name": "python", 71 | "nbconvert_exporter": "python", 72 | "pygments_lexer": "ipython2", 73 | "version": "2.7.13" 74 | } 75 | }, 76 | "nbformat": 4, 77 | "nbformat_minor": 0 78 | } -------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/pyout-html.html: -------------------------------------------------------------------------------- 1 |
In [1]:
%matplotlib inline
  2 | import matplotlib.pyplot as plt
  3 | import numpy as np
  4 | %precision 4
  5 | import os, sys, glob

Using SQLite3

6 |

Willl change this to use the same example for queries and schema design

7 |
    8 |
  • Subjects - Ann, Bob, Charlie
  • 9 |
  • Tests - Liver function, Complete blood count
  • 10 |
  • Test parameters - AST, ALT, RBC, platelets, WBC (may perform all or only subset of parameters)
  • 11 |
  • Diffrent number of visits, different number of tests per visit
  • 12 |
13 |

Working example dataset

14 |

This data contains the survival time after receiving a heart transplant, the age of the patient and whether or not the survival time was censored

15 |
    16 |
  • Number of Observations - 69
  • 17 |
  • Number of Variables - 3
  • 18 |
19 |

Variable name definitions::

20 |
    21 |
  • death - Days after surgery until death
  • 22 |
  • age - age at the time of surgery
  • 23 |
  • censored - indicates if an observation is censored. 1 is uncensored
  • 24 |
25 |
In [2]:
import statsmodels.api as sm
 26 | heart = sm.datasets.heart.load_pandas().data
 27 | heart.take(np.random.choice(len(heart), 6))
Out [2]:
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 |
survivalcensorsage
32 147 1 47.5
67 13 0 28.9
49 499 0 52.2
24 1367 0 48.6
20 54 1 49.0
1 3 1 40.4
76 |
    survival  censors   age
 77 | 32       147        1  47.5
 78 | 67        13        0  28.9
 79 | 49       499        0  52.2
 80 | 24      1367        0  48.6
 81 | 20        54        1  49.0
 82 | 1          3        1  40.4
In [64]:
table_df = pd.read_hdf('dump.h5', 'tables')
 83 | table_df
Out [64]:
84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 |
NameValueAge
0 a 5 0
1 c 6 10
2 e 9 20
3 a 5 0
4 c 6 10
5 e 9 20
132 |
  Name  Value  Age
133 | 0    a      5    0
134 | 1    c      6   10
135 | 2    e      9   20
136 | 3    a      5    0
137 | 4    c      6   10
138 | 5    e      9   20
In [68]:
store.close()
In [ ]:
-------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/pyout-html.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "", 4 | "signature": "sha256:7144d40b448e5eefe830bed388c14e9e07bee9084aeefed67448abe0329fe191" 5 | }, 6 | "nbformat": 3, 7 | "nbformat_minor": 0, 8 | "worksheets": [ 9 | { 10 | "cells": [ 11 | { 12 | "cell_type": "code", 13 | "collapsed": false, 14 | "input": [ 15 | "%matplotlib inline\n", 16 | "import matplotlib.pyplot as plt\n", 17 | "import numpy as np\n", 18 | "%precision 4\n", 19 | "import os, sys, glob" 20 | ], 21 | "language": "python", 22 | "metadata": {}, 23 | "outputs": [], 24 | "prompt_number": 1 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "## Using SQLite3\n", 31 | "\n", 32 | "Willl change this to use the same example for queries and schema design\n", 33 | "\n", 34 | "* Subjects - Ann, Bob, Charlie\n", 35 | "* Tests - Liver function, Complete blood count\n", 36 | "* Test parameters - AST, ALT, RBC, platelets, WBC (may perform all or only subset of parameters)\n", 37 | "* Diffrent number of visits, different number of tests per visit" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "### Working example dataset\n", 45 | "\n", 46 | "This data contains the survival time after receiving a heart transplant, the age of the patient and whether or not the survival time was censored \n", 47 | "\n", 48 | "* Number of Observations - 69\n", 49 | "* Number of Variables - 3\n", 50 | "\n", 51 | "Variable name definitions::\n", 52 | "* death - Days after surgery until death\n", 53 | "* age - age at the time of surgery\n", 54 | "* censored - indicates if an observation is censored. 1 is uncensored" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "collapsed": false, 60 | "input": [ 61 | "import statsmodels.api as sm\n", 62 | "heart = sm.datasets.heart.load_pandas().data\n", 63 | "heart.take(np.random.choice(len(heart), 6))" 64 | ], 65 | "language": "python", 66 | "metadata": {}, 67 | "outputs": [ 68 | { 69 | "html": [ 70 | "
\n", 71 | "\n", 72 | " \n", 73 | " \n", 74 | " \n", 75 | " \n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | "
survivalcensorsage
32 147 1 47.5
67 13 0 28.9
49 499 0 52.2
24 1367 0 48.6
20 54 1 49.0
1 3 1 40.4
\n", 119 | "
" 120 | ], 121 | "metadata": {}, 122 | "output_type": "pyout", 123 | "prompt_number": 2, 124 | "text": [ 125 | " survival censors age\n", 126 | "32 147 1 47.5\n", 127 | "67 13 0 28.9\n", 128 | "49 499 0 52.2\n", 129 | "24 1367 0 48.6\n", 130 | "20 54 1 49.0\n", 131 | "1 3 1 40.4" 132 | ] 133 | } 134 | ], 135 | "prompt_number": 2 136 | }, 137 | { 138 | "cell_type": "code", 139 | "collapsed": false, 140 | "input": [ 141 | "table_df = pd.read_hdf('dump.h5', 'tables')\n", 142 | "table_df" 143 | ], 144 | "language": "python", 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "html": [ 149 | "
\n", 150 | "\n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | "
NameValueAge
0 a 5 0
1 c 6 10
2 e 9 20
3 a 5 0
4 c 6 10
5 e 9 20
\n", 198 | "
" 199 | ], 200 | "metadata": {}, 201 | "output_type": "pyout", 202 | "prompt_number": 64, 203 | "text": [ 204 | " Name Value Age\n", 205 | "0 a 5 0\n", 206 | "1 c 6 10\n", 207 | "2 e 9 20\n", 208 | "3 a 5 0\n", 209 | "4 c 6 10\n", 210 | "5 e 9 20" 211 | ] 212 | } 213 | ], 214 | "prompt_number": 64 215 | }, 216 | { 217 | "cell_type": "code", 218 | "collapsed": false, 219 | "input": [ 220 | "store.close()" 221 | ], 222 | "language": "python", 223 | "metadata": {}, 224 | "outputs": [], 225 | "prompt_number": 68 226 | }, 227 | { 228 | "cell_type": "code", 229 | "collapsed": false, 230 | "input": [], 231 | "language": "python", 232 | "metadata": {}, 233 | "outputs": [] 234 | } 235 | ], 236 | "metadata": {} 237 | } 238 | ] 239 | } -------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/pyout-metadata.html: -------------------------------------------------------------------------------- 1 |
In [1]:
pwd
Out [1]:
u'/ifs/devel/antoniob/projects/BEST-D'
In [3]:
cd /ifs/projects/proj043/analysis.dir
/ifs/projects/proj043/analysis.dir
2 | 
In [21]:
import pandas
3 | import sqlite3
4 | import os
In [ ]:
#Create SQL database and insert tables:
5 | df.to_sql(name='JULIAN_sheet_1_original', if_exists='replace', flavor='sqlite', con=sqlite3.connect('BESTD_csvdb'))
6 | df2.to_sql(name='JULIAN_sheet_1_for_plink', if_exists='replace', flavor='sqlite', con=sqlite3.connect('BESTD_csvdb'))
-------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/pyout-metadata.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "code", 12 | "collapsed": false, 13 | "input": [ 14 | "pwd" 15 | ], 16 | "language": "python", 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "metadata": {}, 21 | "output_type": "pyout", 22 | "prompt_number": 1, 23 | "text": [ 24 | "u'/ifs/devel/antoniob/projects/BEST-D'" 25 | ] 26 | } 27 | ], 28 | "prompt_number": 1 29 | }, 30 | { 31 | "cell_type": "code", 32 | "collapsed": false, 33 | "input": [ 34 | "cd /ifs/projects/proj043/analysis.dir" 35 | ], 36 | "language": "python", 37 | "metadata": {}, 38 | "outputs": [ 39 | { 40 | "output_type": "stream", 41 | "stream": "stdout", 42 | "text": [ 43 | "/ifs/projects/proj043/analysis.dir\n" 44 | ] 45 | } 46 | ], 47 | "prompt_number": 3 48 | }, 49 | { 50 | "cell_type": "code", 51 | "collapsed": false, 52 | "input": [ 53 | "import pandas\n", 54 | "import sqlite3\n", 55 | "import os" 56 | ], 57 | "language": "python", 58 | "metadata": {}, 59 | "outputs": [], 60 | "prompt_number": 21 61 | }, 62 | { 63 | "cell_type": "code", 64 | "collapsed": false, 65 | "input": [ 66 | "#Create SQL database and insert tables:\n", 67 | "df.to_sql(name='JULIAN_sheet_1_original', if_exists='replace', flavor='sqlite', con=sqlite3.connect('BESTD_csvdb'))\n", 68 | "df2.to_sql(name='JULIAN_sheet_1_for_plink', if_exists='replace', flavor='sqlite', con=sqlite3.connect('BESTD_csvdb'))" 69 | ], 70 | "language": "python", 71 | "metadata": {}, 72 | "outputs": [] 73 | } 74 | ], 75 | "metadata": {} 76 | } 77 | ] 78 | } -------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/pyout-svg-output.html: -------------------------------------------------------------------------------- 1 |

Working with Internal Representations

2 |
In [1]:
from pymbolic import parse
  3 | 
  4 | x = parse("x")
  5 | h = parse("h")

Visualizing an Expression Tree

6 |
In [2]:
u = (x+4)**3
  7 | 
  8 | h = parse("h")
  9 | 
 10 | expr = u + 2*u*h + 4*u*h**2
 11 | 
In [3]:
# Load an IPython extension for graph drawing
 12 | %load_ext gvmagic
In [4]:
from pymbolic.mapper.graphviz import GraphvizMapper
 13 | 
 14 | gvm = GraphvizMapper()
 15 | gvm(expr)
In [5]:
%dotstr gvm.get_dot_code()
16 | 17 | 19 | 20 | 21 | 22 | expression 23 | 24 | 25 | id139855649446656 26 | 27 | + 28 | 29 | 30 | id139855649446712 31 | 32 | Power 33 | 34 | 35 | id139855649446656->id139855649446712 36 | 37 | 38 | 39 | 40 | id139855649446768 41 | 42 | * 43 | 44 | 45 | id139855649446656->id139855649446768 46 | 47 | 48 | 49 | 50 | id139855649446936 51 | 52 | * 53 | 54 | 55 | id139855649446656->id139855649446936 56 | 57 | 58 | 59 | 60 | id139855649446600 61 | 62 | + 63 | 64 | 65 | id139855649446712->id139855649446600 66 | 67 | 68 | 69 | 70 | uid2 71 | 72 | 3 73 | 74 | 75 | id139855649446712->uid2 76 | 77 | 78 | 79 | 80 | uid0 81 | 82 | x 83 | 84 | 85 | id139855649446600->uid0 86 | 87 | 88 | 89 | 90 | uid1 91 | 92 | 4 93 | 94 | 95 | id139855649446600->uid1 96 | 97 | 98 | 99 | 100 | id139855649446768->id139855649446712 101 | 102 | 103 | 104 | 105 | uid3 106 | 107 | 2 108 | 109 | 110 | id139855649446768->uid3 111 | 112 | 113 | 114 | 115 | uid4 116 | 117 | h 118 | 119 | 120 | id139855649446768->uid4 121 | 122 | 123 | 124 | 125 | id139855649446936->id139855649446712 126 | 127 | 128 | 129 | 130 | uid5 131 | 132 | 4 133 | 134 | 135 | id139855649446936->uid5 136 | 137 | 138 | 139 | 140 | id139855649446880 141 | 142 | Power 143 | 144 | 145 | id139855649446936->id139855649446880 146 | 147 | 148 | 149 | 150 | uid6 151 | 152 | h 153 | 154 | 155 | id139855649446880->uid6 156 | 157 | 158 | 159 | 160 | uid7 161 | 162 | 2 163 | 164 | 165 | id139855649446880->uid7 166 | 167 | 168 | 169 | 170 | 171 |
In [22]:
ec.compile(expr)
Out [22]:
'pow(x + 4, 3) + 4 * pow(x + 4, 3) * h * h + 2 * pow(x + 4, 3) * h'
In [ ]:
-------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/pyout-svg-output.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "worksheets": [ 3 | { 4 | "cells": [ 5 | { 6 | "cell_type": "markdown", 7 | "metadata": {}, 8 | "source": [ 9 | "# Working with Internal Representations" 10 | ] 11 | }, 12 | { 13 | "language": "python", 14 | "prompt_number": 1, 15 | "cell_type": "code", 16 | "outputs": [], 17 | "metadata": {}, 18 | "input": [ 19 | "from pymbolic import parse\n", 20 | "\n", 21 | "x = parse(\"x\")\n", 22 | "h = parse(\"h\")" 23 | ], 24 | "collapsed": false 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "## Visualizing an Expression Tree" 31 | ] 32 | }, 33 | { 34 | "language": "python", 35 | "prompt_number": 2, 36 | "cell_type": "code", 37 | "outputs": [], 38 | "metadata": {}, 39 | "input": [ 40 | "u = (x+4)**3\n", 41 | "\n", 42 | "h = parse(\"h\")\n", 43 | "\n", 44 | "expr = u + 2*u*h + 4*u*h**2\n" 45 | ], 46 | "collapsed": false 47 | }, 48 | { 49 | "language": "python", 50 | "prompt_number": 3, 51 | "cell_type": "code", 52 | "outputs": [], 53 | "metadata": {}, 54 | "input": [ 55 | "# Load an IPython extension for graph drawing\n", 56 | "%load_ext gvmagic" 57 | ], 58 | "collapsed": false 59 | }, 60 | { 61 | "language": "python", 62 | "prompt_number": 4, 63 | "cell_type": "code", 64 | "outputs": [], 65 | "metadata": {}, 66 | "input": [ 67 | "from pymbolic.mapper.graphviz import GraphvizMapper\n", 68 | "\n", 69 | "gvm = GraphvizMapper()\n", 70 | "gvm(expr)" 71 | ], 72 | "collapsed": false 73 | }, 74 | { 75 | "language": "python", 76 | "prompt_number": 5, 77 | "cell_type": "code", 78 | "outputs": [ 79 | { 80 | "metadata": {}, 81 | "svg": [ 82 | "\n", 83 | "\n", 85 | "\n", 87 | "\n", 88 | "\n", 90 | "\n", 91 | "expression\n", 92 | "\n", 93 | "\n", 94 | "id139855649446656\n", 95 | "\n", 96 | "+\n", 97 | "\n", 98 | "\n", 99 | "id139855649446712\n", 100 | "\n", 101 | "Power\n", 102 | "\n", 103 | "\n", 104 | "id139855649446656->id139855649446712\n", 105 | "\n", 106 | "\n", 107 | "\n", 108 | "\n", 109 | "id139855649446768\n", 110 | "\n", 111 | "*\n", 112 | "\n", 113 | "\n", 114 | "id139855649446656->id139855649446768\n", 115 | "\n", 116 | "\n", 117 | "\n", 118 | "\n", 119 | "id139855649446936\n", 120 | "\n", 121 | "*\n", 122 | "\n", 123 | "\n", 124 | "id139855649446656->id139855649446936\n", 125 | "\n", 126 | "\n", 127 | "\n", 128 | "\n", 129 | "id139855649446600\n", 130 | "\n", 131 | "+\n", 132 | "\n", 133 | "\n", 134 | "id139855649446712->id139855649446600\n", 135 | "\n", 136 | "\n", 137 | "\n", 138 | "\n", 139 | "uid2\n", 140 | "\n", 141 | "3\n", 142 | "\n", 143 | "\n", 144 | "id139855649446712->uid2\n", 145 | "\n", 146 | "\n", 147 | "\n", 148 | "\n", 149 | "uid0\n", 150 | "\n", 151 | "x\n", 152 | "\n", 153 | "\n", 154 | "id139855649446600->uid0\n", 155 | "\n", 156 | "\n", 157 | "\n", 158 | "\n", 159 | "uid1\n", 160 | "\n", 161 | "4\n", 162 | "\n", 163 | "\n", 164 | "id139855649446600->uid1\n", 165 | "\n", 166 | "\n", 167 | "\n", 168 | "\n", 169 | "id139855649446768->id139855649446712\n", 170 | "\n", 171 | "\n", 172 | "\n", 173 | "\n", 174 | "uid3\n", 175 | "\n", 176 | "2\n", 177 | "\n", 178 | "\n", 179 | "id139855649446768->uid3\n", 180 | "\n", 181 | "\n", 182 | "\n", 183 | "\n", 184 | "uid4\n", 185 | "\n", 186 | "h\n", 187 | "\n", 188 | "\n", 189 | "id139855649446768->uid4\n", 190 | "\n", 191 | "\n", 192 | "\n", 193 | "\n", 194 | "id139855649446936->id139855649446712\n", 195 | "\n", 196 | "\n", 197 | "\n", 198 | "\n", 199 | "uid5\n", 200 | "\n", 201 | "4\n", 202 | "\n", 203 | "\n", 204 | "id139855649446936->uid5\n", 205 | "\n", 206 | "\n", 207 | "\n", 208 | "\n", 209 | "id139855649446880\n", 210 | "\n", 211 | "Power\n", 212 | "\n", 213 | "\n", 214 | "id139855649446936->id139855649446880\n", 215 | "\n", 216 | "\n", 217 | "\n", 218 | "\n", 219 | "uid6\n", 220 | "\n", 221 | "h\n", 222 | "\n", 223 | "\n", 224 | "id139855649446880->uid6\n", 225 | "\n", 226 | "\n", 227 | "\n", 228 | "\n", 229 | "uid7\n", 230 | "\n", 231 | "2\n", 232 | "\n", 233 | "\n", 234 | "id139855649446880->uid7\n", 235 | "\n", 236 | "\n", 237 | "\n", 238 | "\n", 239 | "\n" 240 | ], 241 | "output_type": "display_data" 242 | } 243 | ], 244 | "metadata": {}, 245 | "input": [ 246 | "%dotstr gvm.get_dot_code()" 247 | ], 248 | "collapsed": false 249 | }, 250 | { 251 | "language": "python", 252 | "prompt_number": 22, 253 | "cell_type": "code", 254 | "outputs": [ 255 | { 256 | "text": [ 257 | "'pow(x + 4, 3) + 4 * pow(x + 4, 3) * h * h + 2 * pow(x + 4, 3) * h'" 258 | ], 259 | "metadata": {}, 260 | "prompt_number": 22, 261 | "output_type": "pyout" 262 | } 263 | ], 264 | "metadata": {}, 265 | "input": [ 266 | "ec.compile(expr)" 267 | ], 268 | "collapsed": false 269 | }, 270 | { 271 | "language": "python", 272 | "cell_type": "code", 273 | "outputs": [], 274 | "metadata": {}, 275 | "input": [], 276 | "collapsed": false 277 | } 278 | ], 279 | "metadata": {} 280 | } 281 | ], 282 | "metadata": { 283 | "name": "", 284 | "signature": "sha256:dcdcac6e7cea1b0b1cb3a557dc318ebfbd96766779328864ee42de8d79f6180e" 285 | }, 286 | "nbformat": 3, 287 | "nbformat_minor": 0 288 | } -------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/raw-cell-type.html: -------------------------------------------------------------------------------- 1 |
In [1]:
import pandas as pd
2 | import numpy as np
3 | import seaborn as sns
4 | import matplotlib.pyplot as plt
# Linear Regression - Target variable is Continuous variable 5 | # Logistic Regression - Target variable is Categorical Variable 6 | # Classification of Categorical variables - Binary(High/Low Risk), Multiclass(High,Med,Low Risk) 7 | # Sigmoid or Logit Function returns Y or N
-------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/raw-cell-type.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas as pd\n", 10 | "import numpy as np\n", 11 | "import seaborn as sns\n", 12 | "import matplotlib.pyplot as plt" 13 | ] 14 | }, 15 | { 16 | "cell_type": "raw", 17 | "metadata": {}, 18 | "source": [ 19 | "# Linear Regression - Target variable is Continuous variable\n", 20 | "# Logistic Regression - Target variable is Categorical Variable\n", 21 | "# Classification of Categorical variables - Binary(High/Low Risk), Multiclass(High,Med,Low Risk)\n", 22 | "# Sigmoid or Logit Function returns Y or N" 23 | ] 24 | } 25 | ], 26 | "metadata": { 27 | "kernelspec": { 28 | "display_name": "Python 3", 29 | "language": "python", 30 | "name": "python3" 31 | }, 32 | "language_info": { 33 | "codemirror_mode": { 34 | "name": "ipython", 35 | "version": 3 36 | }, 37 | "file_extension": ".py", 38 | "mimetype": "text/x-python", 39 | "name": "python", 40 | "nbconvert_exporter": "python", 41 | "pygments_lexer": "ipython3", 42 | "version": "3.7.4" 43 | } 44 | }, 45 | "nbformat": 4, 46 | "nbformat_minor": 2 47 | } 48 | -------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/repro-pr46.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "above-parker", 6 | "metadata": {}, 7 | "source": [ 8 | "Repro of [PR #46](https://github.com/kokes/nbviewer.js/pull/46). The change introduces display in [KaTeX](https://katex.org/docs/options.html) for block based math. The most notable changes are: centering, being in a block, and larger sums and integrals." 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "copyrighted-wells", 14 | "metadata": {}, 15 | "source": [ 16 | "We should apply a different parameter to KaTeX for inline math - like this - $\\sum_{x=1}^\\infty x^2 - \\int_0^12\\frac{1}{2-x}$ - and to block based math, like this:\n", 17 | "\n", 18 | "$$\n", 19 | "\\begin{aligned} \n", 20 | "2x - 5y &= 8 \\\\ \n", 21 | "3x + 9y &= -12\n", 22 | "\\end{aligned}\n", 23 | "$$\n", 24 | "\n", 25 | "$$\n", 26 | "\\begin{aligned}\n", 27 | "x&=y & w &=z & a&=b+c\\\\\n", 28 | "2x&=-y & 3w&=\\frac{1}{2}z & a&=b\\\\\n", 29 | "-4 + 5x&=2+y & w+2&=-1+w & ab&=cb\n", 30 | "\\end{aligned}\n", 31 | "$$\n", 32 | "\n", 33 | "$$\n", 34 | "\\sum_{x=1}^n x^2 = \\ldots\n", 35 | "\\int_0^12 x = \\ldots\n", 36 | "$$" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "id": "subtle-alloy", 42 | "metadata": {}, 43 | "source": [ 44 | "Also, if we use block-based math inline, it will be forced into a block - $$x^2 = \\ldots$$ - like this." 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "id": "metric-virtue", 50 | "metadata": {}, 51 | "source": [ 52 | "Some of the equations above taken from [overleaf.com](https://www.overleaf.com/learn/latex/Aligning%20equations%20with%20amsmath)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "id": "herbal-chemistry", 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [] 62 | } 63 | ], 64 | "metadata": { 65 | "kernelspec": { 66 | "display_name": "Python 3", 67 | "language": "python", 68 | "name": "python3" 69 | }, 70 | "language_info": { 71 | "codemirror_mode": { 72 | "name": "ipython", 73 | "version": 3 74 | }, 75 | "file_extension": ".py", 76 | "mimetype": "text/x-python", 77 | "name": "python", 78 | "nbconvert_exporter": "python", 79 | "pygments_lexer": "ipython3", 80 | "version": "3.9.0" 81 | } 82 | }, 83 | "nbformat": 4, 84 | "nbformat_minor": 5 85 | } 86 | -------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/repro-pr47.html: -------------------------------------------------------------------------------- 1 |

Test for PR #47

2 |

This ipynb was edited and saved with VSCode (version 1.47.3).

3 |
In [3]:
print("""A multi-line
4 | string
5 | """)
A multi-line
6 | string
7 | 
8 | 
-------------------------------------------------------------------------------- /nbviewer.js/tests/notebooks/repro-pr47.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Test for PR #47\n", 8 | "\n", 9 | "This ipynb was edited and saved with VSCode (version 1.47.3)." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 3, 15 | "metadata": { 16 | "tags": [] 17 | }, 18 | "outputs": [ 19 | { 20 | "output_type": "stream", 21 | "name": "stdout", 22 | "text": "A multi-line\nstring\n\n" 23 | } 24 | ], 25 | "source": [ 26 | "print(\"\"\"A multi-line\n", 27 | "string\n", 28 | "\"\"\")" 29 | ] 30 | } 31 | ], 32 | "metadata": { 33 | "kernelspec": { 34 | "display_name": "Python 3.8.5 64-bit", 35 | "language": "python", 36 | "name": "python_defaultSpec_1611999024431" 37 | }, 38 | "language_info": { 39 | "name": "", 40 | "version": "3.8.3-final" 41 | } 42 | }, 43 | "nbformat": 4, 44 | "nbformat_minor": 4 45 | } -------------------------------------------------------------------------------- /nbviewer.js/tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "jsdom": "^16.4.0", 4 | "katex": "^0.12.0", 5 | "marked": "^2.0.0", 6 | "prismjs": "^1.23.0" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /nbviewer.js/tests/test.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | const process = require("process"); 4 | 5 | const marked = require("marked"); 6 | const katex = require("katex"); 7 | const prism = require("prismjs"); 8 | 9 | const { JSDOM } = require("jsdom"); 10 | const { exception } = require("console"); 11 | const document = (new JSDOM("")).window.document; 12 | const nbv = require("../lib/nbv.js").nbv_constructor(document, {marked, prism, katex}); 13 | 14 | const target = document.createElement("div"); 15 | 16 | const nbdir = process.argv[2]; 17 | const listing = fs.readdirSync(nbdir) 18 | 19 | for (const filename of listing) { 20 | if (!filename.endsWith(".ipynb")) { 21 | console.log("skipping " + filename); 22 | continue 23 | } 24 | const fullPath = path.join(nbdir, filename); 25 | console.log(fullPath) 26 | const nb = JSON.parse(fs.readFileSync(fullPath)); 27 | nbv.render(nb, target); 28 | 29 | const htmlPath = fullPath.replace(".ipynb", ".html"); 30 | const htmlOriginal = fs.readFileSync(htmlPath); 31 | 32 | if (target.innerHTML != htmlOriginal) { 33 | fs.writeFileSync(htmlPath.replace(".html", "_test.html"), target.innerHTML); 34 | throw new Error(`rendering of ${filename} did not result in the HTML format expected`); 35 | } 36 | 37 | // useful for testing new files: 38 | // try { 39 | // nbv.render(nb, target); 40 | // } catch(e) { 41 | // console.log(e) 42 | // continue 43 | // } 44 | // fs.rmSync(fullPath) 45 | 46 | // huzzah, our first test 47 | // console.log(tg.innerHTML) 48 | // we can compare this to a snapshot 49 | 50 | } 51 | -------------------------------------------------------------------------------- /nbviewer.js/viewer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | nbviewer.js 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 75 | 76 | 77 | Fork me on GitHub 78 | 79 |
80 | 81 | 82 |
Drag and drop Jupyter notebooks anywhere here...
83 | or paste a link from Github:
84 | 85 |
86 | 87 |
88 | 89 |
90 | 91 |
92 | Hey there! If you have any feedback for this tool - issues, ideas for improvement, 93 | or you want to just tell me about your use case for this, I'd love to know. E-mail me or tweet at me. 94 |
95 | 96 | 97 | 295 | 296 | 306 | 307 | 308 | 309 | 310 | --------------------------------------------------------------------------------