├── .Rbuildignore ├── .github ├── .gitignore ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── question.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── R-CMD-check.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── as_html.R ├── as_sass.R ├── compile.R ├── deprecated.R ├── file_cache.R ├── fonts.R ├── format.R ├── layers.R ├── options.R ├── sass.R ├── sass_cache.R ├── shiny_devmode.R ├── staticimports.R └── utils.R ├── README.Rmd ├── README.md ├── inst ├── examples │ ├── example-full.scss │ ├── rules.scss │ └── variables.scss ├── sass-color │ ├── DESCRIPTION │ ├── README.md │ ├── app.R │ └── rsconnect │ │ └── shinyapps.io │ │ └── gallery │ │ └── sass-color.dcf ├── sass-font │ ├── DESCRIPTION │ ├── README.md │ ├── app.R │ ├── rsconnect │ │ └── shinyapps.io │ │ │ └── gallery │ │ │ └── sass-font.dcf │ └── sass-font.scss ├── sass-size │ ├── DESCRIPTION │ ├── README.md │ ├── app.R │ ├── rsconnect │ │ └── shinyapps.io │ │ │ └── gallery │ │ │ └── sass-size.dcf │ └── sass-size.scss └── sass-theme │ ├── DESCRIPTION │ ├── README.md │ ├── app.R │ └── rsconnect │ └── shinyapps.io │ └── gallery │ └── sass-theme.dcf ├── logo ├── sass-hex.png ├── sass-original.svg ├── sass.png └── sass.svg ├── man ├── FileCache.Rd ├── as_sass.Rd ├── as_sass_layer.Rd ├── figures │ ├── logo.svg │ ├── sass-color.gif │ └── sass-logo-color.png ├── font_face.Rd ├── output_template.Rd ├── sass-deprecated.Rd ├── sass.Rd ├── sass_cache_context_dir.Rd ├── sass_cache_get.Rd ├── sass_cache_get_dir.Rd ├── sass_cache_options.Rd ├── sass_file_cache.Rd ├── sass_import.Rd ├── sass_layer.Rd ├── sass_options.Rd ├── sass_partial.Rd └── write_file_attachments.Rd ├── pkgdown ├── _pkgdown.yml └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── sass.Rproj ├── scripts ├── apply_libsass_patches.R ├── build_docs.R ├── patches │ ├── 001-remove-makefile-pipes.patch │ ├── 003-replace-curdir-with-dot.patch │ ├── 004-remove-remaining-pipes.patch │ ├── 005-remove-pragma-marks.patch │ ├── 006-add-newline-fn_numbers.patch │ ├── 007-add-newline-sass_functions.patch │ ├── 008-gcc-12-address-warnings │ ├── 009-deprecated-declarations.patch │ ├── 010-clang-15-address-warnings.patch │ └── 010-gcc-12-windows-warning.patch ├── rhub.R └── update_libsass.R ├── src ├── .gitignore ├── Makevars ├── README.md ├── compile.c ├── compile.h ├── init.cpp └── libsass │ ├── .editorconfig │ ├── .gitattributes │ ├── .github │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE.md │ └── workflows │ │ └── build-and-test.yml │ ├── .gitignore │ ├── CODE_OF_CONDUCT.md │ ├── COPYING │ ├── GNUmakefile.am │ ├── INSTALL │ ├── LICENSE │ ├── Makefile │ ├── Makefile.conf │ ├── Readme.md │ ├── SECURITY.md │ ├── appveyor.yml │ ├── configure.ac │ ├── contrib │ ├── libsass.spec │ └── plugin.cpp │ ├── docs │ ├── README.md │ ├── api-context-example.md │ ├── api-context-internal.md │ ├── api-context.md │ ├── api-doc.md │ ├── api-function-example.md │ ├── api-function-internal.md │ ├── api-function.md │ ├── api-importer-example.md │ ├── api-importer-internal.md │ ├── api-importer.md │ ├── api-value-example.md │ ├── api-value-internal.md │ ├── api-value.md │ ├── build-on-darwin.md │ ├── build-on-gentoo.md │ ├── build-on-windows.md │ ├── build-shared-library.md │ ├── build-with-autotools.md │ ├── build-with-makefiles.md │ ├── build-with-mingw.md │ ├── build-with-visual-studio.md │ ├── build.md │ ├── contributing.md │ ├── custom-functions-internal.md │ ├── dev-ast-memory.md │ ├── dev-profiling.md │ ├── implementations.md │ ├── plugins.md │ ├── setup-environment.md │ ├── source-map-internals.md │ ├── trace.md │ ├── triage.md │ └── unicode.md │ ├── include │ ├── sass.h │ ├── sass │ │ ├── base.h │ │ ├── context.h │ │ ├── functions.h │ │ ├── values.h │ │ ├── version.h │ │ └── version.h.in │ └── sass2scss.h │ ├── m4 │ ├── .gitkeep │ └── m4-ax_cxx_compile_stdcxx_11.m4 │ ├── res │ └── resource.rc │ ├── script │ ├── bootstrap │ ├── branding │ ├── ci-build-libsass │ ├── ci-build-plugin │ ├── ci-install-compiler │ ├── ci-install-deps │ ├── ci-report-coverage │ ├── spec │ ├── tap-driver │ ├── tap-runner │ └── test-leaks.pl │ ├── src │ ├── GNUmakefile.am │ ├── MurmurHash2.hpp │ ├── ast.cpp │ ├── ast.hpp │ ├── ast2c.cpp │ ├── ast2c.hpp │ ├── ast_def_macros.hpp │ ├── ast_fwd_decl.cpp │ ├── ast_fwd_decl.hpp │ ├── ast_helpers.hpp │ ├── ast_sel_cmp.cpp │ ├── ast_sel_super.cpp │ ├── ast_sel_unify.cpp │ ├── ast_sel_weave.cpp │ ├── ast_selectors.cpp │ ├── ast_selectors.hpp │ ├── ast_supports.cpp │ ├── ast_supports.hpp │ ├── ast_values.cpp │ ├── ast_values.hpp │ ├── b64 │ │ ├── cencode.h │ │ └── encode.h │ ├── backtrace.cpp │ ├── backtrace.hpp │ ├── base64vlq.cpp │ ├── base64vlq.hpp │ ├── bind.cpp │ ├── bind.hpp │ ├── c2ast.cpp │ ├── c2ast.hpp │ ├── c99func.c │ ├── cencode.c │ ├── check_nesting.cpp │ ├── check_nesting.hpp │ ├── color_maps.cpp │ ├── color_maps.hpp │ ├── constants.cpp │ ├── constants.hpp │ ├── context.cpp │ ├── context.hpp │ ├── cssize.cpp │ ├── cssize.hpp │ ├── dart_helpers.hpp │ ├── debug.hpp │ ├── debugger.hpp │ ├── emitter.cpp │ ├── emitter.hpp │ ├── environment.cpp │ ├── environment.hpp │ ├── error_handling.cpp │ ├── error_handling.hpp │ ├── eval.cpp │ ├── eval.hpp │ ├── eval_selectors.cpp │ ├── expand.cpp │ ├── expand.hpp │ ├── extender.cpp │ ├── extender.hpp │ ├── extension.cpp │ ├── extension.hpp │ ├── file.cpp │ ├── file.hpp │ ├── fn_colors.cpp │ ├── fn_colors.hpp │ ├── fn_lists.cpp │ ├── fn_lists.hpp │ ├── fn_maps.cpp │ ├── fn_maps.hpp │ ├── fn_miscs.cpp │ ├── fn_miscs.hpp │ ├── fn_numbers.cpp │ ├── fn_numbers.hpp │ ├── fn_selectors.cpp │ ├── fn_selectors.hpp │ ├── fn_strings.cpp │ ├── fn_strings.hpp │ ├── fn_utils.cpp │ ├── fn_utils.hpp │ ├── inspect.cpp │ ├── inspect.hpp │ ├── json.cpp │ ├── json.hpp │ ├── kwd_arg_macros.hpp │ ├── lexer.cpp │ ├── lexer.hpp │ ├── listize.cpp │ ├── listize.hpp │ ├── mapping.hpp │ ├── memory.hpp │ ├── memory │ │ ├── allocator.cpp │ │ ├── allocator.hpp │ │ ├── config.hpp │ │ ├── memory_pool.hpp │ │ ├── shared_ptr.cpp │ │ └── shared_ptr.hpp │ ├── operation.hpp │ ├── operators.cpp │ ├── operators.hpp │ ├── ordered_map.hpp │ ├── output.cpp │ ├── output.hpp │ ├── parser.cpp │ ├── parser.hpp │ ├── parser_selectors.cpp │ ├── permutate.hpp │ ├── plugins.cpp │ ├── plugins.hpp │ ├── position.cpp │ ├── position.hpp │ ├── prelexer.cpp │ ├── prelexer.hpp │ ├── remove_placeholders.cpp │ ├── remove_placeholders.hpp │ ├── sass.cpp │ ├── sass.hpp │ ├── sass2scss.cpp │ ├── sass_context.cpp │ ├── sass_context.hpp │ ├── sass_functions.cpp │ ├── sass_functions.hpp │ ├── sass_values.cpp │ ├── sass_values.hpp │ ├── settings.hpp │ ├── source.cpp │ ├── source.hpp │ ├── source_data.hpp │ ├── source_map.cpp │ ├── source_map.hpp │ ├── stylesheet.cpp │ ├── stylesheet.hpp │ ├── support │ │ └── libsass.pc.in │ ├── to_value.cpp │ ├── to_value.hpp │ ├── units.cpp │ ├── units.hpp │ ├── utf8.h │ ├── utf8 │ │ ├── checked.h │ │ ├── core.h │ │ └── unchecked.h │ ├── utf8_string.cpp │ ├── utf8_string.hpp │ ├── util.cpp │ ├── util.hpp │ ├── util_string.cpp │ ├── util_string.hpp │ ├── values.cpp │ └── values.hpp │ ├── utils │ ├── README.md │ ├── build-skeletons │ │ ├── libsass.targets │ │ └── libsass.vcxproj.filters │ └── update-builds.pl │ ├── version.sh │ └── win │ ├── libsass.sln │ ├── libsass.sln.DotSettings │ ├── libsass.targets │ ├── libsass.vcxproj │ └── libsass.vcxproj.filters ├── tests ├── testthat.R └── testthat │ ├── .gitattributes │ ├── _reset.scss │ ├── _snaps │ ├── font-objects.md │ ├── font-objects │ │ └── font-css │ ├── html-dependencies.md │ ├── layers.md │ └── utils.md │ ├── helper-cache.R │ ├── helper-utils.R │ ├── test-assets │ ├── a.txt │ ├── b │ │ └── b1.txt │ ├── c │ │ ├── c1.txt │ │ └── d │ │ │ └── d1.txt │ └── test-layer-file.scss │ ├── test-cache.R │ ├── test-compile.R │ ├── test-compile.sass │ ├── test-compile.scss │ ├── test-extend.R │ ├── test-extend.scss │ ├── test-font-objects.R │ ├── test-html-dependencies.R │ ├── test-import.R │ ├── test-import.scss │ ├── test-include-path │ └── _need.scss │ ├── test-include-path2 │ └── _need2.scss │ ├── test-include-paths.R │ ├── test-layers-list.R │ ├── test-layers.R │ ├── test-mixins.R │ ├── test-mixins.scss │ ├── test-nesting-expected.css │ ├── test-nesting-input.scss │ ├── test-nesting.R │ ├── test-option-errors.R │ ├── test-options.R │ ├── test-output.R │ ├── test-shiny-devmode.R │ ├── test-unicode-bom-expected.css │ ├── test-unicode-bom-input.scss │ ├── test-unicode-css-expected.css │ ├── test-unicode-css-input.scss │ ├── test-unicode-var-expected.css │ ├── test-unicode-var-input.scss │ ├── test-unicode.R │ ├── test-utils.R │ ├── test-variables.R │ └── test-variables.scss └── vignettes ├── color-contrast.scss ├── hello-pacifico.png ├── my-style.png ├── my-style.scss └── sass.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^src/README\.md$ 2 | ^docs$ 3 | ^_pkgdown\.yml$ 4 | ^README\.Rmd$ 5 | ^cran-comments\.md$ 6 | ^LICENSE\.md$ 7 | ^.*\.Rproj$ 8 | ^\.Rproj\.user$ 9 | ^src/libsass/\.editorconfig$ 10 | ^src/libsass/\.travis.yml$ 11 | ^src/libsass/m4/\.gitkeep$ 12 | ^src/libsass/\.github$ 13 | ^src/libsass/lib/.*\.a$ 14 | ^src/libsass/src/.*\.o$ 15 | ^\.travis\.yml$ 16 | ^appveyor\.yml$ 17 | ^man/figures/shiny-app.gif$ 18 | ^.lintr 19 | ^scripts/ 20 | ^README\.html$ 21 | ^Untitled\. 22 | ^inst/*/rsconnect$ 23 | ^doc$ 24 | ^Meta$ 25 | ^revdep$ 26 | ^\.github$ 27 | ^logo$ 28 | ^pkgdown$ 29 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name : Bug report 3 | about : Report a bug in sass. 4 | --- 5 | 6 | 11 | 12 | 13 | ## Describe the problem 14 | 15 | 18 | 19 | ```r 20 | # Include a minimal and reproducible example here 21 | # If you don't know what that means, please see https://www.tidyverse.org/help 22 | ``` 23 | 24 | 25 | ### Session Info 26 | 27 |
28 |

29 | Place your devtools::session_info() here
30 | 
31 |
32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name : Feature request 3 | about : Request a new feature. 4 | --- 5 | 6 | 15 | 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name : Ask a Question 3 | about : The issue tracker is not for general help questions -- please ask general plumber help questions on RStudio Community, https://forum.posit.co/tag/sass. 4 | --- 5 | 6 | The issue tracker is not for questions. If you have a question, please feel free to ask sass help questions on RStudio Community under the `sass` tag, at https://forum.posit.co/tag/sass. Please tag your post with a `sass` tag to increase visibility. 7 | 8 | [Click here](https://forum.posit.co/new-topic?title=&tags=sass&u=cpsievert&body=%0A%0A%0A--------%0A%0A%3Csup%3EReferred%20here%20by%20%5B%60rstudio%2Fsass%60%5D(http%3A%2F%2Fgithub.com%2Frstudio%2Fsass)%3C%2Fsup%3E%0A) to create a new post with a `sass` tag. 9 | 10 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Pull Request 2 | 3 | Before you submit a pull request, please ensure you've completed the following checklist 4 | 5 | - [ ] Ensure there is an already open and relevant [GitHub issue](https://github.com/rstudio/sass/issues/new) describing the problem in detail and you've already received some indication from the maintainers that they are welcome to a contribution to fix the problem. This helps us to prevent wasting anyone's time. 6 | 7 | - [ ] Add unit tests in the tests/testthat directory. 8 | 9 | - [ ] This project uses [roxygen2 for documentation](http://r-pkgs.had.co.nz/man.html). If you've made changes to documentation, run `devtools::document()`. 10 | 11 | - [ ] Run `devtools::check()` (or, equivalently, click on Build->Check Package in the RStudio IDE) to make sure your change did not add any messages, warnings, or errors. 12 | * Note there is a decent chance that some tests were already failing before your changes. Just make sure you haven't introduced any new ones. 13 | 14 | - [ ] Ensure your code changes follow the style outlined in http://r-pkgs.had.co.nz/style.html 15 | 16 | - [ ] Add an entry to NEWS.md concisely describing what you changed. 17 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/rstudio/shiny-workflows 2 | # 3 | # NOTE: This Shiny team GHA workflow is overkill for most R packages. 4 | # For most R packages it is better to use https://github.com/r-lib/actions 5 | on: 6 | push: 7 | branches: [main, rc-**] 8 | pull_request: 9 | branches: [main] 10 | schedule: 11 | - cron: '0 4 * * 1' # every monday 12 | 13 | name: Package checks 14 | 15 | jobs: 16 | website: 17 | uses: rstudio/shiny-workflows/.github/workflows/website.yaml@v1 18 | routine: 19 | uses: rstudio/shiny-workflows/.github/workflows/routine.yaml@v1 20 | R-CMD-check: 21 | uses: rstudio/shiny-workflows/.github/workflows/R-CMD-check.yaml@v1 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | inst/doc 2 | .Rproj.user 3 | .Rhistory 4 | .RData 5 | .Ruserdata 6 | .DS_Store 7 | README.html 8 | Untitled.* 9 | doc 10 | Meta 11 | revdep 12 | docs 13 | scripts/build 14 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Type: Package 2 | Package: sass 3 | Version: 0.4.10.9000 4 | Title: Syntactically Awesome Style Sheets ('Sass') 5 | Description: An 'SCSS' compiler, powered by the 'LibSass' library. With this, 6 | R developers can use variables, inheritance, and functions to generate 7 | dynamic style sheets. The package uses the 'Sass CSS' extension language, 8 | which is stable, powerful, and CSS compatible. 9 | Authors@R: c( 10 | person("Joe", "Cheng", , "joe@rstudio.com", "aut"), 11 | person("Timothy", "Mastny", , "tim.mastny@gmail.com", "aut"), 12 | person("Richard", "Iannone", , "rich@rstudio.com", "aut", 13 | comment = c(ORCID = "0000-0003-3925-190X")), 14 | person("Barret", "Schloerke", , "barret@rstudio.com", "aut", 15 | comment = c(ORCID = "0000-0001-9986-114X")), 16 | person("Carson", "Sievert", , "carson@rstudio.com", c("aut", "cre"), 17 | comment = c(ORCID = "0000-0002-4958-2844")), 18 | person("Christophe", "Dervieux", , "cderv@rstudio.com", c("ctb"), 19 | comment = c(ORCID = "0000-0003-4474-2498")), 20 | person(family = "RStudio", role = c("cph", "fnd")), 21 | person(family = "Sass Open Source Foundation", role = c("ctb", "cph"), 22 | comment = "LibSass library"), 23 | person("Greter", "Marcel", role = c("ctb", "cph"), 24 | comment = "LibSass library"), 25 | person("Mifsud", "Michael", role = c("ctb", "cph"), 26 | comment = "LibSass library"), 27 | person("Hampton", "Catlin", role = c("ctb", "cph"), 28 | comment = "LibSass library"), 29 | person("Natalie", "Weizenbaum", role = c("ctb", "cph"), 30 | comment = "LibSass library"), 31 | person("Chris", "Eppstein", role = c("ctb", "cph"), 32 | comment = "LibSass library"), 33 | person("Adams", "Joseph", role = c("ctb", "cph"), 34 | comment = "json.cpp"), 35 | person("Trifunovic", "Nemanja", role = c("ctb", "cph"), 36 | comment = "utf8.h") 37 | ) 38 | License: MIT + file LICENSE 39 | URL: https://rstudio.github.io/sass/, https://github.com/rstudio/sass 40 | BugReports: https://github.com/rstudio/sass/issues 41 | Encoding: UTF-8 42 | RoxygenNote: 7.3.2 43 | Roxygen: list(markdown = TRUE) 44 | SystemRequirements: GNU make 45 | Imports: 46 | fs (>= 1.2.4), 47 | rlang (>= 0.4.10), 48 | htmltools (>= 0.5.1), 49 | R6, 50 | rappdirs 51 | Suggests: 52 | testthat, 53 | knitr, 54 | rmarkdown, 55 | withr, 56 | shiny, 57 | curl 58 | VignetteBuilder: knitr 59 | Config/testthat/edition: 3 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2019 2 | COPYRIGHT HOLDER: RStudio, Inc. 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2019 RStudio, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(format,css) 4 | S3method(format,sass) 5 | S3method(format,sass_bundle) 6 | S3method(format,sass_layer) 7 | S3method(print,css) 8 | S3method(print,sass) 9 | S3method(print,sass_bundle) 10 | S3method(print,sass_layer) 11 | export(as_sass) 12 | export(as_sass_layer) 13 | export(font_collection) 14 | export(font_face) 15 | export(font_google) 16 | export(font_link) 17 | export(is_font_collection) 18 | export(is_sass_bundle) 19 | export(output_template) 20 | export(sass) 21 | export(sass_bundle) 22 | export(sass_bundle_remove) 23 | export(sass_cache_context_dir) 24 | export(sass_cache_get) 25 | export(sass_cache_get_dir) 26 | export(sass_cache_options) 27 | export(sass_cache_set_dir) 28 | export(sass_file) 29 | export(sass_file_cache) 30 | export(sass_import) 31 | export(sass_layer) 32 | export(sass_layer_file) 33 | export(sass_layer_merge) 34 | export(sass_options) 35 | export(sass_options_get) 36 | export(sass_options_set) 37 | export(sass_partial) 38 | export(write_file_attachments) 39 | import(htmltools) 40 | importFrom(R6,R6Class) 41 | importFrom(rlang,"%||%") 42 | importFrom(rlang,have_name) 43 | importFrom(rlang,is_missing) 44 | importFrom(rlang,list2) 45 | importFrom(rlang,maybe_missing) 46 | importFrom(rlang,missing_arg) 47 | importFrom(rlang,names2) 48 | importFrom(stats,na.omit) 49 | importFrom(utils,download.file) 50 | importFrom(utils,modifyList) 51 | importFrom(utils,packageVersion) 52 | useDynLib(sass, .registration = TRUE) 53 | -------------------------------------------------------------------------------- /R/as_html.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | # add class html and attr('html') <- TRUE to spoof htmltoolts::HTML(css) output 4 | as_html <- function(x, extra_class = NULL) { 5 | class(x) <- c(extra_class, "html", "character") 6 | attr(x, "html") <- TRUE 7 | x 8 | } 9 | -------------------------------------------------------------------------------- /R/compile.R: -------------------------------------------------------------------------------- 1 | 2 | #' @useDynLib sass, .registration = TRUE 3 | compile_file <- function(file, opts) { 4 | .Call(C_compile_file, file, opts) 5 | } 6 | 7 | compile_data <- function(data, opts) { 8 | .Call(C_compile_data, data, opts) 9 | } 10 | 11 | .onUnload <- function (libpath) { 12 | library.dynam.unload("sass", libpath) 13 | } 14 | -------------------------------------------------------------------------------- /R/deprecated.R: -------------------------------------------------------------------------------- 1 | 2 | #' Deprecated 3 | #' 4 | #' Deprecated Sass functions 5 | #' 6 | #' @rdname sass-deprecated 7 | #' @name sass-deprecated 8 | #' @keywords internal 9 | NULL 10 | 11 | #' @describeIn sass-deprecated Please use `sass_bundle(...)` 12 | #' @export 13 | sass_layer_merge <- function(...) { 14 | .Deprecated(msg = "`sass_layer_merge()` is deprecated. Please use `sass_bundle()` instead. See `?sass_bundle()`") 15 | sass_bundle(...) 16 | } 17 | -------------------------------------------------------------------------------- /R/shiny_devmode.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### 4 | # These methods could be removed if shiny were able to be imported. 5 | # * `shiny::in_devmode()` 6 | # * `shiny::get_devmode_option()` 7 | ### 8 | 9 | 10 | in_shiny_devmode <- function() { 11 | isTRUE(getOption("shiny.devmode", FALSE)) && 12 | !identical(Sys.getenv("TESTTHAT"), "true") 13 | } 14 | 15 | #' @importFrom rlang missing_arg is_missing maybe_missing 16 | get_shiny_devmode_option <- function( 17 | name, 18 | default = NULL, 19 | devmode_default = missing_arg(), 20 | devmode_message = missing_arg() 21 | ) { 22 | 23 | if (!in_shiny_devmode()) { 24 | # Dev Mode disabled, act like `getOption()` 25 | return(getOption(name, default = default)) 26 | } 27 | 28 | # Dev Mode enabled, update the default value for `getOption()` 29 | getOption(name, default = { 30 | # Notify developer 31 | if ( 32 | !is_missing(devmode_message) && 33 | !is.null(devmode_message) && 34 | getOption("shiny.devmode.verbose", TRUE) 35 | ) { 36 | devmode_message <- paste0("shiny devmode - ", devmode_message) 37 | rlang::inform( 38 | message = devmode_message, 39 | .frequency = "regularly", 40 | .frequency_id = devmode_message, 41 | .file = stderr() 42 | ) 43 | } 44 | 45 | # Return Dev Mode default value `devmode_default` 46 | maybe_missing(devmode_default, default) 47 | }) 48 | } 49 | -------------------------------------------------------------------------------- /R/staticimports.R: -------------------------------------------------------------------------------- 1 | # Generated by staticimports; do not edit by hand. 2 | # ====================================================================== 3 | # Imported from pkg:staticimports 4 | # ====================================================================== 5 | 6 | get_package_version <- function(pkg) { 7 | # `utils::packageVersion()` can be slow, so first try the fast path of 8 | # checking if the package is already loaded. 9 | ns <- .getNamespace(pkg) 10 | if (is.null(ns)) { 11 | utils::packageVersion(pkg) 12 | } else { 13 | as.package_version(ns$.__NAMESPACE__.$spec[["version"]]) 14 | } 15 | } 16 | 17 | is_installed <- function(pkg, version = NULL) { 18 | installed <- isNamespaceLoaded(pkg) || nzchar(system_file_cached(package = pkg)) 19 | if (is.null(version)) { 20 | return(installed) 21 | } 22 | installed && isTRUE(get_package_version(pkg) >= version) 23 | } 24 | 25 | # A wrapper for `system.file()`, which caches the results, because 26 | # `system.file()` can be slow. Note that because of caching, if 27 | # `system_file_cached()` is called on a package that isn't installed, then the 28 | # package is installed, and then `system_file_cached()` is called again, it will 29 | # still return "". 30 | system_file_cached <- local({ 31 | pkg_dir_cache <- character() 32 | 33 | function(..., package = "base") { 34 | if (!is.null(names(list(...)))) { 35 | stop("All arguments other than `package` must be unnamed.") 36 | } 37 | 38 | not_cached <- is.na(match(package, names(pkg_dir_cache))) 39 | if (not_cached) { 40 | pkg_dir <- system.file(package = package) 41 | pkg_dir_cache[[package]] <<- pkg_dir 42 | } else { 43 | pkg_dir <- pkg_dir_cache[[package]] 44 | } 45 | 46 | file.path(pkg_dir, ...) 47 | } 48 | }) 49 | -------------------------------------------------------------------------------- /inst/examples/example-full.scss: -------------------------------------------------------------------------------- 1 | $bg: #333; 2 | $fg: white; 3 | $fontsize: 16px; 4 | 5 | body { 6 | background-color: $bg; 7 | color: $fg; 8 | font-size: $fontsize; 9 | } 10 | -------------------------------------------------------------------------------- /inst/examples/rules.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: $bg; 3 | color: $fg; 4 | font-size: $fontsize; 5 | } 6 | -------------------------------------------------------------------------------- /inst/examples/variables.scss: -------------------------------------------------------------------------------- 1 | $bg: #333; 2 | $fg: white; 3 | $fontsize: 16px; 4 | -------------------------------------------------------------------------------- /inst/sass-color/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Title: Sass Color Example 2 | Author: RStudio, Inc. 3 | AuthorUrl: http://www.rstudio.com/ 4 | License: MIT 5 | DisplayMode: Showcase 6 | Tags: sass css 7 | Type: Shiny 8 | -------------------------------------------------------------------------------- /inst/sass-color/README.md: -------------------------------------------------------------------------------- 1 | This example shows how to use the [sass](https://github.com/rstudio/sass) R package to dynamically generate a stylesheet that changes the background color in a shiny app. 2 | -------------------------------------------------------------------------------- /inst/sass-color/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(sass) 3 | library(colourpicker) 4 | 5 | ui <- fluidPage( 6 | headerPanel("Sass Color Example"), 7 | uiOutput("sass"), 8 | 9 | sidebarPanel( 10 | colourInput("color", "Background Color", value = "#6498d2", 11 | showColour = "text") 12 | ), 13 | 14 | mainPanel( 15 | plotOutput("distPlot"), 16 | br() 17 | ), 18 | 19 | column(6, verbatimTextOutput("scssTxt")), 20 | column(6, verbatimTextOutput("cssTxt")) 21 | ) 22 | 23 | server <- function(input, output) { 24 | output$distPlot <- renderPlot({ 25 | hist(rnorm(500)) 26 | }) 27 | 28 | variables <- reactive({ 29 | list( 30 | color = input$color 31 | ) 32 | }) 33 | 34 | sass_input <- reactive({ 35 | list( 36 | variables(), 37 | paste( 38 | "body {", 39 | " background-color: $color;", 40 | "}", 41 | sep = "\n" 42 | ) 43 | ) 44 | }) 45 | compiled_css <- reactive({ 46 | sass(sass_input()) 47 | }) 48 | 49 | output$sass <- renderUI({ 50 | tags$head(tags$style(compiled_css())) 51 | }) 52 | 53 | output$scssTxt <- renderText({ 54 | paste0("/* Sass */\n", as_sass(sass_input())) 55 | }) 56 | 57 | output$cssTxt <- renderText({ 58 | paste0("/* Compiled CSS */\n", compiled_css()) 59 | }) 60 | } 61 | 62 | shinyApp(ui, server) 63 | -------------------------------------------------------------------------------- /inst/sass-color/rsconnect/shinyapps.io/gallery/sass-color.dcf: -------------------------------------------------------------------------------- 1 | name: sass-color 2 | title: sass-color 3 | username: 4 | account: gallery 5 | server: shinyapps.io 6 | hostUrl: https://api.shinyapps.io/v1 7 | appId: 429290 8 | bundleId: 1584201 9 | url: https://gallery.shinyapps.io/sass-color/ 10 | when: 1536858925.49865 11 | asMultiple: FALSE 12 | asStatic: FALSE 13 | -------------------------------------------------------------------------------- /inst/sass-font/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Title: Sass Font Example 2 | Author: RStudio, Inc. 3 | AuthorUrl: http://www.rstudio.com/ 4 | License: MIT 5 | DisplayMode: Showcase 6 | Tags: sass css 7 | Type: Shiny 8 | -------------------------------------------------------------------------------- /inst/sass-font/README.md: -------------------------------------------------------------------------------- 1 | This example shows how to use the [sass](https://github.com/rstudio/sass) R package to dynamically generate a stylesheet that changes the background color in a shiny app. The font color also depends on the background color, changing between black and white as necessary. 2 | -------------------------------------------------------------------------------- /inst/sass-font/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(sass) 3 | library(colourpicker) 4 | 5 | ui <- fluidPage( 6 | headerPanel("Sass Font Example"), 7 | uiOutput("sass"), 8 | 9 | sidebarPanel( 10 | colourInput("color", "Background Color", value = "#6498d2", 11 | showColour = "text") 12 | ), 13 | 14 | mainPanel( 15 | plotOutput("distPlot"), 16 | br() 17 | ), 18 | 19 | column(6, verbatimTextOutput("scssTxt"), verbatimTextOutput("sassFile")), 20 | column(6, verbatimTextOutput("cssTxt")) 21 | ) 22 | 23 | server <- function(input, output) { 24 | output$distPlot <- renderPlot({ 25 | hist(rnorm(500)) 26 | }) 27 | 28 | variables <- reactive({ 29 | list( 30 | color = input$color 31 | ) 32 | }) 33 | 34 | sass_input <- reactive({ 35 | list( 36 | variables(), 37 | sass_file("sass-font.scss") 38 | ) 39 | }) 40 | compiled_css <- reactive({ 41 | sass(sass_input()) 42 | }) 43 | 44 | output$sass <- renderUI({ 45 | tags$head(tags$style(compiled_css())) 46 | }) 47 | 48 | output$scssTxt <- renderText({ 49 | paste0("/* Sass */\n", as_sass(sass_input())) 50 | }) 51 | output$sassFile <- renderText({ 52 | paste0( 53 | "/* sass-font.scss */\n\n", 54 | paste0(readLines("sass-font.scss"), collapse = "\n") 55 | ) 56 | }) 57 | 58 | output$cssTxt <- renderText({ 59 | paste0("/* Compiled CSS */\n", compiled_css()) 60 | }) 61 | } 62 | 63 | shinyApp(ui, server) 64 | -------------------------------------------------------------------------------- /inst/sass-font/rsconnect/shinyapps.io/gallery/sass-font.dcf: -------------------------------------------------------------------------------- 1 | name: sass-font 2 | title: sass-font 3 | username: 4 | account: gallery 5 | server: shinyapps.io 6 | hostUrl: https://api.shinyapps.io/v1 7 | appId: 429503 8 | bundleId: 1585777 9 | url: https://gallery.shinyapps.io/sass-font/ 10 | when: 1536936506.34148 11 | asMultiple: FALSE 12 | asStatic: FALSE 13 | -------------------------------------------------------------------------------- /inst/sass-font/sass-font.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: $color; 3 | } 4 | 5 | // https://stackoverflow.com/a/3943023/6637133 6 | @function font-color($color) { 7 | @return if( 8 | red($color) * 0.299 + green($color) * 0.587 + blue($color) * 0.114 > 186, 9 | #000000, #ffffff 10 | ); 11 | } 12 | 13 | h1 { 14 | color: if( 15 | red($color) * 0.299 + green($color) * 0.587 + blue($color) * 0.114 > 186, 16 | #000000, #ffffff); 17 | } 18 | -------------------------------------------------------------------------------- /inst/sass-size/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Title: Sass Resize Example 2 | Author: RStudio, Inc. 3 | AuthorUrl: http://www.rstudio.com/ 4 | License: MIT 5 | DisplayMode: Showcase 6 | Tags: sass css 7 | Type: Shiny 8 | -------------------------------------------------------------------------------- /inst/sass-size/README.md: -------------------------------------------------------------------------------- 1 | This example shows how to use the [sass](https://github.com/rstudio/sass) R package to dynamically generate a stylesheet that changes the background and font color in a shiny app. The app also allows you to dynmically resize the plot width. 2 | -------------------------------------------------------------------------------- /inst/sass-size/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(sass) 3 | library(colourpicker) 4 | 5 | ui <- fluidPage( 6 | headerPanel("Sass Size Example"), 7 | uiOutput("sass"), 8 | 9 | sidebarPanel( 10 | sliderInput("width", "Image Percent of Screen", 11 | min = 1, max = 100, value = 100), 12 | colourInput("color", "Background Color", value = "#6498d2", 13 | showColour = "text") 14 | ), 15 | 16 | mainPanel( 17 | plotOutput("distPlot"), 18 | br() 19 | ), 20 | 21 | column(6, verbatimTextOutput("scssTxt"), verbatimTextOutput("sassFile")), 22 | column(6, verbatimTextOutput("cssTxt")) 23 | ) 24 | 25 | server <- function(input, output) { 26 | output$distPlot <- renderPlot({ 27 | hist(rnorm(500)) 28 | }) 29 | 30 | variables <- reactive({ 31 | list( 32 | color = input$color, 33 | width = input$width 34 | ) 35 | }) 36 | 37 | sass_input <- reactive({ 38 | list( 39 | variables(), 40 | sass_file("sass-size.scss") 41 | ) 42 | }) 43 | compiled_css <- reactive({ 44 | sass(sass_input()) 45 | }) 46 | 47 | output$sass <- renderUI({ 48 | tags$head(tags$style(compiled_css())) 49 | }) 50 | 51 | output$scssTxt <- renderText({ 52 | paste0("/* Sass */\n", as_sass(sass_input())) 53 | }) 54 | output$sassFile <- renderText({ 55 | paste0( 56 | "/* sass-size.scss */\n\n", 57 | paste0(readLines("sass-size.scss"), collapse = "\n") 58 | ) 59 | }) 60 | 61 | output$cssTxt <- renderText({ 62 | paste0("/* Compiled CSS */\n", compiled_css()) 63 | }) 64 | } 65 | 66 | shinyApp(ui, server) 67 | -------------------------------------------------------------------------------- /inst/sass-size/rsconnect/shinyapps.io/gallery/sass-size.dcf: -------------------------------------------------------------------------------- 1 | name: sass-size 2 | title: sass-size 3 | username: 4 | account: gallery 5 | server: shinyapps.io 6 | hostUrl: https://api.shinyapps.io/v1 7 | appId: 429512 8 | bundleId: 1585784 9 | url: https://gallery.shinyapps.io/sass-size/ 10 | when: 1536936702.32887 11 | asMultiple: FALSE 12 | asStatic: FALSE 13 | -------------------------------------------------------------------------------- /inst/sass-size/sass-size.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: $color; 3 | } 4 | 5 | // https://stackoverflow.com/a/3943023/6637133 6 | @function font-color($color) { 7 | @return if( 8 | red($color) * 0.299 + green($color) * 0.587 + blue($color) * 0.114 > 186, 9 | #000000, #ffffff 10 | ); 11 | } 12 | 13 | h1 { 14 | color: if( 15 | red($color) * 0.299 + green($color) * 0.587 + blue($color) * 0.114 > 186, 16 | #000000, #ffffff); 17 | } 18 | 19 | .shiny-plot-output { 20 | max-width: percentage($width / 100); 21 | } 22 | -------------------------------------------------------------------------------- /inst/sass-theme/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Title: Sass CSS Theme 2 | Author: RStudio, Inc. 3 | AuthorUrl: http://www.rstudio.com/ 4 | License: MIT 5 | DisplayMode: Showcase 6 | Tags: sass css javascript 7 | Type: Shiny 8 | -------------------------------------------------------------------------------- /inst/sass-theme/README.md: -------------------------------------------------------------------------------- 1 | This self contained example shows how to use the [sass](https://github.com/rstudio/sass) R package to generate CSS for multiple themes and dynamically create colors based off of an original theme color. If a Shiny button is clicked, the javascript event is captured and the theme color is updated within the browser. A Shiny server event is triggered in addition to changing the theme within browser. 2 | 3 | Original [article](http://www.sitepoint.com/dealing-color-schemes-sass/) and [demo](https://codepen.io/SitePoint/pen/czixa) by [Hugo Giraudel](https://codepen.io/HugoGiraudel). 4 | -------------------------------------------------------------------------------- /inst/sass-theme/rsconnect/shinyapps.io/gallery/sass-theme.dcf: -------------------------------------------------------------------------------- 1 | name: sass-theme 2 | title: sass-theme 3 | username: 4 | account: gallery 5 | server: shinyapps.io 6 | hostUrl: https://api.shinyapps.io/v1 7 | appId: 429513 8 | bundleId: 1584213 9 | url: https://gallery.shinyapps.io/sass-theme/ 10 | when: 1536859335.89206 11 | asMultiple: FALSE 12 | asStatic: FALSE 13 | -------------------------------------------------------------------------------- /logo/sass-hex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/logo/sass-hex.png -------------------------------------------------------------------------------- /logo/sass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/logo/sass.png -------------------------------------------------------------------------------- /man/as_sass.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/as_sass.R 3 | \name{as_sass} 4 | \alias{as_sass} 5 | \title{Convert an R object into Sass code} 6 | \usage{ 7 | as_sass(input) 8 | } 9 | \arguments{ 10 | \item{input}{Any of the following: 11 | \itemize{ 12 | \item A character vector containing Sass code. 13 | \item A named list containing variable names and values. 14 | \item A \code{\link[=sass_file]{sass_file()}}, \code{\link[=sass_layer]{sass_layer()}}, and/or \code{\link[=sass_bundle]{sass_bundle()}}. 15 | \item A \code{\link[=list]{list()}} containing any of the above. 16 | }} 17 | } 18 | \value{ 19 | a single character value to be supplied to \code{\link[=sass]{sass()}}. 20 | } 21 | \description{ 22 | Converts multiple types of inputs to a single Sass input string for 23 | \code{\link[=sass]{sass()}}. 24 | } 25 | \examples{ 26 | # Example of regular Sass input 27 | as_sass("body { color: \"blue\"; }") 28 | 29 | # There is support for adding variables 30 | as_sass( 31 | list( 32 | list(color = "blue"), 33 | "body { color: $color; }" 34 | ) 35 | ) 36 | 37 | \donttest{ 38 | # Add a file name 39 | someFile <- tempfile("variables") 40 | 41 | # Overwrite color to red 42 | write("$color: \"red\";", someFile) 43 | 44 | input <- 45 | as_sass( 46 | list( 47 | list(color = "blue"), 48 | sass_file(someFile), 49 | "body { color: $color; }" 50 | ) 51 | ) 52 | 53 | input 54 | 55 | # The final body color is red 56 | sass(input) 57 | } 58 | } 59 | \references{ 60 | \url{https://sass-lang.com/documentation/at-rules/import} 61 | } 62 | -------------------------------------------------------------------------------- /man/as_sass_layer.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layers.R 3 | \name{as_sass_layer} 4 | \alias{as_sass_layer} 5 | \title{Sass Bundle to Single Sass Layer} 6 | \usage{ 7 | as_sass_layer(x) 8 | } 9 | \description{ 10 | Converts a \code{\link[=sass_bundle]{sass_bundle()}} to a single Sass layer object. 11 | } 12 | \details{ 13 | This is exported for internal use between packages and should not be used. 14 | Instead, please use \code{\link[=sass_layer]{sass_layer()}} or \code{\link[=sass_bundle]{sass_bundle()}} to construct and manage your sass objects 15 | and \code{\link[=sass]{sass()}} and \code{\link[=as_sass]{as_sass()}} to convert your objects. 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/figures/sass-color.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/man/figures/sass-color.gif -------------------------------------------------------------------------------- /man/figures/sass-logo-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/man/figures/sass-logo-color.png -------------------------------------------------------------------------------- /man/output_template.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sass.R 3 | \name{output_template} 4 | \alias{output_template} 5 | \title{An intelligent (temporary) output file} 6 | \usage{ 7 | output_template( 8 | basename = "sass", 9 | dirname = basename, 10 | fileext = NULL, 11 | path = tempdir() 12 | ) 13 | } 14 | \arguments{ 15 | \item{basename}{a non-empty character string giving the outfile name (without 16 | the extension).} 17 | 18 | \item{dirname}{a non-empty character string giving the initial part of the 19 | directory name.} 20 | 21 | \item{fileext}{the output file extension. The default is \code{".min.css"} for 22 | compressed and compact output styles; otherwise, its \code{".css"}.} 23 | 24 | \item{path}{the output file's root directory path.} 25 | } 26 | \value{ 27 | A function with two arguments: \code{options} and \code{suffix}. When called inside 28 | \code{\link[=sass]{sass()}} with caching enabled, the caching key is supplied to \code{suffix}. 29 | } 30 | \description{ 31 | Intended for use with \code{\link[=sass]{sass()}}'s \code{output} argument for temporary file 32 | generation that is \code{cache} and \code{options} aware. In particular, this ensures 33 | that new redundant file(s) aren't generated on a \code{\link[=sass]{sass()}} cache hit, and that 34 | the file's extension is suitable for the \code{\link[=sass_options]{sass_options()}}'s \code{output_style}. 35 | } 36 | \examples{ 37 | sass("body {color: red}", output = output_template()) 38 | 39 | func <- output_template(basename = "foo", dirname = "bar-") 40 | func(suffix = "baz") 41 | 42 | } 43 | -------------------------------------------------------------------------------- /man/sass-deprecated.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deprecated.R 3 | \name{sass-deprecated} 4 | \alias{sass-deprecated} 5 | \alias{sass_layer_merge} 6 | \title{Deprecated} 7 | \usage{ 8 | sass_layer_merge(...) 9 | } 10 | \description{ 11 | Deprecated Sass functions 12 | } 13 | \section{Functions}{ 14 | \itemize{ 15 | \item \code{sass_layer_merge()}: Please use \code{sass_bundle(...)} 16 | 17 | }} 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/sass_cache_context_dir.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sass_cache.R 3 | \name{sass_cache_context_dir} 4 | \alias{sass_cache_context_dir} 5 | \title{Return the cache directory for the current context.} 6 | \usage{ 7 | sass_cache_context_dir() 8 | } 9 | \description{ 10 | Return the cache directory for the current context. 11 | } 12 | \details{ 13 | In most cases, this function returns the user's cache directory, by calling 14 | \code{tools::R_user_dir("sass", which = "cache")} (for R 4.0 and above) or 15 | \code{rappdirs::user_cache_dir("R-sass")} (for older versions of R). 16 | 17 | If this function is called from a Shiny application, it will also look for a 18 | subdirectory named \verb{app_cache/}. If it exists, it will use a directory named 19 | \verb{app_cache/sass/} to store the cache. 20 | 21 | When running a Shiny application in a typical R session, it will not create 22 | the \verb{app_cache/} subdirectory, but it will use it if present. This scopes the 23 | cache to the application. 24 | 25 | With Shiny applications hosted on Shiny Server and Connect, it \emph{will} create 26 | a \verb{app_cache/sass/} subdirectory, so that the cache is scoped to the 27 | application and will not interfere with another application's cache. 28 | } 29 | \keyword{internal} 30 | -------------------------------------------------------------------------------- /man/sass_cache_get.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sass_cache.R 3 | \name{sass_cache_get} 4 | \alias{sass_cache_get} 5 | \title{Retrieve the default file cache} 6 | \usage{ 7 | sass_cache_get() 8 | } 9 | \description{ 10 | When caching is enabled, this function returns a \code{\link[=sass_file_cache]{sass_file_cache()}} object 11 | that \code{\link[=sass]{sass()}}'s \code{cache} argument uses (by default) for caching Sass 12 | compilation. When caching is disabled (either by setting the \code{sass.cache} 13 | option to \code{FALSE}, \code{NULL}, or via \code{\link[shiny:devmode]{shiny::devmode()}}), this function returns 14 | \code{NULL} (effectively telling \code{\link[=sass]{sass()}} to not \code{cache} by default). 15 | } 16 | \details{ 17 | When caching is enabled, then this function returns a \code{sass_file_cache()} 18 | object that (by default) uses \code{\link[=sass_cache_context_dir]{sass_cache_context_dir()}} for its directory. 19 | The directory can also be customized by providing the \code{sass.cache} option 20 | with either a filepath (as a string) or a full-blown \code{sass_file_cache()} 21 | object. 22 | } 23 | \seealso{ 24 | \code{\link[=sass_cache_get_dir]{sass_cache_get_dir()}}, \code{\link[=sass]{sass()}} 25 | } 26 | -------------------------------------------------------------------------------- /man/sass_cache_get_dir.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sass_cache.R 3 | \name{sass_cache_get_dir} 4 | \alias{sass_cache_get_dir} 5 | \alias{sass_cache_set_dir} 6 | \title{Get and set the cache object registered for a specific directory} 7 | \usage{ 8 | sass_cache_get_dir(dir, create = FALSE) 9 | 10 | sass_cache_set_dir(dir, cache) 11 | } 12 | \arguments{ 13 | \item{dir}{A directory. An error will be thrown if the directory does not 14 | exist.} 15 | 16 | \item{create}{If \code{TRUE}, then if the cache directory doesn't exist, or if 17 | there is not a registered cache object for the directory, create them as 18 | needed.} 19 | 20 | \item{cache}{A \code{\link[=sass_file_cache]{sass_file_cache()}} object, or \code{NULL} if you don't want to 21 | unset the cache for a directory.} 22 | } 23 | \description{ 24 | Get and set the cache object registered for a specific directory 25 | } 26 | \details{ 27 | If \code{sass_cache_get_dir()} is called for a given directory, before 28 | \code{sass_cache_set_dir()} has been called for that directory, then it will 29 | return \code{NULL}. 30 | 31 | After \code{sass_cache_set_dir()} is called for a directory, any future calls to 32 | \code{sass_cache_get_dir()} with that directory will return that specific cache 33 | object. This can be useful if you customize parameters for the cache object, 34 | like maximum size or age. 35 | } 36 | \seealso{ 37 | \code{\link[=sass_cache_get]{sass_cache_get()}}, \code{\link[=sass_file_cache]{sass_file_cache()}}, \code{\link[=sass]{sass()}} 38 | } 39 | \keyword{internal} 40 | -------------------------------------------------------------------------------- /man/sass_cache_options.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sass_cache.R 3 | \name{sass_cache_options} 4 | \alias{sass_cache_options} 5 | \title{Caching Options for Sass (defunct)} 6 | \usage{ 7 | sass_cache_options(cache, cache_dir) 8 | } 9 | \arguments{ 10 | \item{cache}{No longer used.} 11 | 12 | \item{cache_dir}{No longer used.} 13 | } 14 | \description{ 15 | This function is no longer used. Please see \code{\link[=sass_cache_get]{sass_cache_get()}}. 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/sass_file_cache.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/file_cache.R 3 | \name{sass_file_cache} 4 | \alias{sass_file_cache} 5 | \title{Create a file cache object} 6 | \usage{ 7 | sass_file_cache(dir, max_size = 40 * 1024^2, max_age = Inf) 8 | } 9 | \arguments{ 10 | \item{dir}{The directory in which to store the cached files.} 11 | 12 | \item{max_size}{The maximum size of the cache, in bytes. If the cache grows 13 | past this size, the least-recently-used objects will be removed until it 14 | fits within this size.} 15 | 16 | \item{max_age}{The maximum age of objects in the cache, in seconds. The 17 | default is one week.} 18 | } 19 | \value{ 20 | A \link{FileCache} object. 21 | } 22 | \description{ 23 | This creates a file cache which is to be used by sass for caching generated 24 | .css files. 25 | } 26 | \examples{ 27 | \dontrun{ 28 | # Create a cache with the default settings 29 | cache <- sass_file_cache(sass_cache_context_dir()) 30 | 31 | # Clear the cache 32 | cache$reset() 33 | } 34 | 35 | } 36 | \seealso{ 37 | \code{\link[=sass_cache_get]{sass_cache_get()}}, \code{\link[=sass_cache_context_dir]{sass_cache_context_dir()}}, \link{FileCache} 38 | } 39 | -------------------------------------------------------------------------------- /man/sass_import.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/as_sass.R 3 | \name{sass_import} 4 | \alias{sass_import} 5 | \alias{sass_file} 6 | \title{Sass Import} 7 | \usage{ 8 | sass_import(input, quote = TRUE) 9 | 10 | sass_file(input) 11 | } 12 | \arguments{ 13 | \item{input}{Character string to be placed in an import statement.} 14 | 15 | \item{quote}{Logical that determines if a double quote is added to the import 16 | value. Defaults to \code{TRUE}.} 17 | } 18 | \value{ 19 | Fully defined Sass import string. 20 | } 21 | \description{ 22 | Create an import statement to be used within your Sass file. See 23 | \url{https://sass-lang.com/documentation/at-rules/import} for 24 | more details. 25 | } 26 | \details{ 27 | \code{sass_file()} adds extra checks to make sure an appropriate file path 28 | exists given the input value. 29 | 30 | Note that the LibSass compiler expects .sass files to use the Sass Indented 31 | Syntax. 32 | } 33 | \examples{ 34 | sass_import("foo") 35 | sass_import("$foo", FALSE) 36 | \donttest{ 37 | tmp_scss_file <- tempfile(fileext = ".scss") 38 | writeLines("$color: red; body{ color: $color; }", tmp_scss_file) 39 | sass_file(tmp_scss_file) 40 | sass(sass_file(tmp_scss_file)) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /man/write_file_attachments.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layers.R 3 | \name{write_file_attachments} 4 | \alias{write_file_attachments} 5 | \title{Write file attachments from a sass theme object} 6 | \usage{ 7 | write_file_attachments(file_attachments, output_path) 8 | } 9 | \arguments{ 10 | \item{file_attachments}{A character vector of files or directories.} 11 | 12 | \item{output_path}{A directory to copy the attachments to.} 13 | } 14 | \description{ 15 | Write file attachments from a sass theme object 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /pkgdown/_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://rstudio.github.io/sass/ 2 | 3 | template: 4 | params: 5 | docsearch: 6 | api_key: b7f32716c953bf205e00b89772b35d36 7 | index_name: rstudio_sass 8 | 9 | toc: 10 | depth: 2 11 | 12 | navbar: 13 | type: default 14 | left: 15 | - text: Overview 16 | href: articles/sass.html 17 | - text: Reference 18 | href: reference/index.html 19 | - text: News 20 | href: news/index.html 21 | 22 | reference: 23 | - title: Sass compilation 24 | description: | 25 | Tools for invoking and controling Sass -> CSS compilation 26 | contents: 27 | - sass 28 | - sass_options 29 | - output_template 30 | - title: Sass code 31 | description: | 32 | Tools for generating Sass code from R 33 | contents: 34 | - as_sass 35 | - sass_file 36 | - sass_layer 37 | - sass_partial 38 | - title: Caching 39 | description: | 40 | Functions related to caching sass output 41 | contents: 42 | - sass_file_cache 43 | - sass_cache_get 44 | - title: Font importing 45 | description: | 46 | Helpers for importing font files 47 | contents: 48 | - font_face 49 | -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /sass.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageCheckArgs: --as-cran 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /scripts/apply_libsass_patches.R: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env Rscript 2 | # Applies patches stored in scripts/patches 3 | # Should be run after running scripts/update_libsass.R 4 | 5 | library(rprojroot) 6 | 7 | # Remove libsass test files (the entire `test` directory) since they contain unicode 8 | # directory paths, and R CMD check provides a warning. 9 | unlink( 10 | find_package_root_file("src/libsass/test"), 11 | recursive = TRUE 12 | ) 13 | 14 | patch_dir <- find_package_root_file("scripts/patches") 15 | 16 | for (patch in list.files(patch_dir, full.names = TRUE)) { 17 | tryCatch({ 18 | message(sprintf("Applying %s", basename(patch))) 19 | system(sprintf("git apply --reject --whitespace=fix '%s'", patch)) 20 | }, 21 | error = function(e) { 22 | quit(save = "no", status = 1) 23 | } 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /scripts/build_docs.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | (function() { 6 | 7 | owd <- getwd() 8 | on.exit({ 9 | setwd(owd) 10 | }) 11 | 12 | setwd(devtools::as.package(".")$path) 13 | 14 | devtools::document() 15 | 16 | devtools::install() 17 | 18 | rmarkdown::render("README.Rmd") 19 | 20 | unlink("docs", recursive = TRUE) 21 | pkgdown::build_site() 22 | 23 | })() 24 | -------------------------------------------------------------------------------- /scripts/patches/001-remove-makefile-pipes.patch: -------------------------------------------------------------------------------- 1 | The order-only prerequisite operators (|) were removed since they cannot be 2 | interpreted by Make 3.79.1 (which is used by Rtools 3.4). There were 3 instances 3 | removed by this patch 4 | 5 | diff --git a/src/libsass/Makefile b/src/libsass/Makefile 6 | index 30023ba..8c4ed4d 100644 7 | --- a/src/libsass/Makefile 8 | +++ b/src/libsass/Makefile 9 | @@ -204,17 +204,17 @@ debug-shared: shared 10 | lib: 11 | $(MKDIR) lib 12 | 13 | -lib/libsass.a: $(COBJECTS) $(OBJECTS) | lib 14 | +lib/libsass.a: $(COBJECTS) $(OBJECTS) lib 15 | $(AR) rcvs $@ $(COBJECTS) $(OBJECTS) 16 | 17 | -lib/libsass.so: $(COBJECTS) $(OBJECTS) | lib 18 | +lib/libsass.so: $(COBJECTS) $(OBJECTS) lib 19 | $(CXX) -shared $(LDFLAGS) -o $@ $(COBJECTS) $(OBJECTS) $(LDLIBS) 20 | 21 | -lib/libsass.dylib: $(COBJECTS) $(OBJECTS) | lib 22 | +lib/libsass.dylib: $(COBJECTS) $(OBJECTS) lib 23 | $(CXX) -shared $(LDFLAGS) -o $@ $(COBJECTS) $(OBJECTS) $(LDLIBS) \ 24 | -install_name @rpath/libsass.dylib 25 | 26 | -lib/libsass.dll: $(COBJECTS) $(OBJECTS) $(RCOBJECTS) | lib 27 | +lib/libsass.dll: $(COBJECTS) $(OBJECTS) $(RCOBJECTS) lib 28 | $(CXX) -shared $(LDFLAGS) -o $@ $(COBJECTS) $(OBJECTS) $(RCOBJECTS) $(LDLIBS) \ 29 | -s -Wl,--subsystem,windows,--out-implib,lib/libsass.a 30 | 31 | -------------------------------------------------------------------------------- /scripts/patches/003-replace-curdir-with-dot.patch: -------------------------------------------------------------------------------- 1 | An instance of the `CURDIR` builtin variable was removed and simply replaced 2 | with a `.`. This replacement was made to address paths with spaces (which 3 | are common in newer versions of Windows). Make 3.79.1 (used by Rtools 3.4) 4 | in Windows 10, for instance, constructs invalid paths when using `CURDIR`. 5 | 6 | diff --git a/src/libsass/Makefile b/src/libsass/Makefile 7 | index 9255f0d..ee36d92 100644 8 | --- a/src/libsass/Makefile 9 | +++ b/src/libsass/Makefile 10 | @@ -74,7 +74,7 @@ else 11 | endif 12 | 13 | ifndef SASS_LIBSASS_PATH 14 | - SASS_LIBSASS_PATH = $(CURDIR) 15 | + SASS_LIBSASS_PATH = . 16 | endif 17 | ifdef SASS_LIBSASS_PATH 18 | CFLAGS += -I $(SASS_LIBSASS_PATH)/include 19 | -------------------------------------------------------------------------------- /scripts/patches/005-remove-pragma-marks.patch: -------------------------------------------------------------------------------- 1 | This removes some diagnostic pragma marks that produce a NOTE during 2 | R CMD check. 3 | 4 | diff --git a/src/libsass/src/parser.hpp b/src/libsass/src/parser.hpp 5 | index 25c39b9..c32a54e 100644 6 | --- a/src/libsass/src/parser.hpp 7 | +++ b/src/libsass/src/parser.hpp 8 | @@ -68,9 +68,6 @@ namespace Sass { 9 | // branches. This is not a bug, just a merging of behaviour into 10 | // one function 11 | 12 | -#pragma clang diagnostic push 13 | -#pragma clang diagnostic ignored "-Wtautological-compare" 14 | - 15 | #endif 16 | 17 | 18 | @@ -227,8 +224,6 @@ namespace Sass { 19 | 20 | #ifdef __clang__ 21 | 22 | -#pragma clang diagnostic pop 23 | - 24 | #endif 25 | 26 | void error(sass::string msg); 27 | -------------------------------------------------------------------------------- /scripts/patches/006-add-newline-fn_numbers.patch: -------------------------------------------------------------------------------- 1 | This adds a newline to the end of file. Lack of a terminating newline 2 | produces a NOTE during R CMD check. 3 | 4 | diff --git a/src/libsass/src/fn_numbers.hpp b/src/libsass/src/fn_numbers.hpp 5 | index dba96be..67bec46 100644 6 | --- a/src/libsass/src/fn_numbers.hpp 7 | +++ b/src/libsass/src/fn_numbers.hpp 8 | @@ -42,4 +42,4 @@ namespace Sass { 9 | 10 | } 11 | 12 | -#endif 13 | \ No newline at end of file 14 | +#endif 15 | -------------------------------------------------------------------------------- /scripts/patches/007-add-newline-sass_functions.patch: -------------------------------------------------------------------------------- 1 | This adds a newline to the end of file. Lack of a terminating newline 2 | produces a NOTE during R CMD check. 3 | 4 | diff --git a/src/libsass/src/sass_functions.hpp b/src/libsass/src/sass_functions.hpp 5 | index 482ed64..bed9560 100644 6 | --- a/src/libsass/src/sass_functions.hpp 7 | +++ b/src/libsass/src/sass_functions.hpp 8 | @@ -47,4 +47,4 @@ struct Sass_Importer { 9 | void* cookie; 10 | }; 11 | 12 | -#endif 13 | \ No newline at end of file 14 | +#endif 15 | -------------------------------------------------------------------------------- /scripts/patches/008-gcc-12-address-warnings: -------------------------------------------------------------------------------- 1 | Avoids some warning messages from gcc-12 that CRAN doesn't like. Example: 2 | src/lexer.hpp:89:15: warning: the address of ‘Sass::Constants::warn_kwd’ will never be NULL [-Waddress] 3 | 4 | Basically the compiler statically knows whether the str is NULL, and doesn't like 5 | there being code that checks. Adding a template specialization for the null case 6 | lets us remove the check. 7 | 8 | 9 | diff --git a/src/libsass/src/lexer.hpp b/src/libsass/src/lexer.hpp 10 | index 360ed22..e4091f4 100644 11 | --- a/src/libsass/src/lexer.hpp 12 | +++ b/src/libsass/src/lexer.hpp 13 | @@ -86,7 +86,6 @@ namespace Sass { 14 | // Regex equivalent: /(?:literal)/ 15 | template 16 | const char* exactly(const char* src) { 17 | - if (str == NULL) return 0; 18 | const char* pre = str; 19 | if (src == NULL) return 0; 20 | // there is a small chance that the search string 21 | @@ -98,6 +97,11 @@ namespace Sass { 22 | return *pre == 0 ? src : 0; 23 | } 24 | 25 | + template <> 26 | + inline const char* exactly(const char* src) { 27 | + return 0; 28 | + } 29 | + 30 | 31 | // Match a single character literal. 32 | // Regex equivalent: /(?:x)/i 33 | @@ -112,7 +116,6 @@ namespace Sass { 34 | // only define lower case alpha chars 35 | template 36 | const char* insensitive(const char* src) { 37 | - if (str == NULL) return 0; 38 | const char* pre = str; 39 | if (src == NULL) return 0; 40 | // there is a small chance that the search string 41 | @@ -124,6 +127,11 @@ namespace Sass { 42 | return *pre == 0 ? src : 0; 43 | } 44 | 45 | + template <> 46 | + inline const char* insensitive(const char* src) { 47 | + return 0; 48 | + } 49 | + 50 | // Match for members of char class. 51 | // Regex equivalent: /[axy]/ 52 | template 53 | -------------------------------------------------------------------------------- /scripts/patches/009-deprecated-declarations.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/libsass/src/json.cpp b/src/libsass/src/json.cpp 2 | index f7d06e4..41ee2f1 100644 3 | --- a/src/libsass/src/json.cpp 4 | +++ b/src/libsass/src/json.cpp 5 | @@ -1286,7 +1286,7 @@ static void emit_number(SB *out, double num) 6 | * like 0.3 -> 0.299999999999999988898 . 7 | */ 8 | char buf[64]; 9 | - sprintf(buf, "%.16g", num); 10 | + snprintf(buf, sizeof(buf), "%.16g", num); 11 | 12 | if (number_is_valid(buf)) 13 | sb_puts(out, buf); 14 | -------------------------------------------------------------------------------- /scripts/patches/010-clang-15-address-warnings.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/libsass/Makefile b/src/libsass/Makefile 2 | index 6f81feb..41e3739 100644 3 | --- a/src/libsass/Makefile 4 | +++ b/src/libsass/Makefile 5 | @@ -110,7 +110,6 @@ ifeq ($(STATIC_LIBSTDCPP),1) 6 | endif 7 | 8 | ifeq ($(UNAME),Darwin) 9 | - CFLAGS += -stdlib=libc++ 10 | CXXFLAGS += -stdlib=libc++ 11 | LDFLAGS += -stdlib=libc++ 12 | endif 13 | -------------------------------------------------------------------------------- /scripts/patches/010-gcc-12-windows-warning.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/libsass/src/memory/shared_ptr.hpp b/src/libsass/src/memory/shared_ptr.hpp 2 | index 09d263a..ba98b94 100644 3 | --- a/src/libsass/src/memory/shared_ptr.hpp 4 | +++ b/src/libsass/src/memory/shared_ptr.hpp 5 | @@ -11,6 +11,14 @@ 6 | #include 7 | #include 8 | 9 | +// Workaround for what appears to be a false positive (Wuse-after-free) warning in gcc-12 on Windows. 10 | +// See here for evidence of other false positives: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=Wuse-after-free 11 | +// And here for a discussion of the issue: https://github.com/rstudio/sass/issues/127 12 | +#if __GNUC__ > 11 && _WIN32 13 | +/*IGNORE*/ #pragma GCC diagnostic push 14 | +/*IGNORE*/ #pragma GCC diagnostic ignored "-Wuse-after-free" 15 | +#endif 16 | + 17 | // https://lokiastari.com/blog/2014/12/30/c-plus-plus-by-example-smart-pointer/index.html 18 | // https://lokiastari.com/blog/2015/01/15/c-plus-plus-by-example-smart-pointer-part-ii/index.html 19 | // https://lokiastari.com/blog/2015/01/23/c-plus-plus-by-example-smart-pointer-part-iii/index.html 20 | -------------------------------------------------------------------------------- /scripts/rhub.R: -------------------------------------------------------------------------------- 1 | 2 | if (!require("rhub", quietly = TRUE)) install.packages("rhub") 3 | 4 | root_store <- rprojroot::find_package_root_file() 5 | 6 | build_path <- file.path(root_store, "scripts", "build") 7 | 8 | dir.create( 9 | file.path(root_store, "scripts", "build"), 10 | recursive = TRUE, showWarnings = FALSE 11 | ) 12 | 13 | build_file <- devtools::build(root_store, build_path) 14 | 15 | platforms <- 16 | c("windows-x86_64-release", 17 | "debian-gcc-release", 18 | rhub:::default_cran_check_platforms(build_file)) 19 | 20 | # platforms <- "debian-gcc-release" 21 | 22 | check_output <- 23 | rhub::check_for_cran( 24 | build_file, 25 | email = "carson@rstudio.com", 26 | platforms = platforms, 27 | show_status = FALSE 28 | ) 29 | 30 | for (i in seq_along(platforms)) { 31 | check_output$livelog(i) 32 | } 33 | 34 | check_output$web() 35 | 36 | print(check_output) 37 | -------------------------------------------------------------------------------- /scripts/update_libsass.R: -------------------------------------------------------------------------------- 1 | # Script to update libsass from https://github.com/sass/libsass/ 2 | # After running this, run the scripts/apply_libsass_patches.R script 3 | 4 | (function() { 5 | owd <- getwd() 6 | on.exit({setwd(owd)}) 7 | 8 | 9 | ROOT <- rprojroot::find_package_root_file() 10 | setwd(ROOT) 11 | 12 | LIBSASS_VERSION <- "3.6.5" 13 | 14 | url <- sprintf( 15 | "https://github.com/sass/libsass/archive/%s.tar.gz", 16 | LIBSASS_VERSION 17 | ) 18 | 19 | destfile <- tempfile("libsass-tarball-") 20 | on.exit({unlink(destfile)}, add = TRUE) 21 | download.file(url, destfile = destfile) 22 | 23 | exdir <- file.path("src") 24 | 25 | untar(tarfile = destfile, exdir = exdir) 26 | 27 | finaldir <- file.path(exdir, "libsass") 28 | unlink(finaldir, recursive = TRUE) 29 | file.rename( 30 | file.path(exdir, paste0("libsass-", LIBSASS_VERSION)), 31 | finaldir 32 | ) 33 | 34 | message("Saved in ", finaldir) 35 | })() 36 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.dll 4 | -------------------------------------------------------------------------------- /src/Makevars: -------------------------------------------------------------------------------- 1 | PKG_LIBS = ./libsass/lib/libsass.a 2 | PKG_CPPFLAGS = -I./libsass/include 3 | 4 | STATLIB = libsass/lib/libsass.a 5 | 6 | all: $(SHLIB) cleanup 7 | 8 | $(SHLIB): $(STATLIB) 9 | 10 | $(STATLIB): 11 | MAKEFLAGS= CC="$(CC)" CFLAGS="$(CFLAGS)" CXX="$(CXX)" AR="$(AR)" LDFLAGS="$(LDFLAGS)" $(MAKE) -C libsass 12 | 13 | cleanup: $(SHLIB) 14 | @rm -f $(STATLIB) 15 | 16 | clean: 17 | MAKEFLAGS= $(MAKE) -C libsass clean 18 | rm -Rf $(SHLIB) $(OBJECTS) $(STATLIB) 19 | 20 | .PHONY: all cleanup clean 21 | -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | # Updates and patches to `libsass` 2 | 3 | ## Updating 4 | 5 | [libsass](https://github.com/sass/libsass) can be updated with the script `update_libsass.R`. The file contains the commit hash (in `master`) from which the source was cloned. The version number was obtained by running the `version.sh` shell script in a clean git checkout of libsass. 6 | 7 | The `update_libsass.R` script should be run first, immediately followed by running the `apply_libsass_patches.R` script. 8 | 9 | ## Making a new patch 10 | 11 | Here are the recommended steps for creating a new patch: 12 | 13 | 1. Make any necessary changes to files in `src`. 14 | 1. Create a patch with a command like `git diff {parent_commit_hash^} {child_commit_hash} > scripts/patches/[000]-a-description.patch`. 15 | 1. (Optional) Edit the patch file and add a comment to the top that explains what the patch does. 16 | 1. Add the new `.patch` file to the repo with a descriptive commit message. 17 | 1. Test your changes. 18 | 19 | ## Notes about compiled sources 20 | 21 | - 001-remove-makefile-pipes.patch: The order-only prerequisite operators (|) were removed since they cannot be interpreted by Make 3.79.1 (which is used by Rtools 3.4). There were 3 instances 22 | removed by this patch. 23 | 24 | -------------------------------------------------------------------------------- /src/compile.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPILE_H 2 | #define COMPILE_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | SEXP compile_file(SEXP file, SEXP options); 11 | SEXP compile_data(SEXP data, SEXP options); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/init.cpp: -------------------------------------------------------------------------------- 1 | #include "compile.h" 2 | #include 3 | 4 | static const R_CallMethodDef callMethods[] = { 5 | {"C_compile_file", (DL_FUNC) &compile_file, 2}, 6 | {"C_compile_data", (DL_FUNC) &compile_data, 2}, 7 | {NULL, NULL, 0} 8 | }; 9 | 10 | extern "C" void R_init_sass(DllInfo* info) { 11 | R_registerRoutines(info, NULL, callMethods, NULL, NULL); 12 | R_useDynamicSymbols(info, FALSE); 13 | R_forceSymbols(info, TRUE); 14 | } 15 | -------------------------------------------------------------------------------- /src/libsass/.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 2 12 | 13 | [{Makefile,GNUmakefile.am}] 14 | indent_style = tab 15 | indent_size = 4 16 | -------------------------------------------------------------------------------- /src/libsass/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /src/libsass/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | [todo]: # (Title: Be as meaningful as possible) 2 | [todo]: # (Title: Try to use 60 or less chars) 3 | 4 | [todo]: # (This is only a template!) 5 | [todo]: # (remove unneeded bits) 6 | [todo]: # (use github preview!) 7 | 8 | ## input.scss 9 | 10 | [todo]: # (always test and report with scss syntax) 11 | [todo]: # (use sass only when results differ from scss) 12 | 13 | ```scss 14 | test { 15 | content: bar 16 | } 17 | ``` 18 | 19 | ## Actual results 20 | 21 | [todo]: # (update version info!) 22 | 23 | [libsass 3.X.y][1] 24 | ```css 25 | test { 26 | content: bar; } 27 | ``` 28 | 29 | ## Expected result 30 | 31 | [todo]: # (update version info!) 32 | 33 | ruby sass 3.X.y 34 | ```css 35 | test { 36 | content: bar; } 37 | ``` 38 | 39 | [todo]: # (update version info!) 40 | [todo]: # (example for node-sass!) 41 | 42 | version info: 43 | ```cmd 44 | $ node-sass --version 45 | node-sass 3.X.y (Wrapper) [JavaScript] 46 | libsass 3.X.y (Sass Compiler) [C/C++] 47 | ``` 48 | 49 | [todo]: # (Go to http://libsass.ocbnet.ch/srcmap) 50 | [todo]: # (Enter your SCSS code and hit compile) 51 | [todo]: # (Click `bookmark` and replace the url) 52 | [todo]: # (link is used in actual results above) 53 | 54 | [1]: http://libsass.ocbnet.ch/srcmap/#dGVzdCB7CiAgY29udGVudDogYmFyOyB9Cg== 55 | -------------------------------------------------------------------------------- /src/libsass/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous stuff 2 | 3 | /sassc 4 | /sass-spec 5 | /plugins/ 6 | 7 | VERSION 8 | .DS_Store 9 | .sass-cache 10 | *.gem 11 | *.gcno 12 | .svn/* 13 | .cproject 14 | .project 15 | .settings/ 16 | *.db 17 | *.aps 18 | 19 | # Configuration stuff 20 | 21 | GNUmakefile.in 22 | GNUmakefile 23 | /aclocal.m4 24 | /autom4te.cache/ 25 | /src/config.h 26 | /config.h.in 27 | /config.log 28 | /config.status 29 | /configure 30 | /libtool 31 | /m4/libtool.m4 32 | /m4/ltoptions.m4 33 | /m4/ltsugar.m4 34 | /m4/ltversion.m4 35 | /m4/lt~obsolete.m4 36 | /script/ar-lib 37 | /script/compile 38 | /script/config.guess 39 | /script/config.sub 40 | /script/depcomp 41 | /script/install-sh 42 | /script/ltmain.sh 43 | /script/missing 44 | /script/test-driver 45 | /src/stamp-h1 46 | /src/Makefile.in 47 | /src/Makefile 48 | libsass/* 49 | 50 | # Build stuff 51 | 52 | *.o 53 | *.lo 54 | *.so 55 | *.dll 56 | *.a 57 | *.suo 58 | *.sdf 59 | *.opendb 60 | *.opensdf 61 | a.out 62 | libsass.js 63 | tester 64 | tester.exe 65 | build/ 66 | config.h.in* 67 | lib/pkgconfig/ 68 | 69 | bin/* 70 | .deps/ 71 | .libs/ 72 | win/bin 73 | *.user 74 | win/*.db 75 | 76 | # Final results 77 | 78 | sassc++ 79 | libsass.la 80 | src/support/libsass.pc 81 | 82 | # Cloned testing dirs 83 | sassc/ 84 | sass-spec/ 85 | 86 | installer/ 87 | 88 | # Visual Studio cache directory 89 | .vs/ 90 | 91 | # Visual Studio Code 92 | .vscode/* 93 | !.vscode/settings.json 94 | !.vscode/tasks.json 95 | !.vscode/launch.json 96 | !.vscode/extensions.json 97 | -------------------------------------------------------------------------------- /src/libsass/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | Sass is more than a technology; Sass is driven by the community of individuals 2 | that power its development and use every day. As a community, we want to embrace 3 | the very differences that have made our collaboration so powerful, and work 4 | together to provide the best environment for learning, growing, and sharing of 5 | ideas. It is imperative that we keep Sass a fun, welcoming, challenging, and 6 | fair place to play. 7 | 8 | [The full community guidelines can be found on the Sass website.][link] 9 | 10 | [link]: https://sass-lang.com/community-guidelines 11 | -------------------------------------------------------------------------------- /src/libsass/COPYING: -------------------------------------------------------------------------------- 1 | 2 | Copyright (C) 2012 by Hampton Catlin 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 8 | of the Software, and to permit persons to whom the Software is furnished to do 9 | so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | 22 | 23 | The following files in the spec were taken from the original Ruby Sass project which 24 | is copyright Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein and under 25 | the same license. 26 | -------------------------------------------------------------------------------- /src/libsass/INSTALL: -------------------------------------------------------------------------------- 1 | // Autotools requires us to have this file. Boo. 2 | -------------------------------------------------------------------------------- /src/libsass/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (C) 2012-2016 by the Sass Open Source Foundation 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 8 | of the Software, and to permit persons to whom the Software is furnished to do 9 | so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | 22 | 23 | The following files in the spec were taken from the original Ruby Sass project which 24 | is copyright Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein and under 25 | the same license. 26 | -------------------------------------------------------------------------------- /src/libsass/SECURITY.md: -------------------------------------------------------------------------------- 1 | Serious about security 2 | ====================== 3 | 4 | The LibSass team recognizes the important contributions the security research 5 | community can make. We therefore encourage reporting security issues with the 6 | code contained in this repository. 7 | 8 | If you believe you have discovered a security vulnerability, please report it at 9 | https://hackerone.com/libsass instead of GitHub. 10 | 11 | -------------------------------------------------------------------------------- /src/libsass/contrib/libsass.spec: -------------------------------------------------------------------------------- 1 | Name: libsass 2 | Version: %{version} 3 | Release: 1%{?dist} 4 | Summary: A C/C++ implementation of a Sass compiler 5 | 6 | License: MIT 7 | URL: http://libsass.org 8 | Source0: %{name}-%{version}.tar.gz 9 | 10 | BuildRequires: gcc-c++ >= 4.7 11 | BuildRequires: autoconf 12 | BuildRequires: automake 13 | BuildRequires: libtool 14 | 15 | 16 | %description 17 | LibSass is a C/C++ port of the Sass engine. The point is to be simple, fast, and easy to integrate. 18 | 19 | %package devel 20 | Summary: Development files for %{name} 21 | Requires: %{name}%{?_isa} = %{version}-%{release} 22 | 23 | 24 | %description devel 25 | The %{name}-devel package contains libraries and header files for 26 | developing applications that use %{name}. 27 | 28 | 29 | %prep 30 | %setup -q 31 | autoreconf --force --install 32 | 33 | 34 | %build 35 | %configure --disable-static \ 36 | --disable-tests \ 37 | --enable-shared 38 | 39 | make %{?_smp_mflags} 40 | 41 | 42 | %install 43 | %make_install 44 | find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' 45 | 46 | 47 | %post -p /sbin/ldconfig 48 | 49 | %postun -p /sbin/ldconfig 50 | 51 | 52 | %files 53 | %doc Readme.md LICENSE 54 | %{_libdir}/*.so.* 55 | 56 | %files devel 57 | %doc 58 | %{_includedir}/* 59 | %{_libdir}/*.so 60 | %{_libdir}/pkgconfig/*.pc 61 | 62 | 63 | %changelog 64 | * Tue Feb 10 2015 Gawain Lynch - 3.1.0-1 65 | - Initial SPEC file 66 | 67 | -------------------------------------------------------------------------------- /src/libsass/contrib/plugin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // gcc: g++ -shared plugin.cpp -o plugin.so -fPIC -Llib -lsass 7 | // mingw: g++ -shared plugin.cpp -o plugin.dll -Llib -lsass 8 | 9 | extern "C" const char* ADDCALL libsass_get_version() { 10 | return libsass_version(); 11 | } 12 | 13 | union Sass_Value* custom_function(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Compiler* comp) 14 | { 15 | // get context/option struct associated with this compiler 16 | struct Sass_Context* ctx = sass_compiler_get_context(comp); 17 | struct Sass_Options* opts = sass_compiler_get_options(comp); 18 | // get the cookie from function descriptor 19 | void* cookie = sass_function_get_cookie(cb); 20 | // we actually abuse the void* to store an "int" 21 | return sass_make_number((intptr_t)cookie, "px"); 22 | } 23 | 24 | extern "C" Sass_Function_List ADDCALL libsass_load_functions() 25 | { 26 | // allocate a custom function caller 27 | Sass_Function_Entry c_func = 28 | sass_make_function("foo()", custom_function, (void*)42); 29 | // create list of all custom functions 30 | Sass_Function_List fn_list = sass_make_function_list(1); 31 | // put the only function in this plugin to the list 32 | sass_function_set_list_entry(fn_list, 0, c_func); 33 | // return the list 34 | return fn_list; 35 | } 36 | 37 | Sass_Import_List custom_importer(const char* cur_path, Sass_Importer_Entry cb, struct Sass_Compiler* comp) 38 | { 39 | // get the cookie from importer descriptor 40 | void* cookie = sass_importer_get_cookie(cb); 41 | // create a list to hold our import entries 42 | Sass_Import_List incs = sass_make_import_list(1); 43 | // create our only import entry (route path back) 44 | incs[0] = sass_make_import_entry(cur_path, 0, 0); 45 | // return imports 46 | return incs; 47 | } 48 | 49 | extern "C" Sass_Importer_List ADDCALL libsass_load_importers() 50 | { 51 | // allocate a custom function caller 52 | Sass_Importer_Entry c_imp = 53 | sass_make_importer(custom_importer, - 99, (void*)42); 54 | // create list of all custom functions 55 | Sass_Importer_List imp_list = sass_make_importer_list(1); 56 | // put the only function in this plugin to the list 57 | sass_importer_set_list_entry(imp_list, 0, c_imp); 58 | // return the list 59 | return imp_list; 60 | } 61 | -------------------------------------------------------------------------------- /src/libsass/docs/README.md: -------------------------------------------------------------------------------- 1 | ## LibSass documentation 2 | 3 | LibSass is just a library. To run the code locally (i.e. to compile your 4 | stylesheets), you need an implementer. SassC is an implementer written in C. 5 | There are a number of other implementations of LibSass - for example NodeJS. 6 | We encourage you to write your own port - the whole point of LibSass is that 7 | we want to bring Sass to many other languages! 8 | 9 | ## LibSass road-map 10 | 11 | Since ruby-sass was retired in 2019 in favor of dart-sass, we slowly move 12 | toward full compatibility with the latest Sass specifications, although 13 | features like the module `@use` system may take a bit longer to add. 14 | 15 | ### Implementing LibSass 16 | 17 | If you're interested in implementing LibSass in your own project see the 18 | [API Documentation](api-doc.md) which now includes implementing your own 19 | [Sass functions](api-function.md). You may wish to [look at other 20 | implementations](implementations.md) for your language of choice. 21 | 22 | ### Contributing to LibSass 23 | 24 | | Issue Tracker | Issue Triage | Community Guidelines | 25 | |-------------------|----------------------------------|-----------------------------| 26 | | We're always needing help, so check out our issue tracker, help some people out, and read our article on [Contributing](contributing.md)! It's got all the details on what to do! | To help understand the process of triaging bugs, have a look at our [Issue-Triage](triage.md) document. | Oh, and don't forget we always follow [Sass Community Guidelines](https://sass-lang.com/community-guidelines). Be nice and everyone else will be nice too! | 27 | 28 | ### Building LibSass 29 | 30 | Please refer to the steps on [Building LibSass](build.md) 31 | 32 | ### Developing LibSass 33 | 34 | Please refer to [Developing LibSass](developing.md) 35 | -------------------------------------------------------------------------------- /src/libsass/docs/api-function-example.md: -------------------------------------------------------------------------------- 1 | ## Example main.c 2 | 3 | ```C 4 | #include 5 | #include 6 | #include "sass/context.h" 7 | 8 | union Sass_Value* call_fn_foo(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Compiler* comp) 9 | { 10 | // get context/option struct associated with this compiler 11 | struct Sass_Context* ctx = sass_compiler_get_context(comp); 12 | struct Sass_Options* opts = sass_compiler_get_options(comp); 13 | // get information about previous importer entry from the stack 14 | Sass_Import_Entry import = sass_compiler_get_last_import(comp); 15 | const char* prev_abs_path = sass_import_get_abs_path(import); 16 | const char* prev_imp_path = sass_import_get_imp_path(import); 17 | // get the cookie from function descriptor 18 | void* cookie = sass_function_get_cookie(cb); 19 | // we actually abuse the void* to store an "int" 20 | return sass_make_number((intptr_t)cookie, "px"); 21 | } 22 | 23 | int main( int argc, const char* argv[] ) 24 | { 25 | 26 | // get the input file from first argument or use default 27 | const char* input = argc > 1 ? argv[1] : "styles.scss"; 28 | 29 | // create the file context and get all related structs 30 | struct Sass_File_Context* file_ctx = sass_make_file_context(input); 31 | struct Sass_Context* ctx = sass_file_context_get_context(file_ctx); 32 | struct Sass_Options* ctx_opt = sass_context_get_options(ctx); 33 | 34 | // allocate a custom function caller 35 | Sass_Function_Entry fn_foo = 36 | sass_make_function("foo()", call_fn_foo, (void*)42); 37 | 38 | // create list of all custom functions 39 | Sass_Function_List fn_list = sass_make_function_list(1); 40 | sass_function_set_list_entry(fn_list, 0, fn_foo); 41 | sass_option_set_c_functions(ctx_opt, fn_list); 42 | 43 | // context is set up, call the compile step now 44 | int status = sass_compile_file_context(file_ctx); 45 | 46 | // print the result or the error to the stdout 47 | if (status == 0) puts(sass_context_get_output_string(ctx)); 48 | else puts(sass_context_get_error_message(ctx)); 49 | 50 | // release allocated memory 51 | sass_delete_file_context(file_ctx); 52 | 53 | // exit status 54 | return status; 55 | 56 | } 57 | ``` 58 | 59 | ### Compile main.c 60 | 61 | ```bash 62 | gcc -c main.c -o main.o 63 | gcc -o sample main.o -lsass 64 | echo "foo { margin: foo(); }" > foo.scss 65 | ./sample foo.scss => "foo { margin: 42px }" 66 | ``` 67 | 68 | -------------------------------------------------------------------------------- /src/libsass/docs/api-function-internal.md: -------------------------------------------------------------------------------- 1 | ```C 2 | // Struct to hold custom function callback 3 | struct Sass_Function { 4 | const char* signature; 5 | Sass_Function_Fn function; 6 | void* cookie; 7 | }; 8 | ``` 9 | -------------------------------------------------------------------------------- /src/libsass/docs/api-importer-internal.md: -------------------------------------------------------------------------------- 1 | ```C 2 | // External import entry 3 | struct Sass_Import { 4 | char* imp_path; // path as found in the import statement 5 | char *abs_path; // path after importer has resolved it 6 | char* source; 7 | char* srcmap; 8 | // error handling 9 | char* error; 10 | size_t line; 11 | size_t column; 12 | }; 13 | 14 | // Struct to hold importer callback 15 | struct Sass_Importer { 16 | Sass_Importer_Fn importer; 17 | double priority; 18 | void* cookie; 19 | }; 20 | ``` 21 | -------------------------------------------------------------------------------- /src/libsass/docs/api-value-example.md: -------------------------------------------------------------------------------- 1 | ## Example operation.c 2 | 3 | ```C 4 | #include 5 | #include 6 | #include "sass/values.h" 7 | 8 | int main( int argc, const char* argv[] ) 9 | { 10 | 11 | // create two new sass values to be added 12 | union Sass_Value* string = sass_make_string("String"); 13 | union Sass_Value* number = sass_make_number(42, "nits"); 14 | 15 | // invoke the add operation which returns a new sass value 16 | union Sass_Value* total = sass_value_op(ADD, string, number); 17 | 18 | // no further use for the two operands 19 | sass_delete_value(string); 20 | sass_delete_value(number); 21 | 22 | // this works since libsass will always return a 23 | // string for add operations with a string as the 24 | // left hand side. But you should never rely on it! 25 | puts(sass_string_get_value(total)); 26 | 27 | // invoke stringification (uncompressed with precision of 5) 28 | union Sass_Value* result = sass_value_stringify(total, false, 5); 29 | 30 | // no further use for the sum 31 | sass_delete_value(total); 32 | 33 | // print the result - you may want to make 34 | // sure result is indeed a string, although 35 | // stringify guarantees to return a string 36 | // if (sass_value_is_string(result)) {} 37 | // really depends on your level of paranoia 38 | puts(sass_string_get_value(result)); 39 | 40 | // finally free result 41 | sass_delete_value(result); 42 | 43 | // exit status 44 | return 0; 45 | 46 | } 47 | ``` 48 | 49 | ## Compile operation.c 50 | 51 | ```bash 52 | gcc -c operation.c -o operation.o 53 | gcc -o operation operation.o -lsass 54 | ./operation # => String42nits 55 | ``` 56 | -------------------------------------------------------------------------------- /src/libsass/docs/api-value-internal.md: -------------------------------------------------------------------------------- 1 | ```C 2 | struct Sass_Unknown { 3 | enum Sass_Tag tag; 4 | }; 5 | 6 | struct Sass_Boolean { 7 | enum Sass_Tag tag; 8 | bool value; 9 | }; 10 | 11 | struct Sass_Number { 12 | enum Sass_Tag tag; 13 | double value; 14 | char* unit; 15 | }; 16 | 17 | struct Sass_Color { 18 | enum Sass_Tag tag; 19 | double r; 20 | double g; 21 | double b; 22 | double a; 23 | }; 24 | 25 | struct Sass_String { 26 | enum Sass_Tag tag; 27 | char* value; 28 | }; 29 | 30 | struct Sass_List { 31 | enum Sass_Tag tag; 32 | enum Sass_Separator separator; 33 | size_t length; 34 | // null terminated "array" 35 | union Sass_Value** values; 36 | }; 37 | 38 | struct Sass_Map { 39 | enum Sass_Tag tag; 40 | size_t length; 41 | struct Sass_MapPair* pairs; 42 | }; 43 | 44 | struct Sass_Null { 45 | enum Sass_Tag tag; 46 | }; 47 | 48 | struct Sass_Error { 49 | enum Sass_Tag tag; 50 | char* message; 51 | }; 52 | 53 | struct Sass_Warning { 54 | enum Sass_Tag tag; 55 | char* message; 56 | }; 57 | 58 | union Sass_Value { 59 | struct Sass_Unknown unknown; 60 | struct Sass_Boolean boolean; 61 | struct Sass_Number number; 62 | struct Sass_Color color; 63 | struct Sass_String string; 64 | struct Sass_List list; 65 | struct Sass_Map map; 66 | struct Sass_Null null; 67 | struct Sass_Error error; 68 | struct Sass_Warning warning; 69 | }; 70 | 71 | struct Sass_MapPair { 72 | union Sass_Value* key; 73 | union Sass_Value* value; 74 | }; 75 | ``` 76 | 77 | -------------------------------------------------------------------------------- /src/libsass/docs/build-on-darwin.md: -------------------------------------------------------------------------------- 1 | To install LibSass, make sure the OS X build tools are installed: 2 | 3 | xcode-select --install 4 | 5 | ## Homebrew 6 | 7 | To install homebrew, see [http://brew.sh](http://brew.sh) 8 | 9 | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 10 | 11 | You can install the latest version of LibSass quite easily with brew. 12 | 13 | brew install --HEAD libsass 14 | 15 | To update this, do: 16 | 17 | brew reinstall --HEAD libsass 18 | 19 | Brew will build static and shared libraries, and a `libsass.pc` file in `/usr/local/lib/pkgconfig`. 20 | 21 | To use `libsass.pc`, make sure this path is in your `PKG_CONFIG_PATH` 22 | 23 | export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig 24 | 25 | ## Manually 26 | 27 | See the linux instructions [Building-with-autotools](build-with-autotools.md) or [Building-with-makefiles](build-with-makefiles.md) 28 | -------------------------------------------------------------------------------- /src/libsass/docs/build-on-gentoo.md: -------------------------------------------------------------------------------- 1 | Here are two ebuilds to compile LibSass and sassc on gentoo linux. If you do not know how to use these ebuilds, you should probably read the gentoo wiki page about [portage overlays](http://wiki.gentoo.org/wiki/Overlay). 2 | 3 | ## www-misc/libsass/libsass-9999.ebuild 4 | ```ebuild 5 | EAPI=4 6 | 7 | inherit eutils git-2 autotools 8 | 9 | DESCRIPTION="A C/C++ implementation of a Sass compiler." 10 | HOMEPAGE="http://libsass.org/" 11 | EGIT_PROJECT='libsass' 12 | EGIT_REPO_URI="https://github.com/sass/libsass.git" 13 | LICENSE="MIT" 14 | SLOT="0" 15 | KEYWORDS="" 16 | IUSE="" 17 | DEPEND="" 18 | RDEPEND="${DEPEND}" 19 | DEPEND="${DEPEND}" 20 | 21 | pkg_pretend() { 22 | # older gcc is not supported 23 | local major=$(gcc-major-version) 24 | local minor=$(gcc-minor-version) 25 | [[ "${MERGE_TYPE}" != "binary" && ( $major > 4 || ( $major == 4 && $minor < 5 ) ) ]] && \ 26 | die "Sorry, but gcc earlier than 4.5 will not work for LibSass." 27 | } 28 | 29 | src_prepare() { 30 | eautoreconf 31 | } 32 | ``` 33 | 34 | ## www-misc/sassc/sassc-9999.ebuild 35 | ```ebuild 36 | EAPI=4 37 | 38 | inherit eutils git-2 autotools 39 | 40 | DESCRIPTION="Command Line Tool for LibSass." 41 | HOMEPAGE="http://libsass.org/" 42 | EGIT_PROJECT='sassc' 43 | EGIT_REPO_URI="https://github.com/sass/sassc.git" 44 | LICENSE="MIT" 45 | SLOT="0" 46 | KEYWORDS="" 47 | IUSE="" 48 | DEPEND="www-misc/libsass" 49 | RDEPEND="${DEPEND}" 50 | DEPEND="${DEPEND}" 51 | 52 | src_prepare() { 53 | eautoreconf 54 | } 55 | ``` 56 | -------------------------------------------------------------------------------- /src/libsass/docs/build-shared-library.md: -------------------------------------------------------------------------------- 1 | This page is mostly intended for people that want to build a system library that gets distributed via RPMs or other means. This is currently in a experimental phase, as we currently do not really guarantee any ABI forward compatibility. The C API was rewritten to make this possible in the future, but we want to wait some more time till we can call this final and stable. 2 | 3 | Building via autotools 4 | -- 5 | 6 | You want to build a system library only via autotools, since it will create the proper `libtool` files to make it loadable on multiple systems. We hope this works correctly, but nobody of the `libsass` core team has much knowledge in this area. Therefore we are open for comments or improvements by people that have more experience in that matter (like package maintainers from various linux distributions). 7 | 8 | ```bash 9 | apt-get install autoconf libtool 10 | git clone https://github.com/sass/libsass.git 11 | cd libsass 12 | autoreconf --force --install 13 | ./configure \ 14 | --disable-tests \ 15 | --disable-static \ 16 | --enable-shared \ 17 | --prefix=/usr 18 | make -j5 install 19 | cd .. 20 | ``` 21 | 22 | This should install these files 23 | ```bash 24 | # $ ls -la /usr/lib/libsass.* 25 | /usr/lib/libsass.la 26 | /usr/lib/libsass.so -> libsass.so.0.0.9 27 | /usr/lib/libsass.so.0 -> libsass.so.0.0.9 28 | /usr/lib/libsass.so.0.0.9 29 | # $ ls -la /usr/include/sass* 30 | /usr/include/sass.h 31 | /usr/include/sass2scss.h 32 | /usr/include/sass/context.h 33 | /usr/include/sass/functions.h 34 | /usr/include/sass/values.h 35 | ``` 36 | -------------------------------------------------------------------------------- /src/libsass/docs/build-with-autotools.md: -------------------------------------------------------------------------------- 1 | ### Get the sources 2 | ```bash 3 | # using git is preferred 4 | git clone https://github.com/sass/libsass.git 5 | # only needed for sassc and/or testsuite 6 | git clone https://github.com/sass/sassc.git libsass/sassc 7 | git clone https://github.com/sass/sass-spec.git libsass/sass-spec 8 | ``` 9 | 10 | ### Prerequisites 11 | 12 | In order to run autotools you need a few tools installed on your system. 13 | ```bash 14 | yum install automake libtool # RedHat Linux 15 | emerge -a automake libtool # Gentoo Linux 16 | pkgin install automake libtool # SmartOS 17 | ``` 18 | 19 | 20 | ### Create configure script 21 | ```bash 22 | cd libsass 23 | autoreconf --force --install 24 | cd .. 25 | ``` 26 | 27 | ### Create custom makefiles 28 | ```bash 29 | cd libsass 30 | ./configure \ 31 | --disable-tests \ 32 | --disable-shared \ 33 | --prefix=/usr 34 | cd .. 35 | ``` 36 | 37 | ### Build the library 38 | ```bash 39 | make -C libsass -j5 40 | ``` 41 | 42 | ### Install the library 43 | The library will be installed to the location given as `prefix` to `configure`. This is standard behavior for autotools and not `libsass` specific. 44 | ```bash 45 | make -C libsass -j5 install 46 | ``` 47 | 48 | ### Configure options 49 | The `configure` script is created by autotools. To get an overview of available options you can call `./configure --help`. When you execute this script, it will create specific makefiles, which you then use via the regular make command. 50 | 51 | There are some `libsass` specific options: 52 | 53 | ``` 54 | Optional Features: 55 | --enable-tests enable testing the build 56 | --enable-coverage enable coverage report for test suite 57 | --enable-shared build shared libraries [default=yes] 58 | --enable-static build static libraries [default=yes] 59 | 60 | Optional Packages: 61 | --with-sassc-dir= specify directory of sassc sources for 62 | testing (default: sassc) 63 | --with-sass-spec-dir= specify directory of sass-spec for testing 64 | (default: sass-spec) 65 | ``` 66 | 67 | ### Build sassc and run spec test-suite 68 | 69 | ```bash 70 | cd libsass 71 | autoreconf --force --install 72 | ./configure \ 73 | --enable-tests \ 74 | --enable-shared \ 75 | --prefix=/usr 76 | make -j5 test_build 77 | cd .. 78 | ``` 79 | -------------------------------------------------------------------------------- /src/libsass/docs/build-with-makefiles.md: -------------------------------------------------------------------------------- 1 | ### Get the sources 2 | ```bash 3 | # using git is preferred 4 | git clone https://github.com/sass/libsass.git 5 | # only needed for sassc and/or testsuite 6 | git clone https://github.com/sass/sassc.git libsass/sassc 7 | git clone https://github.com/sass/sass-spec.git libsass/sass-spec 8 | ``` 9 | 10 | ### Decide for static or shared library 11 | 12 | `libsass` can be built and linked as a `static` or as a `shared` library. The default is `static`. To change it you can set the `BUILD` environment variable: 13 | 14 | ```bash 15 | export BUILD="shared" 16 | ``` 17 | 18 | Alternatively you can also define it directly when calling make: 19 | 20 | ```bash 21 | BUILD="shared" make ... 22 | ``` 23 | 24 | ### Compile the library 25 | ```bash 26 | make -C libsass -j5 27 | ``` 28 | 29 | ### Results can be found in 30 | ```bash 31 | $ ls libsass/lib 32 | libsass.a libsass.so 33 | ``` 34 | 35 | ### Install onto the system 36 | 37 | We recommend to use [autotools to install](build-with-autotools.md) libsass onto the 38 | system, since that brings all the benefits of using libtools as the main install method. 39 | If you still want to install libsass via the makefile, you need to make sure that gnu 40 | `install` utility (or compatible) is installed on your system. 41 | ```bash 42 | yum install coreutils # RedHat Linux 43 | emerge -a coreutils # Gentoo Linux 44 | pkgin install coreutils # SmartOS 45 | ``` 46 | 47 | You can set the install location by setting `PREFIX` 48 | ```bash 49 | PREFIX="/opt/local" make install 50 | ``` 51 | 52 | 53 | ### Compling sassc 54 | 55 | ```bash 56 | # Let build know library location 57 | export SASS_LIBSASS_PATH="`pwd`/libsass" 58 | # Invokes the sassc makefile 59 | make -C libsass -j5 sassc 60 | ``` 61 | 62 | ### Run the spec test-suite 63 | 64 | ```bash 65 | # needs ruby available 66 | # also gem install minitest 67 | make -C libsass -j5 test_build 68 | ``` 69 | -------------------------------------------------------------------------------- /src/libsass/docs/contributing.md: -------------------------------------------------------------------------------- 1 | First of all, welcome! Thanks for even reading this page. If you're here, you're probably wondering what you can do to help make the LibSass project even more awesome. And, even having that feeling means you are awesome! 2 | 3 | ## I'm a programmer 4 | 5 | Awesome! We need your help. The best thing to do is go find issues that are tagged with both "bug" and "test written". We do spec driven development here and these issues have a test that's written already in the sass-spec project. Go find the test by going to sass-spec/spec/LibSass-todo-issues/issue_XXX/ where XXX is the issue number. Write the code, and compile, and then issue a pull request referencing the issue. We'll quickly verify it and get it merged in! 6 | 7 | To get your dev environment setup, check out our article on [Setup-Dev-Environment](setup-environment.md). 8 | 9 | ## I'm not a backend programmer 10 | 11 | COOL! We also need your help. Doing [Issue-Triage](triage.md) is a big deal and something we need constant help with. That means helping to verify issues, write tests for them, and make sure they are getting fixed. It's being part of the smiling face of the project. 12 | 13 | Also, we need help with the Sass-Spec project itself. Just people to organize, refactor, and understand the tests in there. 14 | 15 | ## I don't know what a computer is? 16 | 17 | Hmm.... well, it's the thing you are looking at right now. Ummm... check out training courses! Then, come back and join us! 18 | -------------------------------------------------------------------------------- /src/libsass/docs/dev-profiling.md: -------------------------------------------------------------------------------- 1 | # Profiling LibSass 2 | 3 | ## Linux perf and pprof 4 | 5 | On Linux, you can record the profile with `perf` and inspect it with `pprof`. 6 | 7 | ### Install required tools 8 | 9 | Pre-requisites: 10 | 11 | 1. Linux `perf`, commonly found in the `linux-tools-generic` package. 12 | 2. [go], for installing `pprof`. 13 | 3. [bazel], for installing `perf_to_profile`. 14 | 15 | [go]: https://golang.org 16 | [bazel]: https://bazel.build 17 | 18 | First, install `pprof` with: 19 | 20 | ```bash 21 | go get -u github.com/google/pprof 22 | ``` 23 | 24 | Then, build and install `perf_to_profile`: 25 | 26 | ```bash 27 | git clone https://github.com/google/perf_data_converter 28 | cd perf_data_converter 29 | bazel build -c opt src:perf_to_profile 30 | sudo cp bazel-bin/src/perf_to_profile /usr/local/bin/ 31 | ``` 32 | 33 | Finally, in your libsass repository, clone and build `sassc`: 34 | 35 | ```bash 36 | git clone https://github.com/sass/sassc.git 37 | make sassc 38 | ``` 39 | 40 | ### Record perf data 41 | 42 | ```bash 43 | sudo perf record sassc/bin/sassc input.scss > /dev/null && sudo chown $USER:$USER perf.data 44 | ``` 45 | 46 | This will create a `perf.data` file that you can vizualize with `pprof`. 47 | 48 | ### Inspect perf data 49 | 50 | A web server with various visualization options: 51 | 52 | ```bash 53 | pprof -http=localhost:3232 sassc/bin/sassc perf.data 54 | ``` 55 | 56 | Simple text output: 57 | 58 | ```bash 59 | pprof -text sassc/bin/sassc perf.data 60 | ``` 61 | 62 | Example output: 63 | 64 | ``` 65 | flat flat% sum% cum cum% 66 | 24651348 6.97% 6.97% 24651348 6.97% [[kernel.kallsyms]] 67 | 20746241 5.87% 12.84% 20746241 5.87% Sass::SharedPtr::decRefCount 68 | 18401663 5.20% 18.04% 20420896 5.78% __libc_malloc 69 | 15205959 4.30% 22.34% 15205959 4.30% [libc-2.27.so] 70 | 12974307 3.67% 26.01% 14070189 3.98% _int_malloc 71 | 10958857 3.10% 29.11% 10958857 3.10% Sass::SharedPtr::incRefCount 72 | 9837672 2.78% 31.89% 18433250 5.21% cfree 73 | ``` 74 | -------------------------------------------------------------------------------- /src/libsass/docs/implementations.md: -------------------------------------------------------------------------------- 1 | There are several implementations of `libsass` for a variety of languages. Here are just a few of them. Note, some implementations may or may not be up to date. We have not verified whether they work. 2 | 3 | ### C 4 | * [sassc](https://github.com/hcatlin/sassc) 5 | 6 | ### Crystal 7 | * [sass.cr](https://github.com/straight-shoota/sass.cr) 8 | 9 | ### Elixir 10 | * [sass.ex](https://github.com/scottdavis/sass.ex) 11 | * [sass_compiler](https://github.com/Youimmi/sass_compiler) 12 | 13 | ### Go 14 | * [go-libsass](https://github.com/wellington/go-libsass) 15 | * [go_sass](https://github.com/suapapa/go_sass) 16 | * [go-sass](https://github.com/SamWhited/go-sass) 17 | 18 | ### Haskell 19 | * [hLibsass](https://github.com/jakubfijalkowski/hlibsass) 20 | * [hSass](https://github.com/jakubfijalkowski/hsass) 21 | 22 | ### Java 23 | * [libsass-maven-plugin](https://github.com/warmuuh/libsass-maven-plugin) 24 | * [jsass](https://github.com/bit3/jsass) 25 | 26 | ### JavaScript 27 | * [sass.js](https://github.com/medialize/sass.js) 28 | 29 | ### Lua 30 | * [lua-sass](https://github.com/craigbarnes/lua-sass) 31 | 32 | ### .NET 33 | * [libsass-net](https://github.com/darrenkopp/libsass-net) 34 | * [NSass](https://github.com/TBAPI-0KA/NSass) 35 | * [Sass.Net](https://github.com/andyalm/Sass.Net) 36 | * [SharpScss](https://github.com/xoofx/SharpScss) 37 | * [LibSassHost](https://github.com/Taritsyn/LibSassHost) 38 | 39 | ### Nim 40 | 41 | * [sass](https://github.com/dom96/sass) 42 | * [nim-sass](https://github.com/zacharycarter/nim-sass) 43 | 44 | ### node.js 45 | * [node-sass](https://github.com/sass/node-sass) 46 | 47 | ### Perl 48 | * [CSS::Sass](https://github.com/caldwell/CSS-Sass) 49 | * [Text::Sass::XS](https://github.com/ysasaki/Text-Sass-XS) 50 | 51 | ### PHP 52 | * [sassphp](https://github.com/sensational/sassphp) 53 | * [php-sass](https://github.com/lesstif/php-sass) 54 | 55 | ### Python 56 | * [libsass-python](https://github.com/dahlia/libsass-python) 57 | * [SassPython](https://github.com/marianoguerra/SassPython) 58 | * [pylibsass](https://github.com/rsenk330/pylibsass) 59 | * [python-scss](https://github.com/pistolero/python-scss) 60 | 61 | ### Ruby 62 | * [sassruby](https://github.com/hcatlin/sassruby) 63 | 64 | ### Scala 65 | * [Sass-Scala](https://github.com/kkung/Sass-Scala) 66 | 67 | ### Tcl 68 | * [tclsass](https://github.com/flightaware/tclsass) 69 | -------------------------------------------------------------------------------- /src/libsass/docs/plugins.md: -------------------------------------------------------------------------------- 1 | Plugins are shared object files (.so on *nix and .dll on win) that can be loaded by LibSass on runtime. Currently we only provide a way to load internal/custom functions from plugins. In the future we probably will also add a way to provide custom importers via plugins (needs more refactoring to [support multiple importers with some kind of priority system](https://github.com/sass/libsass/issues/962)). 2 | 3 | ## plugin.cpp 4 | 5 | ```C++ 6 | #include 7 | #include 8 | #include 9 | #include "sass_values.h" 10 | 11 | union Sass_Value* ADDCALL call_fn_foo(const union Sass_Value* s_args, void* cookie) 12 | { 13 | // we actually abuse the void* to store an "int" 14 | return sass_make_number((intptr_t)cookie, "px"); 15 | } 16 | 17 | extern "C" const char* ADDCALL libsass_get_version() { 18 | return libsass_version(); 19 | } 20 | 21 | extern "C" Sass_C_Function_List ADDCALL libsass_load_functions() 22 | { 23 | // allocate a custom function caller 24 | Sass_C_Function_Callback fn_foo = 25 | sass_make_function("foo()", call_fn_foo, (void*)42); 26 | // create list of all custom functions 27 | Sass_C_Function_List fn_list = sass_make_function_list(1); 28 | // put the only function in this plugin to the list 29 | sass_function_set_list_entry(fn_list, 0, fn_foo); 30 | // return the list 31 | return fn_list; 32 | } 33 | ``` 34 | 35 | To compile the plugin you need to have LibSass already built as a shared library (to link against it). The commands below expect the shared library in the `lib` sub-directory (`-Llib`). The plugin and the main LibSass process should "consume" the same shared LibSass library on runtime. It will propably also work if they use different LibSass versions. In this case we check if the major versions are compatible (i.e. 3.1.3 and 3.1.1 would be considered compatible). 36 | 37 | ## Compile with gcc on linux 38 | 39 | ```bash 40 | g++ -O2 -shared plugin.cpp -o plugin.so -fPIC -Llib -lsass 41 | ``` 42 | 43 | ## Compile with mingw on windows 44 | 45 | ```bash 46 | g++ -O2 -shared plugin.cpp -o plugin.dll -Llib -lsass 47 | ``` 48 | -------------------------------------------------------------------------------- /src/libsass/docs/source-map-internals.md: -------------------------------------------------------------------------------- 1 | This document is mainly intended for developers! 2 | 3 | # Documenting some of the source map internals 4 | 5 | Since source maps are somewhat a black box to all LibSass maintainers, [I](@mgreter) will try to document my findings with source maps in LibSass, as I come across them. This document will also brievely explain how LibSass parses the source and how it outputs the result. 6 | 7 | The main storage for SourceMap mappings is the `mappings` vector: 8 | 9 | ``` 10 | # in source_map.hpp 11 | vector mappings 12 | # in mappings.hpp 13 | struct Mapping ... 14 | Position original_position; 15 | Position generated_position; 16 | ``` 17 | 18 | ## Every parsed token has its source associated 19 | 20 | LibSass uses a lexical parser. Whenever LibSass finds a token of interest, it creates a specific `AST_Node`, which will hold a reference to the input source with line/column information. `AST_Node` is the base class for all parsed items. They are declared in `ast.hpp` and are used in `parser.hpp`. Here a simple example: 21 | 22 | ``` 23 | if (lex< custom_property_name >()) { 24 | Sass::String* prop = new (ctx.mem) String_Constant(path, source_position, lexed); 25 | return new (ctx.mem) Declaration(path, prop->position(), prop, ...); 26 | } 27 | ``` 28 | 29 | ## How is the `source_position` calculated 30 | 31 | This is automatically done with `lex` in `parser.hpp`. Whenever something is lexed, the `source_position` is updated. But be aware that `source_position` points to the beginning of the parsed text. If you need a mapping for the position where the parsing ended, you need to add another call to `lex` (to match nothing)! 32 | 33 | ``` 34 | lex< exactly < empty_str > >(); 35 | end = new (ctx.mem) String_Constant(path, source_position, lexed); 36 | ``` 37 | 38 | ## How are mappings for the output created 39 | 40 | So far we have collected all needed data for all tokens in the input stream. We can now use this information to create mappings when we put things into the output stream. Mappings are created via the `add_mappings` method: 41 | 42 | ``` 43 | # in source_map.hpp 44 | void add_mapping(AST_Node* node); 45 | ``` 46 | 47 | This method is called in two places: 48 | - `Inspect::append_to_buffer` 49 | - `Output_[Nested|Compressed]::append_to_buffer` 50 | 51 | Mappings can only be created for things that have been parsed into a `AST_Node`. Otherwise we do not have the information to create the mappings, which is the reason why LibSass currently only maps the most important tokens in source maps. 52 | -------------------------------------------------------------------------------- /src/libsass/docs/trace.md: -------------------------------------------------------------------------------- 1 | ## This is proposed interface in https://github.com/sass/libsass/pull/1288 2 | 3 | Additional debugging macros with low overhead are available, `TRACE()` and `TRACEINST()`. 4 | 5 | Both macros simulate a string stream, so they can be used like this: 6 | 7 | TRACE() << "Reached."; 8 | 9 | produces: 10 | 11 | [LibSass] parse_value parser.cpp:1384 Reached. 12 | 13 | `TRACE()` 14 | logs function name, source filename, source file name to the standard error and the attached 15 | stream to the standard error. 16 | 17 | `TRACEINST(obj)` 18 | logs object instance address, function name, source filename, source file name to the standard error and the attached stream to the standard error, for example: 19 | 20 | TRACEINST(this) << "String_Constant created " << this; 21 | 22 | produces: 23 | 24 | [LibSass] 0x8031ba980:String_Constant ./ast.hpp:1371 String_Constant created (0,"auto") 25 | 26 | The macros generate output only of `LibSass_TRACE` is set in the environment. 27 | -------------------------------------------------------------------------------- /src/libsass/docs/triage.md: -------------------------------------------------------------------------------- 1 | This is an article about how to help with LibSass issues. Issue triage is a fancy word for explaining how we deal with incoming issues and make sure that the right problems get worked on. The lifecycle of an issue goes like this: 2 | 3 | 1. Issue is reported by a user. 4 | 2. If the issue seems like a bug, then the "bug" tag is added. 5 | 3. If the reporting user didn't also create a spec test over at sass/sass-spec, the "needs test" tag is added. 6 | 4. Verify that Ruby Sass *does not* have the same bug. LibSass strives to be an exact replica of how Ruby Sass works. If it's an issue that neither project has solved, please close the ticket with the "not in sass" label. 7 | 5. The smallest possible breaking test is created in sass-spec. Cut away any extra information or non-breaking code until the core issue is made clear. 8 | 6. Again, verify that the expected output matches the latest Ruby Sass release. Do this by using your own tool OR by running ./sass-spec.rb in the spec folder and making sure that your test passes! 9 | 7. Create the test cases in sass-spec with the name spec/LibSass-todo-issues/issue_XXX/input.scss and expected_output.css where the XXX is the issue number here. 10 | 8. Commit that test to sass-spec, making sure to reference the issue in the comment message like "Test to demonstrate sass/LibSass#XXX". 11 | 9. Once the spec test exists, remove the "needs test" tag and replace it with "test written". 12 | 10. A C++ developer will then work on the issue and issue a pull request to fix the issue. 13 | 11. A core member verifies that the fix does actually fix the spec tests. 14 | 12. The fix is merged into the project. 15 | 13. The spec is moved from the LibSass-todo-issues folder into LibSass-closed-issues 16 | 14. The issue is closed 17 | 15. Have a soda pop or enjoyable beverage of your choice 18 | -------------------------------------------------------------------------------- /src/libsass/include/sass.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_H 2 | #define SASS_H 3 | 4 | // #define DEBUG 1 5 | 6 | // include API headers 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /src/libsass/include/sass/version.h: -------------------------------------------------------------------------------- 1 | #ifndef SASS_VERSION_H 2 | #define SASS_VERSION_H 3 | 4 | #ifndef LIBSASS_VERSION 5 | #define LIBSASS_VERSION "[NA]" 6 | #endif 7 | 8 | #ifndef LIBSASS_LANGUAGE_VERSION 9 | #define LIBSASS_LANGUAGE_VERSION "3.5" 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/libsass/include/sass/version.h.in: -------------------------------------------------------------------------------- 1 | #ifndef SASS_VERSION_H 2 | #define SASS_VERSION_H 3 | 4 | #ifndef LIBSASS_VERSION 5 | #define LIBSASS_VERSION "@PACKAGE_VERSION@" 6 | #endif 7 | 8 | #ifndef LIBSASS_LANGUAGE_VERSION 9 | #define LIBSASS_LANGUAGE_VERSION "3.5" 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/libsass/m4/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/src/libsass/m4/.gitkeep -------------------------------------------------------------------------------- /src/libsass/res/resource.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // DLL version information. 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION 1,0,0,0 6 | PRODUCTVERSION 1,0,0,0 7 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 8 | #ifdef _DEBUG 9 | FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE 10 | #else 11 | FILEFLAGS 0 12 | #endif 13 | FILEOS VOS_NT_WINDOWS32 14 | FILETYPE VFT_DLL 15 | FILESUBTYPE VFT2_UNKNOWN 16 | BEGIN 17 | BLOCK "StringFileInfo" 18 | BEGIN 19 | BLOCK "080904b0" 20 | BEGIN 21 | VALUE "CompanyName", "Sass Open Source Foundation" 22 | VALUE "FileDescription", "A C/C++ implementation of a Sass compiler" 23 | VALUE "FileVersion", "1.0.0.0" 24 | VALUE "InternalName", "libsass" 25 | VALUE "LegalCopyright", "\251 2017 libsass.org" 26 | VALUE "OriginalFilename", "libsass.dll" 27 | VALUE "ProductName", "LibSass Library" 28 | VALUE "ProductVersion", "1.0.0.0" 29 | END 30 | END 31 | BLOCK "VarFileInfo" 32 | BEGIN 33 | VALUE "Translation", 0x809, 1200 34 | END 35 | END 36 | -------------------------------------------------------------------------------- /src/libsass/script/bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | script/branding 4 | 5 | : ${LIBSASS_SPEC_PATH:="libsass-spec"} 6 | : ${SASS_SPEC_PATH:="sass-spec"} 7 | : ${SASS_SASSC_PATH:="sassc" } 8 | 9 | if [ ! -d $LIBSASS_SPEC_PATH ]; then 10 | git clone https://github.com/mgreter/libsass-spec.git $LIBSASS_SPEC_PATH 11 | fi 12 | if [ ! -d $SASS_SPEC_PATH ]; then 13 | git clone https://github.com/sass/sass-spec.git $SASS_SPEC_PATH 14 | fi 15 | if [ ! -d $SASS_SASSC_PATH ]; then 16 | git clone https://github.com/sass/sassc.git $SASS_SASSC_PATH 17 | fi 18 | -------------------------------------------------------------------------------- /src/libsass/script/branding: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo " " 4 | echo " _ ___ ____ ____ _ ____ ____ " 5 | echo "| | |_ _| __ ) ___| / \ / ___/ ___| " 6 | echo "| | | || _ \___ \ / _ \ \___ \___ \ " 7 | echo "| |___ | || |_) |__) / ___ \ ___) |__) |" 8 | echo "|_____|___|____/____/_/ \_\____/____/ " 9 | echo " " 10 | 11 | -------------------------------------------------------------------------------- /src/libsass/script/ci-build-plugin: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PLUGIN=$1 4 | RUBY_BIN=ruby 5 | SASS_SPEC_PATH=sass-spec 6 | SASSC_BIN=sassc/bin/sassc 7 | SASS_SPEC_SPEC_DIR=plugins/libsass-${PLUGIN}/test 8 | 9 | if [ -e ./tester ] ; then 10 | SASSC_BIN=./tester 11 | fi 12 | 13 | if [ -d ./build/lib ] ; then 14 | cp -a build/lib lib 15 | fi 16 | 17 | if [ "x$1" == "x" ] ; then 18 | echo "No plugin name given" 19 | exit 1 20 | fi 21 | 22 | if [ "x$COVERAGE" == "0" ] ; then 23 | unset COVERAGE 24 | fi 25 | 26 | export EXTRA_CFLAGS="" 27 | export EXTRA_CXXFLAGS="" 28 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then 29 | # osx doesn't seem to know gcov lib? 30 | export EXTRA_LDFLAGS="--coverage" 31 | else 32 | export EXTRA_LDFLAGS="-lgcov --coverage" 33 | fi 34 | 35 | mkdir -p plugins 36 | if [ ! -d plugins/libsass-${PLUGIN} ] ; then 37 | if [ "$PLUGIN" == "tests" ]; then 38 | git clone https://github.com/mgreter/libsass-${PLUGIN} plugins/libsass-${PLUGIN} --branch master 39 | else 40 | git clone https://github.com/mgreter/libsass-${PLUGIN} plugins/libsass-${PLUGIN} 41 | fi 42 | fi 43 | if [ ! -d plugins/libsass-${PLUGIN}/build ] ; then 44 | mkdir plugins/libsass-${PLUGIN}/build 45 | fi 46 | RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi 47 | 48 | cd plugins/libsass-${PLUGIN}/build 49 | cmake -G "Unix Makefiles" -D LIBSASS_DIR="../../.." .. 50 | RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi 51 | make VERBOSE=1 -j2 52 | RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi 53 | cd ../../.. 54 | 55 | # glob only works on paths relative to imports 56 | if [ "x$PLUGIN" == "xglob" ]; then 57 | ${SASSC_BIN} --precision 5 --plugin-path plugins/libsass-${PLUGIN}/build ${SASS_SPEC_SPEC_DIR}/basic/input.scss > ${SASS_SPEC_SPEC_DIR}/basic/result.css 58 | ${SASSC_BIN} --precision 5 --plugin-path plugins/libsass-${PLUGIN}/build ${SASS_SPEC_SPEC_DIR}/basic/input.scss --sourcemap > /dev/null 59 | else 60 | cat ${SASS_SPEC_SPEC_DIR}/basic/input.scss | ${SASSC_BIN} --precision 5 --plugin-path plugins/libsass-${PLUGIN}/build -I ${SASS_SPEC_SPEC_DIR}/basic > ${SASS_SPEC_SPEC_DIR}/basic/result.css 61 | cat ${SASS_SPEC_SPEC_DIR}/basic/input.scss | ${SASSC_BIN} --precision 5 --plugin-path plugins/libsass-${PLUGIN}/build -I ${SASS_SPEC_SPEC_DIR}/basic --sourcemap > /dev/null 62 | fi 63 | RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi 64 | 65 | diff ${SASS_SPEC_SPEC_DIR}/basic/expected_output.css ${SASS_SPEC_SPEC_DIR}/basic/result.css 66 | RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi 67 | -------------------------------------------------------------------------------- /src/libsass/script/ci-install-compiler: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo gem install minitest 4 | sudo gem install minitap 5 | sudo gem install rspec 6 | sudo gem install hrx 7 | 8 | # sudo pip2 install --user 'requests[security]' 9 | -------------------------------------------------------------------------------- /src/libsass/script/ci-install-deps: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ "x$COVERAGE" == "xyes" ]; then 3 | pip2 install --user gcovr 4 | pip2 install --user cpp-coveralls 5 | else 6 | echo "no dependencies to install" 7 | fi 8 | 9 | if [ "x$AUTOTOOLS" == "xyes" ]; then 10 | AUTOTOOLS=yes 11 | 12 | if [ "$TRAVIS_OS_NAME" == "linux" ]; then 13 | sudo add-apt-repository -y ppa:rbose-debianizer/automake &> /dev/null 14 | sudo apt-get -qq update 15 | sudo apt-get -qq install automake 16 | fi 17 | 18 | fi 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /src/libsass/script/ci-report-coverage: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "x$COVERAGE" = "xyes" ]; then 4 | 5 | # find / -name "gcovr" 6 | # find / -name "coveralls" 7 | # this is only needed for mac os x builds! 8 | PATH=$PATH:/Users/travis/Library/Python/2.7/bin/ 9 | 10 | 11 | # exclude some directories from profiling (.libs is from autotools) 12 | export EXCLUDE_COVERAGE="--exclude plugins 13 | --exclude sassc/sassc.c 14 | --exclude src/sass-spec 15 | --exclude src/.libs 16 | --exclude src/debug.hpp 17 | --exclude src/json.cpp 18 | --exclude src/json.hpp 19 | --exclude src/cencode.c 20 | --exclude src/b64 21 | --exclude src/utf8 22 | --exclude src/utf8_string.hpp 23 | --exclude src/utf8.h 24 | --exclude src/utf8_string.cpp 25 | --exclude src/sass2scss.h 26 | --exclude src/sass2scss.cpp 27 | --exclude src/test 28 | --exclude src/posix 29 | --exclude src/debugger.hpp" 30 | # debug used gcov version 31 | # option not available on mac 32 | if [ "$TRAVIS_OS_NAME" != "osx" ]; then 33 | gcov -v 34 | fi 35 | # create summarized report 36 | gcovr -r . 37 | # submit report to coveralls.io 38 | coveralls $EXCLUDE_COVERAGE --gcov-options '\-lp' 39 | 40 | else 41 | echo "skip coverage reporting" 42 | fi 43 | -------------------------------------------------------------------------------- /src/libsass/script/spec: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | script/bootstrap 4 | 5 | make $MAKE_OPTS test_build 6 | -------------------------------------------------------------------------------- /src/libsass/script/tap-runner: -------------------------------------------------------------------------------- 1 | $@ $TEST_FLAGS --tap --silent | tapout tap 2 | -------------------------------------------------------------------------------- /src/libsass/src/GNUmakefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 -I script 2 | 3 | AM_COPT = -Wall -O2 4 | AM_COVLDFLAGS = 5 | 6 | if ENABLE_COVERAGE 7 | AM_COPT = -O0 --coverage 8 | AM_COVLDFLAGS += -lgcov 9 | endif 10 | 11 | AM_CPPFLAGS = -I$(top_srcdir)/include 12 | AM_CFLAGS = $(AM_COPT) 13 | AM_CXXFLAGS = $(AM_COPT) 14 | AM_LDFLAGS = $(AM_COPT) $(AM_COVLDFLAGS) 15 | 16 | AM_CXXFLAGS += -std=c++11 17 | 18 | EXTRA_DIST = \ 19 | COPYING \ 20 | INSTALL \ 21 | LICENSE \ 22 | Readme.md 23 | 24 | pkgconfigdir = $(libdir)/pkgconfig 25 | pkgconfig_DATA = support/libsass.pc 26 | 27 | lib_LTLIBRARIES = libsass.la 28 | 29 | include $(top_srcdir)/Makefile.conf 30 | 31 | libsass_la_SOURCES = ${CSOURCES} ${SOURCES} 32 | 33 | libsass_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-info 1:0:0 34 | 35 | if ENABLE_TESTS 36 | if ENABLE_COVERAGE 37 | nodist_EXTRA_libsass_la_SOURCES = non-existent-file-to-force-CXX-linking.cxx 38 | endif 39 | endif 40 | 41 | include_HEADERS = $(top_srcdir)/include/sass.h \ 42 | $(top_srcdir)/include/sass2scss.h 43 | 44 | sass_includedir = $(includedir)/sass 45 | 46 | sass_include_HEADERS = $(top_srcdir)/include/sass/base.h \ 47 | $(top_srcdir)/include/sass/values.h \ 48 | $(top_srcdir)/include/sass/version.h \ 49 | $(top_srcdir)/include/sass/context.h \ 50 | $(top_srcdir)/include/sass/functions.h 51 | -------------------------------------------------------------------------------- /src/libsass/src/MurmurHash2.hpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // MurmurHash2 was written by Austin Appleby, and is placed in the public 3 | // domain. The author hereby disclaims copyright to this source code. 4 | //----------------------------------------------------------------------------- 5 | // LibSass only needs MurmurHash2, so we made this header only 6 | //----------------------------------------------------------------------------- 7 | 8 | #ifndef _MURMURHASH2_H_ 9 | #define _MURMURHASH2_H_ 10 | 11 | //----------------------------------------------------------------------------- 12 | // Platform-specific functions and macros 13 | 14 | // Microsoft Visual Studio 15 | 16 | #if defined(_MSC_VER) && (_MSC_VER < 1600) 17 | 18 | typedef unsigned char uint8_t; 19 | typedef unsigned int uint32_t; 20 | typedef unsigned __int64 uint64_t; 21 | 22 | // Other compilers 23 | 24 | #else // defined(_MSC_VER) 25 | 26 | #include 27 | 28 | #endif // !defined(_MSC_VER) 29 | 30 | //----------------------------------------------------------------------------- 31 | 32 | inline uint32_t MurmurHash2 ( const void * key, int len, uint32_t seed ) 33 | { 34 | // 'm' and 'r' are mixing constants generated offline. 35 | // They're not really 'magic', they just happen to work well. 36 | 37 | const uint32_t m = 0x5bd1e995; 38 | const int r = 24; 39 | 40 | // Initialize the hash to a 'random' value 41 | 42 | uint32_t h = seed ^ len; 43 | 44 | // Mix 4 bytes at a time into the hash 45 | 46 | const unsigned char * data = (const unsigned char *)key; 47 | 48 | while(len >= 4) 49 | { 50 | uint32_t k = *(uint32_t*)data; 51 | 52 | k *= m; 53 | k ^= k >> r; 54 | k *= m; 55 | 56 | h *= m; 57 | h ^= k; 58 | 59 | data += 4; 60 | len -= 4; 61 | } 62 | 63 | // Handle the last few bytes of the input array 64 | 65 | switch(len) 66 | { 67 | case 3: 68 | h ^= data[2] << 16; 69 | /* fall through */ 70 | case 2: 71 | h ^= data[1] << 8; 72 | /* fall through */ 73 | case 1: 74 | h ^= data[0]; 75 | h *= m; 76 | }; 77 | 78 | // Do a few final mixes of the hash to ensure the last few 79 | // bytes are well-incorporated. 80 | 81 | h ^= h >> 13; 82 | h *= m; 83 | h ^= h >> 15; 84 | 85 | return h; 86 | } 87 | 88 | //----------------------------------------------------------------------------- 89 | 90 | #endif // _MURMURHASH2_H_ 91 | 92 | -------------------------------------------------------------------------------- /src/libsass/src/ast2c.cpp: -------------------------------------------------------------------------------- 1 | // sass.hpp must go before all system headers to get the 2 | // __EXTENSIONS__ fix on Solaris. 3 | #include "sass.hpp" 4 | 5 | #include "ast2c.hpp" 6 | #include "ast.hpp" 7 | 8 | namespace Sass { 9 | 10 | union Sass_Value* AST2C::operator()(Boolean* b) 11 | { return sass_make_boolean(b->value()); } 12 | 13 | union Sass_Value* AST2C::operator()(Number* n) 14 | { return sass_make_number(n->value(), n->unit().c_str()); } 15 | 16 | union Sass_Value* AST2C::operator()(Custom_Warning* w) 17 | { return sass_make_warning(w->message().c_str()); } 18 | 19 | union Sass_Value* AST2C::operator()(Custom_Error* e) 20 | { return sass_make_error(e->message().c_str()); } 21 | 22 | union Sass_Value* AST2C::operator()(Color_RGBA* c) 23 | { return sass_make_color(c->r(), c->g(), c->b(), c->a()); } 24 | 25 | union Sass_Value* AST2C::operator()(Color_HSLA* c) 26 | { 27 | Color_RGBA_Obj rgba = c->copyAsRGBA(); 28 | return operator()(rgba.ptr()); 29 | } 30 | 31 | union Sass_Value* AST2C::operator()(String_Constant* s) 32 | { 33 | if (s->quote_mark()) { 34 | return sass_make_qstring(s->value().c_str()); 35 | } else { 36 | return sass_make_string(s->value().c_str()); 37 | } 38 | } 39 | 40 | union Sass_Value* AST2C::operator()(String_Quoted* s) 41 | { return sass_make_qstring(s->value().c_str()); } 42 | 43 | union Sass_Value* AST2C::operator()(List* l) 44 | { 45 | union Sass_Value* v = sass_make_list(l->length(), l->separator(), l->is_bracketed()); 46 | for (size_t i = 0, L = l->length(); i < L; ++i) { 47 | sass_list_set_value(v, i, (*l)[i]->perform(this)); 48 | } 49 | return v; 50 | } 51 | 52 | union Sass_Value* AST2C::operator()(Map* m) 53 | { 54 | union Sass_Value* v = sass_make_map(m->length()); 55 | int i = 0; 56 | for (auto key : m->keys()) { 57 | sass_map_set_key(v, i, key->perform(this)); 58 | sass_map_set_value(v, i, m->at(key)->perform(this)); 59 | i++; 60 | } 61 | return v; 62 | } 63 | 64 | union Sass_Value* AST2C::operator()(Arguments* a) 65 | { 66 | union Sass_Value* v = sass_make_list(a->length(), SASS_COMMA, false); 67 | for (size_t i = 0, L = a->length(); i < L; ++i) { 68 | sass_list_set_value(v, i, (*a)[i]->perform(this)); 69 | } 70 | return v; 71 | } 72 | 73 | union Sass_Value* AST2C::operator()(Argument* a) 74 | { return a->value()->perform(this); } 75 | 76 | // not strictly necessary because of the fallback 77 | union Sass_Value* AST2C::operator()(Null* n) 78 | { return sass_make_null(); } 79 | 80 | }; 81 | -------------------------------------------------------------------------------- /src/libsass/src/ast2c.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_AST2C_H 2 | #define SASS_AST2C_H 3 | 4 | #include "ast_fwd_decl.hpp" 5 | #include "operation.hpp" 6 | #include "sass/values.h" 7 | 8 | namespace Sass { 9 | 10 | class AST2C : public Operation_CRTP { 11 | 12 | public: 13 | 14 | AST2C() { } 15 | ~AST2C() { } 16 | 17 | union Sass_Value* operator()(Boolean*); 18 | union Sass_Value* operator()(Number*); 19 | union Sass_Value* operator()(Color_RGBA*); 20 | union Sass_Value* operator()(Color_HSLA*); 21 | union Sass_Value* operator()(String_Constant*); 22 | union Sass_Value* operator()(String_Quoted*); 23 | union Sass_Value* operator()(Custom_Warning*); 24 | union Sass_Value* operator()(Custom_Error*); 25 | union Sass_Value* operator()(List*); 26 | union Sass_Value* operator()(Map*); 27 | union Sass_Value* operator()(Null*); 28 | union Sass_Value* operator()(Arguments*); 29 | union Sass_Value* operator()(Argument*); 30 | 31 | // return sass error if type is not supported 32 | union Sass_Value* fallback(AST_Node* x) 33 | { return sass_make_error("unknown type for C-API"); } 34 | 35 | }; 36 | 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/libsass/src/ast_fwd_decl.cpp: -------------------------------------------------------------------------------- 1 | #include "ast.hpp" 2 | 3 | namespace Sass { 4 | 5 | #define IMPLEMENT_BASE_CAST(T) \ 6 | template<> \ 7 | T* Cast(AST_Node* ptr) { \ 8 | return dynamic_cast(ptr); \ 9 | }; \ 10 | \ 11 | template<> \ 12 | const T* Cast(const AST_Node* ptr) { \ 13 | return dynamic_cast(ptr); \ 14 | }; \ 15 | 16 | IMPLEMENT_BASE_CAST(AST_Node) 17 | IMPLEMENT_BASE_CAST(Expression) 18 | IMPLEMENT_BASE_CAST(Statement) 19 | IMPLEMENT_BASE_CAST(ParentStatement) 20 | IMPLEMENT_BASE_CAST(PreValue) 21 | IMPLEMENT_BASE_CAST(Value) 22 | IMPLEMENT_BASE_CAST(Color) 23 | IMPLEMENT_BASE_CAST(List) 24 | IMPLEMENT_BASE_CAST(String) 25 | IMPLEMENT_BASE_CAST(String_Constant) 26 | IMPLEMENT_BASE_CAST(SupportsCondition) 27 | IMPLEMENT_BASE_CAST(Selector) 28 | IMPLEMENT_BASE_CAST(SelectorComponent) 29 | IMPLEMENT_BASE_CAST(SimpleSelector) 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/libsass/src/b64/cencode.h: -------------------------------------------------------------------------------- 1 | /* 2 | cencode.h - c header for a base64 encoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CENCODE_H 9 | #define BASE64_CENCODE_H 10 | 11 | typedef enum 12 | { 13 | step_A, step_B, step_C 14 | } base64_encodestep; 15 | 16 | typedef struct 17 | { 18 | base64_encodestep step; 19 | char result; 20 | int stepcount; 21 | } base64_encodestate; 22 | 23 | void base64_init_encodestate(base64_encodestate* state_in); 24 | 25 | char base64_encode_value(char value_in); 26 | 27 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); 28 | 29 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in); 30 | 31 | #endif /* BASE64_CENCODE_H */ 32 | 33 | -------------------------------------------------------------------------------- /src/libsass/src/b64/encode.h: -------------------------------------------------------------------------------- 1 | // :mode=c++: 2 | /* 3 | encode.h - c++ wrapper for a base64 encoding algorithm 4 | 5 | This is part of the libb64 project, and has been placed in the public domain. 6 | For details, see http://sourceforge.net/projects/libb64 7 | */ 8 | #ifndef BASE64_ENCODE_H 9 | #define BASE64_ENCODE_H 10 | 11 | #include 12 | 13 | namespace base64 14 | { 15 | extern "C" 16 | { 17 | #include "cencode.h" 18 | } 19 | 20 | struct encoder 21 | { 22 | base64_encodestate _state; 23 | int _buffersize; 24 | 25 | encoder(int buffersize_in = BUFFERSIZE) 26 | : _buffersize(buffersize_in) 27 | { 28 | base64_init_encodestate(&_state); 29 | } 30 | 31 | int encode(char value_in) 32 | { 33 | return base64_encode_value(value_in); 34 | } 35 | 36 | int encode(const char* code_in, const int length_in, char* plaintext_out) 37 | { 38 | return base64_encode_block(code_in, length_in, plaintext_out, &_state); 39 | } 40 | 41 | int encode_end(char* plaintext_out) 42 | { 43 | return base64_encode_blockend(plaintext_out, &_state); 44 | } 45 | 46 | void encode(std::istream& istream_in, std::ostream& ostream_in) 47 | { 48 | base64_init_encodestate(&_state); 49 | // 50 | const int N = _buffersize; 51 | char* plaintext = new char[N]; 52 | char* code = new char[2*N]; 53 | int plainlength; 54 | int codelength; 55 | 56 | do 57 | { 58 | istream_in.read(plaintext, N); 59 | plainlength = static_cast(istream_in.gcount()); 60 | // 61 | codelength = encode(plaintext, plainlength, code); 62 | ostream_in.write(code, codelength); 63 | } 64 | while (istream_in.good() && plainlength > 0); 65 | 66 | codelength = encode_end(code); 67 | ostream_in.write(code, codelength); 68 | // 69 | base64_init_encodestate(&_state); 70 | 71 | delete [] code; 72 | delete [] plaintext; 73 | } 74 | }; 75 | 76 | } // namespace base64 77 | 78 | #endif // BASE64_ENCODE_H 79 | 80 | -------------------------------------------------------------------------------- /src/libsass/src/backtrace.cpp: -------------------------------------------------------------------------------- 1 | #include "backtrace.hpp" 2 | 3 | namespace Sass { 4 | 5 | const sass::string traces_to_string(Backtraces traces, sass::string indent) { 6 | 7 | sass::ostream ss; 8 | sass::string cwd(File::get_cwd()); 9 | 10 | bool first = true; 11 | size_t i_beg = traces.size() - 1; 12 | size_t i_end = sass::string::npos; 13 | for (size_t i = i_beg; i != i_end; i --) { 14 | 15 | const Backtrace& trace = traces[i]; 16 | 17 | // make path relative to the current directory 18 | sass::string rel_path(File::abs2rel(trace.pstate.getPath(), cwd, cwd)); 19 | 20 | // skip functions on error cases (unsure why ruby sass does this) 21 | // if (trace.caller.substr(0, 6) == ", in f") continue; 22 | 23 | if (first) { 24 | ss << indent; 25 | ss << "on line "; 26 | ss << trace.pstate.getLine(); 27 | ss << ":"; 28 | ss << trace.pstate.getColumn(); 29 | ss << " of " << rel_path; 30 | // ss << trace.caller; 31 | first = false; 32 | } else { 33 | ss << trace.caller; 34 | ss << std::endl; 35 | ss << indent; 36 | ss << "from line "; 37 | ss << trace.pstate.getLine(); 38 | ss << ":"; 39 | ss << trace.pstate.getColumn(); 40 | ss << " of " << rel_path; 41 | } 42 | 43 | } 44 | 45 | ss << std::endl; 46 | return ss.str(); 47 | 48 | } 49 | 50 | }; 51 | -------------------------------------------------------------------------------- /src/libsass/src/backtrace.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_BACKTRACE_H 2 | #define SASS_BACKTRACE_H 3 | 4 | #include 5 | #include 6 | #include "file.hpp" 7 | #include "position.hpp" 8 | 9 | namespace Sass { 10 | 11 | struct Backtrace { 12 | 13 | SourceSpan pstate; 14 | sass::string caller; 15 | 16 | Backtrace(SourceSpan pstate, sass::string c = "") 17 | : pstate(pstate), 18 | caller(c) 19 | { } 20 | 21 | }; 22 | 23 | typedef sass::vector Backtraces; 24 | 25 | const sass::string traces_to_string(Backtraces traces, sass::string indent = "\t"); 26 | 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/libsass/src/base64vlq.cpp: -------------------------------------------------------------------------------- 1 | // sass.hpp must go before all system headers to get the 2 | // __EXTENSIONS__ fix on Solaris. 3 | #include "sass.hpp" 4 | 5 | #include "base64vlq.hpp" 6 | 7 | namespace Sass { 8 | 9 | sass::string Base64VLQ::encode(const int number) const 10 | { 11 | sass::string encoded = ""; 12 | 13 | int vlq = to_vlq_signed(number); 14 | 15 | do { 16 | int digit = vlq & VLQ_BASE_MASK; 17 | vlq >>= VLQ_BASE_SHIFT; 18 | if (vlq > 0) { 19 | digit |= VLQ_CONTINUATION_BIT; 20 | } 21 | encoded += base64_encode(digit); 22 | } while (vlq > 0); 23 | 24 | return encoded; 25 | } 26 | 27 | char Base64VLQ::base64_encode(const int number) const 28 | { 29 | int index = number; 30 | if (index < 0) index = 0; 31 | if (index > 63) index = 63; 32 | return CHARACTERS[index]; 33 | } 34 | 35 | int Base64VLQ::to_vlq_signed(const int number) const 36 | { 37 | return (number < 0) ? ((-number) << 1) + 1 : (number << 1) + 0; 38 | } 39 | 40 | const char* Base64VLQ::CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 41 | 42 | const int Base64VLQ::VLQ_BASE_SHIFT = 5; 43 | const int Base64VLQ::VLQ_BASE = 1 << VLQ_BASE_SHIFT; 44 | const int Base64VLQ::VLQ_BASE_MASK = VLQ_BASE - 1; 45 | const int Base64VLQ::VLQ_CONTINUATION_BIT = VLQ_BASE; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/libsass/src/base64vlq.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_BASE64VLQ_H 2 | #define SASS_BASE64VLQ_H 3 | 4 | #include 5 | 6 | namespace Sass { 7 | 8 | class Base64VLQ { 9 | 10 | public: 11 | 12 | sass::string encode(const int number) const; 13 | 14 | private: 15 | 16 | char base64_encode(const int number) const; 17 | 18 | int to_vlq_signed(const int number) const; 19 | 20 | static const char* CHARACTERS; 21 | 22 | static const int VLQ_BASE_SHIFT; 23 | static const int VLQ_BASE; 24 | static const int VLQ_BASE_MASK; 25 | static const int VLQ_CONTINUATION_BIT; 26 | }; 27 | 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/libsass/src/bind.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_BIND_H 2 | #define SASS_BIND_H 3 | 4 | #include 5 | #include "backtrace.hpp" 6 | #include "environment.hpp" 7 | #include "ast_fwd_decl.hpp" 8 | 9 | namespace Sass { 10 | 11 | void bind(sass::string type, sass::string name, Parameters_Obj, Arguments_Obj, Env*, Eval*, Backtraces& traces); 12 | 13 | } 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/libsass/src/c2ast.cpp: -------------------------------------------------------------------------------- 1 | #include "ast.hpp" 2 | #include "units.hpp" 3 | #include "position.hpp" 4 | #include "backtrace.hpp" 5 | #include "sass/values.h" 6 | #include "ast_fwd_decl.hpp" 7 | #include "error_handling.hpp" 8 | 9 | namespace Sass { 10 | 11 | Value* c2ast(union Sass_Value* v, Backtraces traces, SourceSpan pstate) 12 | { 13 | using std::strlen; 14 | using std::strcpy; 15 | Value* e = NULL; 16 | switch (sass_value_get_tag(v)) { 17 | case SASS_BOOLEAN: { 18 | e = SASS_MEMORY_NEW(Boolean, pstate, !!sass_boolean_get_value(v)); 19 | } break; 20 | case SASS_NUMBER: { 21 | e = SASS_MEMORY_NEW(Number, pstate, sass_number_get_value(v), sass_number_get_unit(v)); 22 | } break; 23 | case SASS_COLOR: { 24 | e = SASS_MEMORY_NEW(Color_RGBA, pstate, sass_color_get_r(v), sass_color_get_g(v), sass_color_get_b(v), sass_color_get_a(v)); 25 | } break; 26 | case SASS_STRING: { 27 | if (sass_string_is_quoted(v)) 28 | e = SASS_MEMORY_NEW(String_Quoted, pstate, sass_string_get_value(v)); 29 | else { 30 | e = SASS_MEMORY_NEW(String_Constant, pstate, sass_string_get_value(v)); 31 | } 32 | } break; 33 | case SASS_LIST: { 34 | List* l = SASS_MEMORY_NEW(List, pstate, sass_list_get_length(v), sass_list_get_separator(v)); 35 | for (size_t i = 0, L = sass_list_get_length(v); i < L; ++i) { 36 | l->append(c2ast(sass_list_get_value(v, i), traces, pstate)); 37 | } 38 | l->is_bracketed(sass_list_get_is_bracketed(v)); 39 | e = l; 40 | } break; 41 | case SASS_MAP: { 42 | Map* m = SASS_MEMORY_NEW(Map, pstate); 43 | for (size_t i = 0, L = sass_map_get_length(v); i < L; ++i) { 44 | *m << std::make_pair( 45 | c2ast(sass_map_get_key(v, i), traces, pstate), 46 | c2ast(sass_map_get_value(v, i), traces, pstate)); 47 | } 48 | e = m; 49 | } break; 50 | case SASS_NULL: { 51 | e = SASS_MEMORY_NEW(Null, pstate); 52 | } break; 53 | case SASS_ERROR: { 54 | error("Error in C function: " + sass::string(sass_error_get_message(v)), pstate, traces); 55 | } break; 56 | case SASS_WARNING: { 57 | error("Warning in C function: " + sass::string(sass_warning_get_message(v)), pstate, traces); 58 | } break; 59 | default: break; 60 | } 61 | return e; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/libsass/src/c2ast.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_C2AST_H 2 | #define SASS_C2AST_H 3 | 4 | #include "position.hpp" 5 | #include "backtrace.hpp" 6 | #include "ast_fwd_decl.hpp" 7 | 8 | namespace Sass { 9 | 10 | Value* c2ast(union Sass_Value* v, Backtraces traces, SourceSpan pstate); 11 | 12 | } 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/libsass/src/c99func.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com) 3 | All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | 24 | #if defined(_MSC_VER) && _MSC_VER < 1900 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | static int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) 31 | { 32 | int count = -1; 33 | 34 | if (size != 0) 35 | count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); 36 | if (count == -1) 37 | count = _vscprintf(format, ap); 38 | 39 | return count; 40 | } 41 | 42 | int snprintf(char* str, size_t size, const char* format, ...) 43 | { 44 | int count; 45 | va_list ap; 46 | 47 | va_start(ap, format); 48 | count = c99_vsnprintf(str, size, format, ap); 49 | va_end(ap); 50 | 51 | return count; 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/libsass/src/check_nesting.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_CHECK_NESTING_H 2 | #define SASS_CHECK_NESTING_H 3 | 4 | // sass.hpp must go before all system headers to get the 5 | // __EXTENSIONS__ fix on Solaris. 6 | #include "sass.hpp" 7 | #include "ast.hpp" 8 | #include "operation.hpp" 9 | #include 10 | 11 | namespace Sass { 12 | 13 | class CheckNesting : public Operation_CRTP { 14 | 15 | sass::vector parents; 16 | Backtraces traces; 17 | Statement* parent; 18 | Definition* current_mixin_definition; 19 | 20 | Statement* before(Statement*); 21 | Statement* visit_children(Statement*); 22 | 23 | public: 24 | CheckNesting(); 25 | ~CheckNesting() { } 26 | 27 | Statement* operator()(Block*); 28 | Statement* operator()(Definition*); 29 | Statement* operator()(If*); 30 | 31 | template 32 | Statement* fallback(U x) { 33 | Statement* s = Cast(x); 34 | if (s && this->should_visit(s)) { 35 | Block* b1 = Cast(s); 36 | ParentStatement* b2 = Cast(s); 37 | if (b1 || b2) return visit_children(s); 38 | } 39 | return s; 40 | } 41 | 42 | private: 43 | void invalid_content_parent(Statement*, AST_Node*); 44 | void invalid_charset_parent(Statement*, AST_Node*); 45 | void invalid_extend_parent(Statement*, AST_Node*); 46 | // void invalid_import_parent(Statement*); 47 | void invalid_mixin_definition_parent(Statement*, AST_Node*); 48 | void invalid_function_parent(Statement*, AST_Node*); 49 | 50 | void invalid_function_child(Statement*); 51 | void invalid_prop_child(Statement*); 52 | void invalid_prop_parent(Statement*, AST_Node*); 53 | void invalid_return_parent(Statement*, AST_Node*); 54 | void invalid_value_child(AST_Node*); 55 | 56 | bool is_transparent_parent(Statement*, Statement*); 57 | 58 | bool should_visit(Statement*); 59 | 60 | bool is_charset(Statement*); 61 | bool is_mixin(Statement*); 62 | bool is_function(Statement*); 63 | bool is_root_node(Statement*); 64 | bool is_at_root_node(Statement*); 65 | bool is_directive_node(Statement*); 66 | }; 67 | 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/libsass/src/cssize.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_CSSIZE_H 2 | #define SASS_CSSIZE_H 3 | 4 | #include "ast.hpp" 5 | #include "context.hpp" 6 | #include "operation.hpp" 7 | #include "environment.hpp" 8 | 9 | namespace Sass { 10 | 11 | struct Backtrace; 12 | 13 | class Cssize : public Operation_CRTP { 14 | 15 | Backtraces& traces; 16 | BlockStack block_stack; 17 | sass::vector p_stack; 18 | 19 | public: 20 | Cssize(Context&); 21 | ~Cssize() { } 22 | 23 | Block* operator()(Block*); 24 | Statement* operator()(StyleRule*); 25 | // Statement* operator()(Bubble*); 26 | Statement* operator()(CssMediaRule*); 27 | Statement* operator()(SupportsRule*); 28 | Statement* operator()(AtRootRule*); 29 | Statement* operator()(AtRule*); 30 | Statement* operator()(Keyframe_Rule*); 31 | Statement* operator()(Trace*); 32 | Statement* operator()(Declaration*); 33 | // Statement* operator()(Assignment*); 34 | // Statement* operator()(Import*); 35 | // Statement* operator()(Import_Stub*); 36 | // Statement* operator()(WarningRule*); 37 | // Statement* operator()(Error*); 38 | // Statement* operator()(Comment*); 39 | // Statement* operator()(If*); 40 | // Statement* operator()(ForRule*); 41 | // Statement* operator()(EachRule*); 42 | // Statement* operator()(WhileRule*); 43 | // Statement* operator()(Return*); 44 | // Statement* operator()(ExtendRule*); 45 | // Statement* operator()(Definition*); 46 | // Statement* operator()(Mixin_Call*); 47 | // Statement* operator()(Content*); 48 | Statement* operator()(Null*); 49 | 50 | Statement* parent(); 51 | sass::vector> slice_by_bubble(Block*); 52 | Statement* bubble(AtRule*); 53 | Statement* bubble(AtRootRule*); 54 | Statement* bubble(CssMediaRule*); 55 | Statement* bubble(SupportsRule*); 56 | 57 | Block* debubble(Block* children, Statement* parent = 0); 58 | Block* flatten(const Block*); 59 | bool bubblable(Statement*); 60 | 61 | // generic fallback 62 | template 63 | Statement* fallback(U x) 64 | { return Cast(x); } 65 | 66 | void append_block(Block*, Block*); 67 | }; 68 | 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/libsass/src/debug.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_DEBUG_H 2 | #define SASS_DEBUG_H 3 | 4 | #include 5 | 6 | #ifndef UINT32_MAX 7 | #define UINT32_MAX 0xffffffffU 8 | #endif 9 | 10 | enum dbg_lvl_t : uint32_t { 11 | NONE = 0, 12 | TRIM = 1, 13 | CHUNKS = 2, 14 | SUBWEAVE = 4, 15 | WEAVE = 8, 16 | EXTEND_COMPOUND = 16, 17 | EXTEND_COMPLEX = 32, 18 | LCS = 64, 19 | EXTEND_OBJECT = 128, 20 | ALL = UINT32_MAX 21 | }; 22 | 23 | #ifdef DEBUG 24 | 25 | #ifndef DEBUG_LVL 26 | const uint32_t debug_lvl = UINT32_MAX; 27 | #else 28 | const uint32_t debug_lvl = (DEBUG_LVL); 29 | #endif // DEBUG_LVL 30 | 31 | #define DEBUG_PRINT(lvl, x) if((lvl) & debug_lvl) { std::cerr << x; } 32 | #define DEBUG_PRINTLN(lvl, x) if((lvl) & debug_lvl) { std::cerr << x << std::endl; } 33 | #define DEBUG_EXEC(lvl, x) if((lvl) & debug_lvl) { x; } 34 | 35 | #else // DEBUG 36 | 37 | #define DEBUG_PRINT(lvl, x) 38 | #define DEBUG_PRINTLN(lvl, x) 39 | #define DEBUG_EXEC(lvl, x) 40 | 41 | #endif // DEBUG 42 | 43 | #endif // SASS_DEBUG 44 | -------------------------------------------------------------------------------- /src/libsass/src/eval_selectors.cpp: -------------------------------------------------------------------------------- 1 | // sass.hpp must go before all system headers to get the 2 | // __EXTENSIONS__ fix on Solaris. 3 | #include "sass.hpp" 4 | #include "expand.hpp" 5 | #include "eval.hpp" 6 | #include "ast.hpp" 7 | 8 | 9 | namespace Sass { 10 | 11 | SelectorList* Eval::operator()(SelectorList* s) 12 | { 13 | sass::vector rv; 14 | SelectorListObj sl = SASS_MEMORY_NEW(SelectorList, s->pstate()); 15 | for (size_t i = 0, iL = s->length(); i < iL; ++i) { 16 | rv.push_back(operator()(s->get(i))); 17 | } 18 | 19 | // we should actually permutate parent first 20 | // but here we have permutated the selector first 21 | size_t round = 0; 22 | while (round != sass::string::npos) { 23 | bool abort = true; 24 | for (size_t i = 0, iL = rv.size(); i < iL; ++i) { 25 | if (rv[i]->length() > round) { 26 | sl->append((*rv[i])[round]); 27 | abort = false; 28 | } 29 | } 30 | if (abort) { 31 | round = sass::string::npos; 32 | } 33 | else { 34 | ++round; 35 | } 36 | 37 | } 38 | return sl.detach(); 39 | } 40 | 41 | SelectorComponent* Eval::operator()(SelectorComponent* s) 42 | { 43 | return {}; 44 | } 45 | 46 | SelectorList* Eval::operator()(ComplexSelector* s) 47 | { 48 | bool implicit_parent = !exp.old_at_root_without_rule; 49 | if (is_in_selector_schema) exp.pushNullSelector(); 50 | SelectorListObj other = s->resolve_parent_refs( 51 | exp.getOriginalStack(), traces, implicit_parent); 52 | if (is_in_selector_schema) exp.popNullSelector(); 53 | 54 | for (size_t i = 0; i < other->length(); i++) { 55 | ComplexSelectorObj sel = other->at(i); 56 | for (size_t n = 0; n < sel->length(); n++) { 57 | if (CompoundSelectorObj comp = Cast(sel->at(n))) { 58 | sel->at(n) = operator()(comp); 59 | } 60 | } 61 | } 62 | 63 | return other.detach(); 64 | } 65 | 66 | CompoundSelector* Eval::operator()(CompoundSelector* s) 67 | { 68 | for (size_t i = 0; i < s->length(); i++) { 69 | SimpleSelector* ss = s->at(i); 70 | // skip parents here (called via resolve_parent_refs) 71 | s->at(i) = Cast(ss->perform(this)); 72 | } 73 | return s; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/libsass/src/extension.cpp: -------------------------------------------------------------------------------- 1 | // sass.hpp must go before all system headers to get the 2 | // __EXTENSIONS__ fix on Solaris. 3 | #include "sass.hpp" 4 | 5 | #include "ast_helpers.hpp" 6 | #include "extension.hpp" 7 | #include "ast.hpp" 8 | 9 | namespace Sass { 10 | 11 | // ########################################################################## 12 | // Static function to create a copy with a new extender 13 | // ########################################################################## 14 | Extension Extension::withExtender(const ComplexSelectorObj& newExtender) const 15 | { 16 | Extension extension(newExtender); 17 | extension.specificity = specificity; 18 | extension.isOptional = isOptional; 19 | extension.target = target; 20 | return extension; 21 | } 22 | 23 | // ########################################################################## 24 | // Asserts that the [mediaContext] for a selector is 25 | // compatible with the query context for this extender. 26 | // ########################################################################## 27 | void Extension::assertCompatibleMediaContext(CssMediaRuleObj mediaQueryContext, Backtraces& traces) const 28 | { 29 | 30 | if (this->mediaContext.isNull()) return; 31 | 32 | if (mediaQueryContext && ObjPtrEqualityFn(mediaContext->block(), mediaQueryContext->block())) return; 33 | 34 | if (ObjEqualityFn(mediaQueryContext, mediaContext)) return; 35 | 36 | throw Exception::ExtendAcrossMedia(traces, *this); 37 | 38 | } 39 | 40 | // ########################################################################## 41 | // ########################################################################## 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/libsass/src/extension.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_EXTENSION_H 2 | #define SASS_EXTENSION_H 3 | 4 | // sass.hpp must go before all system headers to get the 5 | // __EXTENSIONS__ fix on Solaris. 6 | #include "sass.hpp" 7 | 8 | #include 9 | #include 10 | #include "ast_fwd_decl.hpp" 11 | #include "backtrace.hpp" 12 | 13 | namespace Sass { 14 | 15 | class Extension { 16 | 17 | public: 18 | 19 | // The selector in which the `@extend` appeared. 20 | ComplexSelectorObj extender; 21 | 22 | // The selector that's being extended. 23 | // `null` for one-off extensions. 24 | SimpleSelectorObj target; 25 | 26 | // The minimum specificity required for any 27 | // selector generated from this extender. 28 | size_t specificity; 29 | 30 | // Whether this extension is optional. 31 | bool isOptional; 32 | 33 | // Whether this is a one-off extender representing a selector that was 34 | // originally in the document, rather than one defined with `@extend`. 35 | bool isOriginal; 36 | 37 | bool isSatisfied; 38 | 39 | // The media query context to which this extend is restricted, 40 | // or `null` if it can apply within any context. 41 | CssMediaRuleObj mediaContext; 42 | 43 | // Creates a one-off extension that's not intended to be modified over time. 44 | // If [specificity] isn't passed, it defaults to `extender.maxSpecificity`. 45 | Extension(ComplexSelectorObj extender) : 46 | extender(extender), 47 | target({}), 48 | specificity(0), 49 | isOptional(true), 50 | isOriginal(false), 51 | isSatisfied(false), 52 | mediaContext({}) { 53 | 54 | } 55 | 56 | // Copy constructor 57 | Extension(const Extension& extension) : 58 | extender(extension.extender), 59 | target(extension.target), 60 | specificity(extension.specificity), 61 | isOptional(extension.isOptional), 62 | isOriginal(extension.isOriginal), 63 | isSatisfied(extension.isSatisfied), 64 | mediaContext(extension.mediaContext) { 65 | 66 | } 67 | 68 | // Default constructor 69 | Extension() : 70 | extender({}), 71 | target({}), 72 | specificity(0), 73 | isOptional(false), 74 | isOriginal(false), 75 | isSatisfied(false), 76 | mediaContext({}) { 77 | } 78 | 79 | // Asserts that the [mediaContext] for a selector is 80 | // compatible with the query context for this extender. 81 | void assertCompatibleMediaContext(CssMediaRuleObj mediaContext, Backtraces& traces) const; 82 | 83 | Extension withExtender(const ComplexSelectorObj& newExtender) const; 84 | 85 | }; 86 | 87 | } 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /src/libsass/src/fn_lists.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_FN_LISTS_H 2 | #define SASS_FN_LISTS_H 3 | 4 | #include "fn_utils.hpp" 5 | 6 | namespace Sass { 7 | 8 | namespace Functions { 9 | 10 | extern Signature length_sig; 11 | extern Signature nth_sig; 12 | extern Signature index_sig; 13 | extern Signature join_sig; 14 | extern Signature append_sig; 15 | extern Signature zip_sig; 16 | extern Signature list_separator_sig; 17 | extern Signature is_bracketed_sig; 18 | extern Signature keywords_sig; 19 | 20 | BUILT_IN(length); 21 | BUILT_IN(nth); 22 | BUILT_IN(index); 23 | BUILT_IN(join); 24 | BUILT_IN(append); 25 | BUILT_IN(zip); 26 | BUILT_IN(list_separator); 27 | BUILT_IN(is_bracketed); 28 | BUILT_IN(keywords); 29 | 30 | } 31 | 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/libsass/src/fn_maps.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_FN_MAPS_H 2 | #define SASS_FN_MAPS_H 3 | 4 | #include "fn_utils.hpp" 5 | 6 | namespace Sass { 7 | 8 | namespace Functions { 9 | 10 | #define ARGM(argname, argtype) get_arg_m(argname, env, sig, pstate, traces) 11 | 12 | extern Signature map_get_sig; 13 | extern Signature map_merge_sig; 14 | extern Signature map_remove_sig; 15 | extern Signature map_keys_sig; 16 | extern Signature map_values_sig; 17 | extern Signature map_has_key_sig; 18 | 19 | BUILT_IN(map_get); 20 | BUILT_IN(map_merge); 21 | BUILT_IN(map_remove); 22 | BUILT_IN(map_keys); 23 | BUILT_IN(map_values); 24 | BUILT_IN(map_has_key); 25 | 26 | } 27 | 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/libsass/src/fn_miscs.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_FN_MISCS_H 2 | #define SASS_FN_MISCS_H 3 | 4 | #include "fn_utils.hpp" 5 | 6 | namespace Sass { 7 | 8 | namespace Functions { 9 | 10 | extern Signature type_of_sig; 11 | extern Signature variable_exists_sig; 12 | extern Signature global_variable_exists_sig; 13 | extern Signature function_exists_sig; 14 | extern Signature mixin_exists_sig; 15 | extern Signature feature_exists_sig; 16 | extern Signature call_sig; 17 | extern Signature not_sig; 18 | extern Signature if_sig; 19 | extern Signature set_nth_sig; 20 | extern Signature content_exists_sig; 21 | extern Signature get_function_sig; 22 | 23 | BUILT_IN(type_of); 24 | BUILT_IN(variable_exists); 25 | BUILT_IN(global_variable_exists); 26 | BUILT_IN(function_exists); 27 | BUILT_IN(mixin_exists); 28 | BUILT_IN(feature_exists); 29 | BUILT_IN(call); 30 | BUILT_IN(sass_not); 31 | BUILT_IN(sass_if); 32 | BUILT_IN(set_nth); 33 | BUILT_IN(content_exists); 34 | BUILT_IN(get_function); 35 | 36 | } 37 | 38 | } 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/libsass/src/fn_numbers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_FN_NUMBERS_H 2 | #define SASS_FN_NUMBERS_H 3 | 4 | #include "fn_utils.hpp" 5 | 6 | namespace Sass { 7 | 8 | namespace Functions { 9 | 10 | // return a number object (copied since we want to have reduced units) 11 | #define ARGN(argname) get_arg_n(argname, env, sig, pstate, traces) // Number copy 12 | 13 | extern Signature percentage_sig; 14 | extern Signature round_sig; 15 | extern Signature ceil_sig; 16 | extern Signature floor_sig; 17 | extern Signature abs_sig; 18 | extern Signature min_sig; 19 | extern Signature max_sig; 20 | extern Signature inspect_sig; 21 | extern Signature random_sig; 22 | extern Signature unique_id_sig; 23 | extern Signature unit_sig; 24 | extern Signature unitless_sig; 25 | extern Signature comparable_sig; 26 | 27 | BUILT_IN(percentage); 28 | BUILT_IN(round); 29 | BUILT_IN(ceil); 30 | BUILT_IN(floor); 31 | BUILT_IN(abs); 32 | BUILT_IN(min); 33 | BUILT_IN(max); 34 | BUILT_IN(inspect); 35 | BUILT_IN(random); 36 | BUILT_IN(unique_id); 37 | BUILT_IN(unit); 38 | BUILT_IN(unitless); 39 | BUILT_IN(comparable); 40 | 41 | } 42 | 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/libsass/src/fn_selectors.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_FN_SELECTORS_H 2 | #define SASS_FN_SELECTORS_H 3 | 4 | #include "fn_utils.hpp" 5 | 6 | namespace Sass { 7 | 8 | namespace Functions { 9 | 10 | #define ARGSEL(argname) get_arg_sel(argname, env, sig, pstate, traces, ctx) 11 | #define ARGSELS(argname) get_arg_sels(argname, env, sig, pstate, traces, ctx) 12 | 13 | BUILT_IN(selector_nest); 14 | BUILT_IN(selector_append); 15 | BUILT_IN(selector_extend); 16 | BUILT_IN(selector_replace); 17 | BUILT_IN(selector_unify); 18 | BUILT_IN(is_superselector); 19 | BUILT_IN(simple_selectors); 20 | BUILT_IN(selector_parse); 21 | 22 | extern Signature selector_nest_sig; 23 | extern Signature selector_append_sig; 24 | extern Signature selector_extend_sig; 25 | extern Signature selector_replace_sig; 26 | extern Signature selector_unify_sig; 27 | extern Signature is_superselector_sig; 28 | extern Signature simple_selectors_sig; 29 | extern Signature selector_parse_sig; 30 | 31 | } 32 | 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/libsass/src/fn_strings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_FN_STRINGS_H 2 | #define SASS_FN_STRINGS_H 3 | 4 | #include "fn_utils.hpp" 5 | 6 | namespace Sass { 7 | 8 | namespace Functions { 9 | 10 | extern Signature unquote_sig; 11 | extern Signature quote_sig; 12 | extern Signature str_length_sig; 13 | extern Signature str_insert_sig; 14 | extern Signature str_index_sig; 15 | extern Signature str_slice_sig; 16 | extern Signature to_upper_case_sig; 17 | extern Signature to_lower_case_sig; 18 | extern Signature length_sig; 19 | 20 | BUILT_IN(sass_unquote); 21 | BUILT_IN(sass_quote); 22 | BUILT_IN(str_length); 23 | BUILT_IN(str_insert); 24 | BUILT_IN(str_index); 25 | BUILT_IN(str_slice); 26 | BUILT_IN(to_upper_case); 27 | BUILT_IN(to_lower_case); 28 | BUILT_IN(length); 29 | 30 | } 31 | 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/libsass/src/kwd_arg_macros.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_KWD_ARG_MACROS_H 2 | #define SASS_KWD_ARG_MACROS_H 3 | 4 | // Example usage: 5 | // KWD_ARG_SET(Args) { 6 | // KWD_ARG(Args, string, foo); 7 | // KWD_ARG(Args, int, bar); 8 | // ... 9 | // }; 10 | // 11 | // ... and later ... 12 | // 13 | // something(Args().foo("hey").bar(3)); 14 | 15 | #define KWD_ARG_SET(set_name) class set_name 16 | 17 | #define KWD_ARG(set_name, type, name) \ 18 | private: \ 19 | type name##_; \ 20 | public: \ 21 | set_name& name(type name##__) { \ 22 | name##_ = name##__; \ 23 | return *this; \ 24 | } \ 25 | type name() { return name##_; } \ 26 | private: 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/libsass/src/listize.cpp: -------------------------------------------------------------------------------- 1 | // sass.hpp must go before all system headers to get the 2 | // __EXTENSIONS__ fix on Solaris. 3 | #include "sass.hpp" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "listize.hpp" 10 | #include "context.hpp" 11 | #include "backtrace.hpp" 12 | #include "error_handling.hpp" 13 | 14 | namespace Sass { 15 | 16 | Listize::Listize() 17 | { } 18 | 19 | Expression* Listize::perform(AST_Node* node) 20 | { 21 | Listize listize; 22 | return node->perform(&listize); 23 | } 24 | 25 | Expression* Listize::operator()(SelectorList* sel) 26 | { 27 | List_Obj l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA); 28 | l->from_selector(true); 29 | for (size_t i = 0, L = sel->length(); i < L; ++i) { 30 | if (!sel->at(i)) continue; 31 | l->append(sel->at(i)->perform(this)); 32 | } 33 | if (l->length()) return l.detach(); 34 | return SASS_MEMORY_NEW(Null, l->pstate()); 35 | } 36 | 37 | Expression* Listize::operator()(CompoundSelector* sel) 38 | { 39 | sass::string str; 40 | for (size_t i = 0, L = sel->length(); i < L; ++i) { 41 | Expression* e = (*sel)[i]->perform(this); 42 | if (e) str += e->to_string(); 43 | } 44 | return SASS_MEMORY_NEW(String_Quoted, sel->pstate(), str); 45 | } 46 | 47 | Expression* Listize::operator()(ComplexSelector* sel) 48 | { 49 | List_Obj l = SASS_MEMORY_NEW(List, sel->pstate()); 50 | // ToDo: investigate what this does 51 | // Note: seems reated to parent ref 52 | l->from_selector(true); 53 | 54 | for (auto component : sel->elements()) { 55 | if (CompoundSelectorObj compound = Cast(component)) { 56 | if (!compound->empty()) { 57 | ExpressionObj hh = compound->perform(this); 58 | if (hh) l->append(hh); 59 | } 60 | } 61 | else if (component) { 62 | l->append(SASS_MEMORY_NEW(String_Quoted, component->pstate(), component->to_string())); 63 | } 64 | } 65 | 66 | if (l->length() == 0) return 0; 67 | return l.detach(); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/libsass/src/listize.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_LISTIZE_H 2 | #define SASS_LISTIZE_H 3 | 4 | // sass.hpp must go before all system headers to get the 5 | // __EXTENSIONS__ fix on Solaris. 6 | #include "sass.hpp" 7 | 8 | #include "ast_fwd_decl.hpp" 9 | #include "operation.hpp" 10 | 11 | namespace Sass { 12 | 13 | struct Backtrace; 14 | 15 | class Listize : public Operation_CRTP { 16 | 17 | public: 18 | 19 | static Expression* perform(AST_Node* node); 20 | 21 | public: 22 | Listize(); 23 | ~Listize() { } 24 | 25 | Expression* operator()(SelectorList*); 26 | Expression* operator()(ComplexSelector*); 27 | Expression* operator()(CompoundSelector*); 28 | 29 | // generic fallback 30 | template 31 | Expression* fallback(U x) 32 | { return Cast(x); } 33 | }; 34 | 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/libsass/src/mapping.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_MAPPING_H 2 | #define SASS_MAPPING_H 3 | 4 | #include "position.hpp" 5 | #include "backtrace.hpp" 6 | 7 | namespace Sass { 8 | 9 | struct Mapping { 10 | Position original_position; 11 | Position generated_position; 12 | 13 | Mapping(const Position& original_position, const Position& generated_position) 14 | : original_position(original_position), generated_position(generated_position) { } 15 | }; 16 | 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/libsass/src/memory.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_MEMORY_H 2 | #define SASS_MEMORY_H 3 | 4 | #include "settings.hpp" 5 | 6 | // Include memory headers 7 | #include "memory/config.hpp" 8 | #include "memory/allocator.hpp" 9 | #include "memory/shared_ptr.hpp" 10 | #include "memory/memory_pool.hpp" 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/libsass/src/memory/allocator.cpp: -------------------------------------------------------------------------------- 1 | #include "../sass.hpp" 2 | #include "allocator.hpp" 3 | #include "memory_pool.hpp" 4 | 5 | #if defined (_MSC_VER) // Visual studio 6 | #define thread_local __declspec( thread ) 7 | #elif defined (__GCC__) // GCC 8 | #define thread_local __thread 9 | #endif 10 | 11 | namespace Sass { 12 | 13 | #ifdef SASS_CUSTOM_ALLOCATOR 14 | 15 | // Only use PODs for thread_local 16 | // Objects get unpredictable init order 17 | static thread_local MemoryPool* pool; 18 | static thread_local size_t allocations; 19 | 20 | void* allocateMem(size_t size) 21 | { 22 | if (pool == nullptr) { 23 | pool = new MemoryPool(); 24 | } 25 | allocations++; 26 | return pool->allocate(size); 27 | } 28 | 29 | void deallocateMem(void* ptr, size_t size) 30 | { 31 | 32 | // It seems thread_local variable might be discharged!? 33 | // But the destructors of e.g. static strings is still 34 | // called, although their memory was discharged too. 35 | // Fine with me as long as address sanitizer is happy. 36 | if (pool == nullptr || allocations == 0) { return; } 37 | 38 | pool->deallocate(ptr); 39 | if (--allocations == 0) { 40 | delete pool; 41 | pool = nullptr; 42 | } 43 | 44 | } 45 | 46 | #endif 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/libsass/src/memory/config.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_MEMORY_CONFIG_H 2 | #define SASS_MEMORY_CONFIG_H 3 | 4 | // Define memory alignment requirements 5 | #define SASS_MEM_ALIGN sizeof(unsigned int) 6 | 7 | // Minimal alignment for memory fragments. Must be a multiple 8 | // of `SASS_MEM_ALIGN` and should not be too big (maybe 1 or 2) 9 | #define SassAllocatorHeadSize sizeof(unsigned int) 10 | 11 | // The number of bytes we use for our book-keeping before every 12 | // memory fragment. Needed to know to which bucket we belongs on 13 | // deallocations, or if it should go directly to the `free` call. 14 | #define SassAllocatorBookSize sizeof(unsigned int) 15 | 16 | // Bytes reserve for book-keeping on the arenas 17 | // Currently unused and for later optimization 18 | #define SassAllocatorArenaHeadSize 0 19 | 20 | #endif -------------------------------------------------------------------------------- /src/libsass/src/memory/shared_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include "../sass.hpp" 2 | #include 3 | #include 4 | 5 | #include "shared_ptr.hpp" 6 | #include "../ast_fwd_decl.hpp" 7 | 8 | #ifdef DEBUG_SHARED_PTR 9 | #include "../debugger.hpp" 10 | #endif 11 | 12 | namespace Sass { 13 | 14 | #ifdef DEBUG_SHARED_PTR 15 | void SharedObj::dumpMemLeaks() { 16 | if (!all.empty()) { 17 | std::cerr << "###################################\n"; 18 | std::cerr << "# REPORTING MISSING DEALLOCATIONS #\n"; 19 | std::cerr << "###################################\n"; 20 | for (SharedObj* var : all) { 21 | if (AST_Node* ast = dynamic_cast(var)) { 22 | debug_ast(ast); 23 | } else { 24 | std::cerr << "LEAKED " << var << "\n"; 25 | } 26 | } 27 | } 28 | } 29 | sass::vector SharedObj::all; 30 | #endif 31 | 32 | bool SharedObj::taint = false; 33 | } 34 | -------------------------------------------------------------------------------- /src/libsass/src/operators.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_OPERATORS_H 2 | #define SASS_OPERATORS_H 3 | 4 | #include "values.hpp" 5 | #include "sass/values.h" 6 | 7 | namespace Sass { 8 | 9 | namespace Operators { 10 | 11 | // equality operator using AST Node operator== 12 | bool eq(ExpressionObj, ExpressionObj); 13 | bool neq(ExpressionObj, ExpressionObj); 14 | // specific operators based on cmp and eq 15 | bool lt(ExpressionObj, ExpressionObj); 16 | bool gt(ExpressionObj, ExpressionObj); 17 | bool lte(ExpressionObj, ExpressionObj); 18 | bool gte(ExpressionObj, ExpressionObj); 19 | // arithmetic for all the combinations that matter 20 | Value* op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false); 21 | Value* op_colors(enum Sass_OP, const Color_RGBA&, const Color_RGBA&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false); 22 | Value* op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false); 23 | Value* op_number_color(enum Sass_OP, const Number&, const Color_RGBA&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false); 24 | Value* op_color_number(enum Sass_OP, const Color_RGBA&, const Number&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false); 25 | 26 | }; 27 | 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/libsass/src/output.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_OUTPUT_H 2 | #define SASS_OUTPUT_H 3 | 4 | #include 5 | #include 6 | 7 | #include "util.hpp" 8 | #include "inspect.hpp" 9 | #include "operation.hpp" 10 | 11 | namespace Sass { 12 | class Context; 13 | 14 | class Output : public Inspect { 15 | protected: 16 | using Inspect::operator(); 17 | 18 | public: 19 | Output(Sass_Output_Options& opt); 20 | virtual ~Output(); 21 | 22 | protected: 23 | sass::string charset; 24 | sass::vector top_nodes; 25 | 26 | public: 27 | OutputBuffer get_buffer(void); 28 | 29 | virtual void operator()(Map*); 30 | virtual void operator()(StyleRule*); 31 | virtual void operator()(SupportsRule*); 32 | virtual void operator()(CssMediaRule*); 33 | virtual void operator()(AtRule*); 34 | virtual void operator()(Keyframe_Rule*); 35 | virtual void operator()(Import*); 36 | virtual void operator()(Comment*); 37 | virtual void operator()(Number*); 38 | virtual void operator()(String_Quoted*); 39 | virtual void operator()(String_Constant*); 40 | 41 | void fallback_impl(AST_Node* n); 42 | 43 | }; 44 | 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/libsass/src/plugins.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_PLUGINS_H 2 | #define SASS_PLUGINS_H 3 | 4 | #include 5 | #include 6 | #include "utf8_string.hpp" 7 | #include "sass/functions.h" 8 | 9 | #ifdef _WIN32 10 | 11 | #define LOAD_LIB(var, path) HMODULE var = LoadLibraryW(UTF_8::convert_to_utf16(path).c_str()) 12 | #define LOAD_LIB_WCHR(var, path_wide_str) HMODULE var = LoadLibraryW(path_wide_str.c_str()) 13 | #define LOAD_LIB_FN(type, var, name) type var = (type) GetProcAddress(plugin, name) 14 | #define CLOSE_LIB(var) FreeLibrary(var) 15 | 16 | #ifndef dlerror 17 | #define dlerror() 0 18 | #endif 19 | 20 | #else 21 | 22 | #define LOAD_LIB(var, path) void* var = dlopen(path.c_str(), RTLD_LAZY) 23 | #define LOAD_LIB_FN(type, var, name) type var = (type) dlsym(plugin, name) 24 | #define CLOSE_LIB(var) dlclose(var) 25 | 26 | #endif 27 | 28 | namespace Sass { 29 | 30 | 31 | class Plugins { 32 | 33 | public: // c-tor 34 | Plugins(void); 35 | ~Plugins(void); 36 | 37 | public: // methods 38 | // load one specific plugin 39 | bool load_plugin(const sass::string& path); 40 | // load all plugins from a directory 41 | size_t load_plugins(const sass::string& path); 42 | 43 | public: // public accessors 44 | const sass::vector get_headers(void) { return headers; } 45 | const sass::vector get_importers(void) { return importers; } 46 | const sass::vector get_functions(void) { return functions; } 47 | 48 | private: // private vars 49 | sass::vector headers; 50 | sass::vector importers; 51 | sass::vector functions; 52 | 53 | }; 54 | 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/libsass/src/remove_placeholders.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_REMOVE_PLACEHOLDERS_H 2 | #define SASS_REMOVE_PLACEHOLDERS_H 3 | 4 | #include "ast_fwd_decl.hpp" 5 | #include "operation.hpp" 6 | 7 | namespace Sass { 8 | 9 | class Remove_Placeholders : public Operation_CRTP { 10 | 11 | public: 12 | 13 | SelectorList* remove_placeholders(SelectorList*); 14 | void remove_placeholders(SimpleSelector* simple); 15 | void remove_placeholders(CompoundSelector* complex); 16 | void remove_placeholders(ComplexSelector* complex); 17 | 18 | 19 | public: 20 | Remove_Placeholders(); 21 | ~Remove_Placeholders() { } 22 | 23 | void operator()(Block*); 24 | void operator()(StyleRule*); 25 | void operator()(CssMediaRule*); 26 | void operator()(SupportsRule*); 27 | void operator()(AtRule*); 28 | 29 | // ignore missed types 30 | template 31 | void fallback(U x) {} 32 | 33 | }; 34 | 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/libsass/src/sass_functions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_SASS_FUNCTIONS_H 2 | #define SASS_SASS_FUNCTIONS_H 3 | 4 | #include "sass.h" 5 | #include "environment.hpp" 6 | #include "fn_utils.hpp" 7 | 8 | // Struct to hold custom function callback 9 | struct Sass_Function { 10 | char* signature; 11 | Sass_Function_Fn function; 12 | void* cookie; 13 | }; 14 | 15 | // External import entry 16 | struct Sass_Import { 17 | char* imp_path; // path as found in the import statement 18 | char *abs_path; // path after importer has resolved it 19 | char* source; 20 | char* srcmap; 21 | // error handling 22 | char* error; 23 | size_t line; 24 | size_t column; 25 | }; 26 | 27 | // External environments 28 | struct Sass_Env { 29 | // links to parent frames 30 | Sass::Env* frame; 31 | }; 32 | 33 | // External call entry 34 | struct Sass_Callee { 35 | const char* name; 36 | const char* path; 37 | size_t line; 38 | size_t column; 39 | enum Sass_Callee_Type type; 40 | struct Sass_Env env; 41 | }; 42 | 43 | // Struct to hold importer callback 44 | struct Sass_Importer { 45 | Sass_Importer_Fn importer; 46 | double priority; 47 | void* cookie; 48 | }; 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/libsass/src/sass_values.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_SASS_VALUES_H 2 | #define SASS_SASS_VALUES_H 3 | 4 | #include "sass.h" 5 | 6 | struct Sass_Unknown { 7 | enum Sass_Tag tag; 8 | }; 9 | 10 | struct Sass_Boolean { 11 | enum Sass_Tag tag; 12 | bool value; 13 | }; 14 | 15 | struct Sass_Number { 16 | enum Sass_Tag tag; 17 | double value; 18 | char* unit; 19 | }; 20 | 21 | struct Sass_Color { 22 | enum Sass_Tag tag; 23 | double r; 24 | double g; 25 | double b; 26 | double a; 27 | }; 28 | 29 | struct Sass_String { 30 | enum Sass_Tag tag; 31 | bool quoted; 32 | char* value; 33 | }; 34 | 35 | struct Sass_List { 36 | enum Sass_Tag tag; 37 | enum Sass_Separator separator; 38 | bool is_bracketed; 39 | size_t length; 40 | // null terminated "array" 41 | union Sass_Value** values; 42 | }; 43 | 44 | struct Sass_Map { 45 | enum Sass_Tag tag; 46 | size_t length; 47 | struct Sass_MapPair* pairs; 48 | }; 49 | 50 | struct Sass_Null { 51 | enum Sass_Tag tag; 52 | }; 53 | 54 | struct Sass_Error { 55 | enum Sass_Tag tag; 56 | char* message; 57 | }; 58 | 59 | struct Sass_Warning { 60 | enum Sass_Tag tag; 61 | char* message; 62 | }; 63 | 64 | union Sass_Value { 65 | struct Sass_Unknown unknown; 66 | struct Sass_Boolean boolean; 67 | struct Sass_Number number; 68 | struct Sass_Color color; 69 | struct Sass_String string; 70 | struct Sass_List list; 71 | struct Sass_Map map; 72 | struct Sass_Null null; 73 | struct Sass_Error error; 74 | struct Sass_Warning warning; 75 | }; 76 | 77 | struct Sass_MapPair { 78 | union Sass_Value* key; 79 | union Sass_Value* value; 80 | }; 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/libsass/src/settings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_SETTINGS_H 2 | #define SASS_SETTINGS_H 3 | 4 | // Global compile time settings should go here 5 | 6 | // When enabled we use our custom memory pool allocator 7 | // With intense workloads this can double the performance 8 | // Max memory usage mostly only grows by a slight amount 9 | // #define SASS_CUSTOM_ALLOCATOR 10 | 11 | // How many buckets should we have for the free-list 12 | // Determines when allocations go directly to malloc/free 13 | // For maximum size of managed items multiply by alignment 14 | #define SassAllocatorBuckets 512 15 | 16 | // The size of the memory pool arenas in bytes. 17 | #define SassAllocatorArenaSize (1024 * 256) 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/libsass/src/source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "source.hpp" 4 | #include "utf8/checked.h" 5 | #include "position.hpp" 6 | 7 | namespace Sass { 8 | 9 | SourceData::SourceData() 10 | : SharedObj() 11 | { 12 | } 13 | 14 | SourceFile::SourceFile( 15 | const char* path, 16 | const char* data, 17 | size_t srcid) : 18 | SourceData(), 19 | path(sass_copy_c_string(path)), 20 | data(sass_copy_c_string(data)), 21 | length(0), 22 | srcid(srcid) 23 | { 24 | length = strlen(data); 25 | } 26 | 27 | SourceFile::~SourceFile() { 28 | sass_free_memory(path); 29 | sass_free_memory(data); 30 | } 31 | 32 | const char* SourceFile::end() const 33 | { 34 | return data + length; 35 | } 36 | 37 | const char* SourceFile::begin() const 38 | { 39 | return data; 40 | } 41 | 42 | const char* SourceFile::getRawData() const 43 | { 44 | return data; 45 | } 46 | 47 | SourceSpan SourceFile::getSourceSpan() 48 | { 49 | return SourceSpan(this); 50 | } 51 | 52 | ItplFile::ItplFile(const char* data, const SourceSpan& pstate) : 53 | SourceFile(pstate.getPath(), 54 | data, pstate.getSrcId()), 55 | pstate(pstate) 56 | {} 57 | 58 | const char* ItplFile::getRawData() const 59 | { 60 | return pstate.getRawData(); 61 | } 62 | 63 | SourceSpan ItplFile::getSourceSpan() 64 | { 65 | return SourceSpan(pstate); 66 | } 67 | 68 | } 69 | 70 | -------------------------------------------------------------------------------- /src/libsass/src/source.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_SOURCE_H 2 | #define SASS_SOURCE_H 3 | 4 | #include "sass.hpp" 5 | #include "memory.hpp" 6 | #include "position.hpp" 7 | #include "source_data.hpp" 8 | 9 | namespace Sass { 10 | 11 | class SourceFile : 12 | public SourceData { 13 | protected: 14 | char* path; 15 | char* data; 16 | size_t length; 17 | size_t srcid; 18 | public: 19 | 20 | SourceFile( 21 | const char* path, 22 | const char* data, 23 | size_t srcid); 24 | 25 | ~SourceFile(); 26 | 27 | const char* end() const override final; 28 | const char* begin() const override final; 29 | virtual const char* getRawData() const override; 30 | virtual SourceSpan getSourceSpan() override; 31 | 32 | size_t size() const override final { 33 | return length; 34 | } 35 | 36 | virtual const char* getPath() const override { 37 | return path; 38 | } 39 | 40 | virtual size_t getSrcId() const override { 41 | return srcid; 42 | } 43 | 44 | }; 45 | 46 | class SynthFile : 47 | public SourceData { 48 | protected: 49 | const char* path; 50 | public: 51 | 52 | SynthFile( 53 | const char* path) : 54 | path(path) 55 | {} 56 | 57 | ~SynthFile() {} 58 | 59 | const char* end() const override final { return nullptr; } 60 | const char* begin() const override final { return nullptr; }; 61 | virtual const char* getRawData() const override { return nullptr; }; 62 | virtual SourceSpan getSourceSpan() override { return SourceSpan(path); }; 63 | 64 | size_t size() const override final { 65 | return 0; 66 | } 67 | 68 | virtual const char* getPath() const override { 69 | return path; 70 | } 71 | 72 | virtual size_t getSrcId() const override { 73 | return std::string::npos; 74 | } 75 | 76 | }; 77 | 78 | 79 | class ItplFile : 80 | public SourceFile { 81 | private: 82 | SourceSpan pstate; 83 | public: 84 | 85 | ItplFile(const char* data, 86 | const SourceSpan& pstate); 87 | 88 | // Offset getPosition() const override final; 89 | const char* getRawData() const override final; 90 | SourceSpan getSourceSpan() override final; 91 | }; 92 | 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /src/libsass/src/source_data.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_SOURCE_DATA_H 2 | #define SASS_SOURCE_DATA_H 3 | 4 | #include "sass.hpp" 5 | #include "memory.hpp" 6 | 7 | namespace Sass { 8 | 9 | class SourceSpan; 10 | 11 | class SourceData : 12 | public SharedObj { 13 | public: 14 | SourceData(); 15 | virtual size_t size() const = 0; 16 | virtual size_t getSrcId() const = 0; 17 | virtual const char* end() const = 0; 18 | virtual const char* begin() const = 0; 19 | virtual const char* getPath() const = 0; 20 | // virtual Offset getPosition() const = 0; 21 | virtual const char* getRawData() const = 0; 22 | virtual SourceSpan getSourceSpan() = 0; 23 | 24 | sass::string to_string() const override { 25 | return sass::string{ begin(), end() }; 26 | } 27 | ~SourceData() {} 28 | }; 29 | 30 | } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/libsass/src/source_map.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_SOURCE_MAP_H 2 | #define SASS_SOURCE_MAP_H 3 | 4 | #include 5 | #include 6 | 7 | #include "ast_fwd_decl.hpp" 8 | #include "base64vlq.hpp" 9 | #include "position.hpp" 10 | #include "mapping.hpp" 11 | 12 | #include "backtrace.hpp" 13 | #include "memory.hpp" 14 | 15 | #define VECTOR_PUSH(vec, ins) vec.insert(vec.end(), ins.begin(), ins.end()) 16 | #define VECTOR_UNSHIFT(vec, ins) vec.insert(vec.begin(), ins.begin(), ins.end()) 17 | 18 | namespace Sass { 19 | 20 | class Context; 21 | class OutputBuffer; 22 | 23 | class SourceMap { 24 | 25 | public: 26 | sass::vector source_index; 27 | SourceMap(); 28 | SourceMap(const sass::string& file); 29 | 30 | void append(const Offset& offset); 31 | void prepend(const Offset& offset); 32 | void append(const OutputBuffer& out); 33 | void prepend(const OutputBuffer& out); 34 | void add_open_mapping(const AST_Node* node); 35 | void add_close_mapping(const AST_Node* node); 36 | 37 | sass::string render_srcmap(Context &ctx); 38 | SourceSpan remap(const SourceSpan& pstate); 39 | 40 | private: 41 | 42 | sass::string serialize_mappings(); 43 | 44 | sass::vector mappings; 45 | Position current_position; 46 | public: 47 | sass::string file; 48 | private: 49 | Base64VLQ base64vlq; 50 | }; 51 | 52 | class OutputBuffer { 53 | public: 54 | OutputBuffer(void) 55 | : buffer(), 56 | smap() 57 | { } 58 | public: 59 | sass::string buffer; 60 | SourceMap smap; 61 | }; 62 | 63 | } 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/libsass/src/stylesheet.cpp: -------------------------------------------------------------------------------- 1 | // sass.hpp must go before all system headers to get the 2 | // __EXTENSIONS__ fix on Solaris. 3 | #include "sass.hpp" 4 | 5 | #include "stylesheet.hpp" 6 | 7 | namespace Sass { 8 | 9 | // Constructor 10 | Sass::StyleSheet::StyleSheet(const Resource& res, Block_Obj root) : 11 | Resource(res), 12 | root(root) 13 | { 14 | } 15 | 16 | StyleSheet::StyleSheet(const StyleSheet& sheet) : 17 | Resource(sheet), 18 | root(sheet.root) 19 | { 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/libsass/src/stylesheet.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_STYLESHEET_H 2 | #define SASS_STYLESHEET_H 3 | 4 | // sass.hpp must go before all system headers to get the 5 | // __EXTENSIONS__ fix on Solaris. 6 | #include "sass.hpp" 7 | 8 | #include "ast_fwd_decl.hpp" 9 | #include "extender.hpp" 10 | #include "file.hpp" 11 | 12 | namespace Sass { 13 | 14 | // parsed stylesheet from loaded resource 15 | // this should be a `Module` for sass 4.0 16 | class StyleSheet : public Resource { 17 | public: 18 | 19 | // The canonical URL for this module's source file. This may be `null` 20 | // if the module was loaded from a string without a URL provided. 21 | // Uri get url; 22 | 23 | // Modules that this module uses. 24 | // List get upstream; 25 | 26 | // The module's variables. 27 | // Map get variables; 28 | 29 | // The module's functions. Implementations must ensure 30 | // that each [Callable] is stored under its own name. 31 | // Map get functions; 32 | 33 | // The module's mixins. Implementations must ensure that 34 | // each [Callable] is stored under its own name. 35 | // Map get mixins; 36 | 37 | // The extensions defined in this module, which is also able to update 38 | // [css]'s style rules in-place based on downstream extensions. 39 | // Extender extender; 40 | 41 | // The module's CSS tree. 42 | Block_Obj root; 43 | 44 | public: 45 | 46 | // default argument constructor 47 | StyleSheet(const Resource& res, Block_Obj root); 48 | 49 | // Copy constructor 50 | StyleSheet(const StyleSheet& res); 51 | 52 | }; 53 | 54 | 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/libsass/src/support/libsass.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libsass 7 | URL: https://github.com/sass/libsass 8 | Description: A C implementation of a Sass compiler 9 | Version: @VERSION@ 10 | Libs: -L${libdir} -lsass 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /src/libsass/src/to_value.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_TO_VALUE_H 2 | #define SASS_TO_VALUE_H 3 | 4 | #include "operation.hpp" 5 | #include "sass/values.h" 6 | #include "ast_fwd_decl.hpp" 7 | 8 | namespace Sass { 9 | 10 | class To_Value : public Operation_CRTP { 11 | 12 | private: 13 | 14 | Context& ctx; 15 | 16 | public: 17 | 18 | To_Value(Context& ctx) 19 | : ctx(ctx) 20 | { } 21 | ~To_Value() { } 22 | using Operation::operator(); 23 | 24 | Value* operator()(Argument*); 25 | Value* operator()(Boolean*); 26 | Value* operator()(Number*); 27 | Value* operator()(Color_RGBA*); 28 | Value* operator()(Color_HSLA*); 29 | Value* operator()(String_Constant*); 30 | Value* operator()(String_Quoted*); 31 | Value* operator()(Custom_Warning*); 32 | Value* operator()(Custom_Error*); 33 | Value* operator()(List*); 34 | Value* operator()(Map*); 35 | Value* operator()(Null*); 36 | Value* operator()(Function*); 37 | 38 | // convert to string via `To_String` 39 | Value* operator()(SelectorList*); 40 | Value* operator()(Binary_Expression*); 41 | 42 | }; 43 | 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/libsass/src/utf8.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | 28 | #ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | #define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 30 | 31 | #include "utf8/checked.h" 32 | #include "utf8/unchecked.h" 33 | 34 | #endif // header guard 35 | -------------------------------------------------------------------------------- /src/libsass/src/utf8_string.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_UTF8_STRING_H 2 | #define SASS_UTF8_STRING_H 3 | 4 | #include 5 | #include "utf8.h" 6 | #include "memory.hpp" 7 | 8 | namespace Sass { 9 | namespace UTF_8 { 10 | 11 | // naming conventions: 12 | // offset: raw byte offset (0 based) 13 | // position: code point offset (0 based) 14 | // index: code point offset (1 based or negative) 15 | 16 | // function that will count the number of code points (utf-8 characters) from the beginning to the given end 17 | size_t code_point_count(const sass::string& str, size_t start, size_t end); 18 | size_t code_point_count(const sass::string& str); 19 | 20 | // function that will return the byte offset of a code point in a 21 | size_t offset_at_position(const sass::string& str, size_t position); 22 | 23 | // function that returns number of bytes in a character in a string 24 | size_t code_point_size_at_offset(const sass::string& str, size_t offset); 25 | 26 | // function that will return a normalized index, given a crazy one 27 | size_t normalize_index(int index, size_t len); 28 | 29 | #ifdef _WIN32 30 | // functions to handle unicode paths on windows 31 | sass::string convert_from_utf16(const std::wstring& wstr); 32 | std::wstring convert_to_utf16(const sass::string& str); 33 | #endif 34 | 35 | } 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/libsass/src/values.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SASS_VALUES_H 2 | #define SASS_VALUES_H 3 | 4 | #include "ast.hpp" 5 | 6 | namespace Sass { 7 | 8 | union Sass_Value* ast_node_to_sass_value (const Expression* val); 9 | Value* sass_value_to_ast_node (const union Sass_Value* val); 10 | 11 | } 12 | #endif 13 | -------------------------------------------------------------------------------- /src/libsass/utils/README.md: -------------------------------------------------------------------------------- 1 | This directory contains some utilities that are not essential for LibSass. 2 | 3 | # perl update-builds.pl 4 | 5 | This will update 3rd party build files from `Makefile.conf`, which 6 | is the master index file for all required sources and headers. 7 | -------------------------------------------------------------------------------- /src/libsass/utils/build-skeletons/libsass.targets: -------------------------------------------------------------------------------- 1 | 2 | {{includes}} 3 | {{headers}} 4 | {{sources}} 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/libsass/utils/build-skeletons/libsass.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 6 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;in;inl;inc;xsd 11 | 12 | 13 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 14 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 15 | 16 | 17 | {{includes}} 18 | {{headers}} 19 | {{sources}} 20 | 21 | -------------------------------------------------------------------------------- /src/libsass/version.sh: -------------------------------------------------------------------------------- 1 | if test "x$LIBSASS_VERSION" = "x"; then 2 | LIBSASS_VERSION=`git describe --abbrev=4 --dirty --always --tags 2>/dev/null` 3 | fi 4 | if test "x$LIBSASS_VERSION" = "x"; then 5 | LIBSASS_VERSION=`cat VERSION 2>/dev/null` 6 | fi 7 | if test "x$LIBSASS_VERSION" = "x"; then 8 | LIBSASS_VERSION="[na]" 9 | fi 10 | echo $LIBSASS_VERSION 11 | -------------------------------------------------------------------------------- /src/libsass/win/libsass.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsass", "libsass.vcxproj", "{E4030474-AFC9-4CC6-BEB6-D846F631502B}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".SolutionItems", ".SolutionItems", "{33318C77-2391-4399-8118-C109155A4A75}" 9 | ProjectSection(SolutionItems) = preProject 10 | ..\.editorconfig = ..\.editorconfig 11 | ..\.gitattributes = ..\.gitattributes 12 | ..\.gitignore = ..\.gitignore 13 | ..\.travis.yml = ..\.travis.yml 14 | ..\appveyor.yml = ..\appveyor.yml 15 | ..\Readme.md = ..\Readme.md 16 | ..\res\resource.rc = ..\res\resource.rc 17 | EndProjectSection 18 | EndProject 19 | Global 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|Win32 = Debug|Win32 22 | Debug|Win64 = Debug|Win64 23 | Release|Win32 = Release|Win32 24 | Release|Win64 = Release|Win64 25 | EndGlobalSection 26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 27 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win32.ActiveCfg = Debug|Win32 28 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win32.Build.0 = Debug|Win32 29 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win64.ActiveCfg = Debug|x64 30 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win64.Build.0 = Debug|x64 31 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win32.ActiveCfg = Release|Win32 32 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win32.Build.0 = Release|Win32 33 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win64.ActiveCfg = Release|x64 34 | {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win64.Build.0 = Release|x64 35 | EndGlobalSection 36 | GlobalSection(SolutionProperties) = preSolution 37 | HideSolutionNode = FALSE 38 | EndGlobalSection 39 | EndGlobal 40 | -------------------------------------------------------------------------------- /src/libsass/win/libsass.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | ExplicitlyExcluded 3 | ExplicitlyExcluded 4 | ExplicitlyExcluded 5 | ExplicitlyExcluded 6 | ExplicitlyExcluded 7 | ExplicitlyExcluded 8 | ExplicitlyExcluded 9 | ExplicitlyExcluded -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(sass) 3 | 4 | test_check("sass") 5 | -------------------------------------------------------------------------------- /tests/testthat/.gitattributes: -------------------------------------------------------------------------------- 1 | # These need to have the exact same bytes on all platforms because read_utf8() 2 | # will return a string with "\r\n" -- it will not change it to "\n" 3 | # automatically -- and the tests expect "\n" only. 4 | 5 | *.sass text eol=lf 6 | *.scss text eol=lf 7 | *.css text eol=lf 8 | -------------------------------------------------------------------------------- /tests/testthat/_reset.scss: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | ul, 4 | ol { 5 | margin: 0; 6 | padding: 0; 7 | } 8 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/font-objects/font-css: -------------------------------------------------------------------------------- 1 | /* cyrillic-ext */ 2 | @font-face { 3 | font-family: 'Pacifico'; 4 | font-style: normal; 5 | font-weight: 400; 6 | font-display: swap; 7 | src: url(FwZY7-Qmy14u9lezJ-6K6MmTpA.woff2) format('woff2'); 8 | unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; 9 | } 10 | /* cyrillic */ 11 | @font-face { 12 | font-family: 'Pacifico'; 13 | font-style: normal; 14 | font-weight: 400; 15 | font-display: swap; 16 | src: url(FwZY7-Qmy14u9lezJ-6D6MmTpA.woff2) format('woff2'); 17 | unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; 18 | } 19 | /* vietnamese */ 20 | @font-face { 21 | font-family: 'Pacifico'; 22 | font-style: normal; 23 | font-weight: 400; 24 | font-display: swap; 25 | src: url(FwZY7-Qmy14u9lezJ-6I6MmTpA.woff2) format('woff2'); 26 | unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; 27 | } 28 | /* latin-ext */ 29 | @font-face { 30 | font-family: 'Pacifico'; 31 | font-style: normal; 32 | font-weight: 400; 33 | font-display: swap; 34 | src: url(FwZY7-Qmy14u9lezJ-6J6MmTpA.woff2) format('woff2'); 35 | unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; 36 | } 37 | /* latin */ 38 | @font-face { 39 | font-family: 'Pacifico'; 40 | font-style: normal; 41 | font-weight: 400; 42 | font-display: swap; 43 | src: url(FwZY7-Qmy14u9lezJ-6H6Mk.woff2) format('woff2'); 44 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/html-dependencies.md: -------------------------------------------------------------------------------- 1 | # sass()/as_sass() relay html dependencies 2 | 3 | Code 4 | sass(scss) 5 | Output 6 | /* CSS */ 7 | body { 8 | color: green; 9 | } 10 | 11 | 12 | /* HTML Dependencies */ 13 | List of 1 14 | $ :List of 10 15 | ..$ name : chr "fake1" 16 | ..$ version : chr "1.0.0" 17 | ..$ src :List of 1 18 | .. ..$ file: chr "" 19 | ..$ meta : NULL 20 | ..$ script : NULL 21 | ..$ stylesheet: NULL 22 | ..$ head : NULL 23 | ..$ attachment: NULL 24 | ..$ package : NULL 25 | ..$ all_files : logi TRUE 26 | ..- attr(*, "class")= chr "html_dependency" 27 | 28 | --- 29 | 30 | Code 31 | as_sass(scss) 32 | Output 33 | /* Sass */ 34 | body{color: green} 35 | 36 | /* HTML Dependencies */ 37 | List of 1 38 | $ :List of 10 39 | ..$ name : chr "fake1" 40 | ..$ version : chr "1.0.0" 41 | ..$ src :List of 1 42 | .. ..$ file: chr "" 43 | ..$ meta : NULL 44 | ..$ script : NULL 45 | ..$ stylesheet: NULL 46 | ..$ head : NULL 47 | ..$ attachment: NULL 48 | ..$ package : NULL 49 | ..$ all_files : logi TRUE 50 | ..- attr(*, "class")= chr "html_dependency" 51 | 52 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/layers.md: -------------------------------------------------------------------------------- 1 | # sass layer format 2 | 3 | Code 4 | format(core) 5 | Output 6 | [1] "@function my_invert($color, $amount: 100%) {\n $inverse: change-color($color, $hue: hue($color) + 180);\n @return mix($inverse, $color, $amount);\n }\n$color: blue !default;\nbody { background-color: $color; color: my_invert($color); }" 7 | 8 | --- 9 | 10 | Code 11 | core 12 | Output 13 | /* Sass Bundle */ 14 | @function my_invert($color, $amount: 100%) { 15 | $inverse: change-color($color, $hue: hue($color) + 180); 16 | @return mix($inverse, $color, $amount); 17 | } 18 | $color: blue !default; 19 | body { background-color: $color; color: my_invert($color); } 20 | /* *** */ 21 | 22 | # sass_layer_file() basically works 23 | 24 | Code 25 | str(sass_layer_file(f)) 26 | Output 27 | List of 1 28 | $ layers:List of 1 29 | ..$ :List of 7 30 | .. ..$ functions : chr [1:7] "@function color-contrast($color) {" " @return if(" " red($color) * 0.299 + green($color) * 0.587 + blue($color) * 0.114 > 186," " black, white" ... 31 | .. ..$ defaults : chr [1:2] "$body-color: color-contrast($body-bg) !default;" "" 32 | .. ..$ mixins : chr [1:4] "@mixin body-color {" " color: $body-color" "}" "" 33 | .. ..$ rules : chr [1:3] "body {" " @include body-color;" "}" 34 | .. ..$ declarations : NULL 35 | .. ..$ html_deps : NULL 36 | .. ..$ file_attachments: chr(0) 37 | .. ..- attr(*, "class")= chr [1:2] "sass_layer" "list" 38 | - attr(*, "class")= chr "sass_bundle" 39 | 40 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/utils.md: -------------------------------------------------------------------------------- 1 | # join_non_null_values combines null elements as expected 2 | 3 | Code 4 | obj 5 | Output 6 | /* Sass Bundle */ 7 | $color: blue; 8 | .rule-b {} 9 | .rule-a {} 10 | .rule-c {} 11 | /* *** */ 12 | 13 | -------------------------------------------------------------------------------- /tests/testthat/helper-cache.R: -------------------------------------------------------------------------------- 1 | # Turn off the default cache until the calling function exits; when that 2 | # happens, the previous default cache will be restored. 3 | local_disable_cache <- function(env = parent.frame()) { 4 | old_opts <- options(sass.cache = FALSE) 5 | withr::defer( 6 | options(old_opts), 7 | envir = env 8 | ) 9 | } 10 | 11 | # Creates a temporary cache that is used as the default. When the calling 12 | # function exits, the temporary cache is destroyed, and the previous default 13 | # cache is restored. 14 | local_temp_cache <- function(env = parent.frame()) { 15 | temp_cache <- sass_file_cache(dir = tempfile()) 16 | old_opts <- options(sass.cache = temp_cache) 17 | withr::defer( 18 | { 19 | options(old_opts) 20 | temp_cache$destroy() 21 | }, 22 | envir = env 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /tests/testthat/helper-utils.R: -------------------------------------------------------------------------------- 1 | compressed_css <- function(x) { 2 | gsub("\\s+|\\n", "", paste(as.character(x), collapse = "")) 3 | } 4 | 5 | expect_css <- function(input, css, output = NULL, ...) { 6 | res <- sass(input, output = output, ...) 7 | if (!is.null(output)) { 8 | res <- read_utf8(res) 9 | } 10 | expect_identical( 11 | compressed_css(res), 12 | compressed_css(css) 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /tests/testthat/test-assets/a.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/tests/testthat/test-assets/a.txt -------------------------------------------------------------------------------- /tests/testthat/test-assets/b/b1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/tests/testthat/test-assets/b/b1.txt -------------------------------------------------------------------------------- /tests/testthat/test-assets/c/c1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/tests/testthat/test-assets/c/c1.txt -------------------------------------------------------------------------------- /tests/testthat/test-assets/c/d/d1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/tests/testthat/test-assets/c/d/d1.txt -------------------------------------------------------------------------------- /tests/testthat/test-assets/test-layer-file.scss: -------------------------------------------------------------------------------- 1 | /*-- scss:functions --*/ 2 | @function color-contrast($color) { 3 | @return if( 4 | red($color) * 0.299 + green($color) * 0.587 + blue($color) * 0.114 > 186, 5 | black, white 6 | ); 7 | } 8 | 9 | /*-- scss:defaults --*/ 10 | $body-color: color-contrast($body-bg) !default; 11 | 12 | /*-- scss:mixins --*/ 13 | @mixin body-color { 14 | color: $body-color 15 | } 16 | 17 | /*-- scss:rules --*/ 18 | body { 19 | @include body-color; 20 | } 21 | -------------------------------------------------------------------------------- /tests/testthat/test-compile.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | test_that(".scss file compiles", { 5 | expected <- "foo {\n margin: 36.6px;\n}\n\nbar {\n margin: 63px;\n}\n" 6 | class(expected) <- c("css", "html", "character") 7 | attr(expected, "html") <- TRUE 8 | 9 | expect_equal( 10 | sass(sass_file("test-compile.scss")), 11 | expected 12 | ) 13 | }) 14 | 15 | test_that("string input compiles", { 16 | expected <- "foo {\n margin: 36.6px;\n}\n" 17 | class(expected) <- c("css", "html", "character") 18 | attr(expected, "html") <- TRUE 19 | 20 | expect_equal( 21 | sass("foo { margin: 122px * .3; }"), 22 | expected 23 | ) 24 | }) 25 | 26 | test_that("character vector input compiles", { 27 | input <- c(".foo {\n color: red;\n}\n", ".bar {\n background-color: blue;\n}\n") 28 | expected <- paste(input, collapse = "\n") 29 | class(expected) <- c("css", "html", "character") 30 | attr(expected, "html") <- TRUE 31 | 32 | expect_equal(sass(input), expected) 33 | expect_equal(sass(as.list(input)), expected) 34 | }) 35 | 36 | test_that("named character vector throws warning", { 37 | expect_warning(sass(c(var = "foo{color: red}")), "named") 38 | }) 39 | 40 | test_that("sass compiles", { 41 | expected <- "foo {\n margin: 36.6px;\n}\n\nbar {\n margin: 63px;\n}\n" 42 | class(expected) <- c("css", "html", "character") 43 | attr(expected, "html") <- TRUE 44 | 45 | expect_equal( 46 | sass(sass_file("test-compile.sass"), sass_options(indented_syntax = TRUE)), 47 | expected 48 | ) 49 | }) 50 | 51 | 52 | test_that("sass_partial() and sass() arguments match", { 53 | s <- formals(sass) 54 | s$input <- NULL 55 | 56 | sp <- formals(sass_partial) 57 | sp$rules <- NULL 58 | sp$bundle <- NULL 59 | 60 | expect_identical(s, sp) 61 | }) 62 | -------------------------------------------------------------------------------- /tests/testthat/test-compile.sass: -------------------------------------------------------------------------------- 1 | foo 2 | margin: 122px * .3 3 | bar 4 | margin: 21px * 3 5 | -------------------------------------------------------------------------------- /tests/testthat/test-compile.scss: -------------------------------------------------------------------------------- 1 | foo { margin: 122px * .3; } 2 | bar { margin: 21px * 3; } 3 | -------------------------------------------------------------------------------- /tests/testthat/test-extend.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | test_that("extend works", { 5 | # allow for css rules to be reordered within a definition 6 | split_sort <- function(x) { 7 | sort( 8 | sub("\\s+$", "", # remove tailing 9 | sub("^\\s+", "", # remove leading 10 | strsplit(x, ",")[[1]] 11 | ) 12 | ) 13 | ) 14 | } 15 | expected_first_line <- ".message, .success, .error, .warning " 16 | css <- sass(sass_file("test-extend.scss")) 17 | expect_equal( 18 | split_sort(strsplit(css, "\\{")[[1]][1]), 19 | split_sort(expected_first_line) 20 | ) 21 | }) 22 | -------------------------------------------------------------------------------- /tests/testthat/test-extend.scss: -------------------------------------------------------------------------------- 1 | // This CSS won't print because %equal-heights is never extended. 2 | %equal-heights { 3 | display: flex; 4 | flex-wrap: wrap; 5 | } 6 | 7 | // This CSS will print because %message-shared is extended. 8 | %message-shared { 9 | border: 1px solid #ccc; 10 | padding: 10px; 11 | color: #333; 12 | } 13 | 14 | .message { 15 | @extend %message-shared; 16 | } 17 | 18 | .success { 19 | @extend %message-shared; 20 | border-color: green; 21 | } 22 | 23 | .error { 24 | @extend %message-shared; 25 | border-color: red; 26 | } 27 | 28 | .warning { 29 | @extend %message-shared; 30 | border-color: yellow; 31 | } 32 | -------------------------------------------------------------------------------- /tests/testthat/test-html-dependencies.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | library(htmltools) 5 | dep1 <- htmlDependency( 6 | name = "fake1", 7 | version = "1.0.0", 8 | src = "" 9 | ) 10 | dep2 <- htmlDependency( 11 | name = "fake2", 12 | version = "1.0.0", 13 | src = "" 14 | ) 15 | 16 | test_that("sass()/as_sass() relay html dependencies", { 17 | scss <- attachDependencies(list("body{color: green}"), dep1) 18 | # Test that the print methods also relay 19 | expect_snapshot(sass(scss), cran = TRUE) 20 | expect_snapshot(as_sass(scss), cran = TRUE) 21 | tmpcss <- tempfile(fileext = ".css") 22 | on.exit(unlink(tmpcss), add = TRUE) 23 | expect_equal(htmlDependencies(sass(scss)), list(dep1)) 24 | }) 25 | 26 | test_that("sass() relays sass_layer()'s html dependencies", { 27 | layer1 <- sass_layer(defaults = "body{color: green}", html_deps = dep1) 28 | input1 <- list(layer1, "body{color: red}") 29 | expect_equal(htmlDependencies(sass(input1)), list(dep1)) 30 | layer2 <- sass_layer(defaults = "body{color: blue}", html_deps = dep2) 31 | input2 <- sass_bundle(layer1, layer2) 32 | expect_equal(htmlDependencies(sass(input2)), list(dep1, dep2)) 33 | }) 34 | -------------------------------------------------------------------------------- /tests/testthat/test-import.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | test_that("import works", { 5 | imported_type <- "html" 6 | css <- sass(sass_file("test-import.scss")) 7 | expect_equal( 8 | strsplit(css, ",")[[1]][1], 9 | imported_type 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /tests/testthat/test-import.scss: -------------------------------------------------------------------------------- 1 | @import 'reset'; 2 | 3 | body { 4 | font: 100% Helvetica, sans-serif; 5 | background-color: #efefef; 6 | } 7 | -------------------------------------------------------------------------------- /tests/testthat/test-include-path/_need.scss: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | ul, 4 | ol { 5 | margin: 0; 6 | padding: 0; 7 | } 8 | -------------------------------------------------------------------------------- /tests/testthat/test-include-path2/_need2.scss: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | ul, 4 | ol { 5 | margin: 0; 6 | padding: 0; 7 | } 8 | -------------------------------------------------------------------------------- /tests/testthat/test-include-paths.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | test_that("single path works", { 5 | scss <- "@import \"need\"" 6 | css <- sass(scss, options = sass_options(include_path = "test-include-path/")) 7 | 8 | actual <- read_utf8("test-include-path/_need.scss") 9 | class(actual) <- c("css", "html", "character") 10 | attr(actual, "html") <- TRUE 11 | 12 | expect_equal(css, actual) 13 | }) 14 | 15 | test_that("multiple paths work", { 16 | scss <- "@import \"need\", \"need2\"" 17 | css <- sass( 18 | scss, 19 | options = sass_options(include_path = c("test-include-path/", "test-include-path2/")) 20 | ) 21 | 22 | css1 <- read_utf8("test-include-path/_need.scss") 23 | css2 <- read_utf8("test-include-path2/_need2.scss") 24 | actual <- paste0(c(css1, css2), collapse = "\n") 25 | class(actual) <- c("css", "html", "character") 26 | attr(actual, "html") <- TRUE 27 | 28 | expect_equal(css, actual) 29 | }) 30 | -------------------------------------------------------------------------------- /tests/testthat/test-layers-list.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | body_rule <- "body { background-color: $color; color: my_invert($color); }" 5 | 6 | blue <- list(color = "blue !default") 7 | red <- list(color = "red !default") 8 | green <- list(color = "green !default") 9 | core <- sass_layer( 10 | defaults = blue, 11 | functions = "@function my_invert($color, $amount: 100%) { 12 | $inverse: change-color($color, $hue: hue($color) + 180); 13 | @return mix($inverse, $color, $amount); 14 | }", 15 | rules = body_rule 16 | ) 17 | 18 | test_that("sass_layer is equivalent to sass", { 19 | expect_equal( 20 | sass(core), 21 | sass(list(blue, "body { background-color: $color; color: yellow; }")), 22 | ignore_attr = TRUE 23 | ) 24 | }) 25 | -------------------------------------------------------------------------------- /tests/testthat/test-mixins.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | test_that("mixins work", { 5 | expected_first_word <- ".box" 6 | css <- sass(sass_file("test-mixins.scss")) 7 | expect_equal( 8 | strsplit(css, " ")[[1]][1], 9 | expected_first_word 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /tests/testthat/test-mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin transform($property) { 2 | -webkit-transform: $property; 3 | -ms-transform: $property; 4 | transform: $property; 5 | } 6 | 7 | .box { @include transform(rotate(30deg)); } 8 | -------------------------------------------------------------------------------- /tests/testthat/test-nesting-expected.css: -------------------------------------------------------------------------------- 1 | nav ul { 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | 7 | nav li { 8 | display: inline-block; 9 | } 10 | 11 | nav a { 12 | display: block; 13 | padding: 6px 12px; 14 | text-decoration: none; 15 | } 16 | -------------------------------------------------------------------------------- /tests/testthat/test-nesting-input.scss: -------------------------------------------------------------------------------- 1 | nav { 2 | ul { 3 | margin: 0; 4 | padding: 0; 5 | list-style: none; 6 | } 7 | 8 | li { display: inline-block; } 9 | 10 | a { 11 | display: block; 12 | padding: 6px 12px; 13 | text-decoration: none; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/testthat/test-nesting.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | test_that("nesting works", { 5 | expected <- read_utf8("test-nesting-expected.css") 6 | class(expected) <- c("css", "html", "character") 7 | attr(expected, "html") <- TRUE 8 | 9 | css <- sass(sass_file("test-nesting-input.scss")) 10 | 11 | expect_equal(css, expected) 12 | }) 13 | -------------------------------------------------------------------------------- /tests/testthat/test-option-errors.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | test_that("unnamed options fail", { 5 | sass_options <- sass_options() 6 | names(sass_options) <- NULL 7 | expect_error( 8 | sass("foo { margin: 122px * .3; }", options = sass_options), 9 | "No named options" 10 | ) 11 | }) 12 | 13 | test_that("too few options fail", { 14 | sass_options <- sass_options() 15 | sass_options$precision <- NULL 16 | expect_error( 17 | sass("foo { margin: 122px * .3; }", options = sass_options), 18 | "missing" 19 | ) 20 | }) 21 | 22 | test_that("too many options fail", { 23 | sass_options <- sass_options() 24 | sass_options$new <- "hello" 25 | expect_error( 26 | sass("foo { margin: 122px * .3; }", options = sass_options), 27 | "unsupported" 28 | ) 29 | }) 30 | 31 | test_that("wrong options fail", { 32 | sass_options <- sass_options() 33 | sass_options$precision <- NULL 34 | sass_options$blah <- "hello" 35 | expect_error( 36 | sass("foo { margin: 122px * .3; }", options = sass_options), 37 | "precision" 38 | ) 39 | }) 40 | 41 | test_that("wrong type fails", { 42 | sass_options <- sass_options() 43 | sass_options$precision <- "hello" 44 | expect_error( 45 | sass("foo { margin: 122px * .3; }", options = sass_options), 46 | "Invalid type for precision" 47 | ) 48 | }) 49 | 50 | test_that("Global options work", { 51 | on.exit(sass_options_set(NULL), add = TRUE) 52 | 53 | expect_identical(sass_options_get(), sass_options()) 54 | 55 | old_options <- sass_options_set(precision = 10) 56 | expect_equal( 57 | sass_options_get(), 58 | sass_options(precision = 10), 59 | ignore_attr = TRUE 60 | ) 61 | 62 | expect_equal( 63 | sass_options_get(precision = 11), 64 | sass_options(precision = 11), 65 | ignore_attr = TRUE 66 | ) 67 | 68 | sass_options_set(old_options) 69 | expect_identical(sass_options_get(), sass_options()) 70 | 71 | sass_options_set(precision = 12) 72 | opts <- sass_options_get() 73 | sass_options_set(precision = 13) 74 | sass_options_set(opts) 75 | expect_equal( 76 | sass_options_get(), 77 | sass_options(precision = 12), 78 | ignore_attr = TRUE 79 | ) 80 | 81 | expect_error( 82 | sass_options_set(1), 83 | "sass_options" 84 | ) 85 | expect_error( 86 | sass_options_get(foo = "bar"), 87 | "foo" 88 | ) 89 | }) 90 | 91 | test_that("Global options work 2", { 92 | expect_identical(sass_options_get(), sass_options()) 93 | }) 94 | -------------------------------------------------------------------------------- /tests/testthat/test-options.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | test_that("indent width works", { 5 | scss <- "foo { margin: 122px * .3; }" 6 | css_default <- sass(scss) 7 | 8 | width <- 4 9 | css_width <- sass(scss, options = sass_options(indent_width = width)) 10 | expect_equal( 11 | nchar(css_default) + width - 2, 12 | nchar(css_width) 13 | ) 14 | }) 15 | 16 | test_that("indent as tabs works", { 17 | scss <- "foo { margin: 122px * .3; }" 18 | css <- sass(scss, options = sass_options(indent_width = 1, indent_type = "tab")) 19 | expect_equal( 20 | strsplit(css, "")[[1]][7], 21 | "\t" 22 | ) 23 | }) 24 | 25 | test_that("linefeed works", { 26 | scss <- "foo { margin: 122px * .3; }" 27 | css_lf <- sass(scss) 28 | 29 | expect_equal( 30 | strsplit(css_lf, "")[[1]][6], 31 | "\n" 32 | ) 33 | 34 | css_cr <- sass(scss, options = sass_options(linefeed = "cr")) 35 | 36 | expect_equal( 37 | strsplit(css_cr, "")[[1]][6], 38 | "\r" 39 | ) 40 | 41 | css_crlf <- sass(scss, options = sass_options(linefeed = "crlf")) 42 | 43 | expect_equal( 44 | paste0(strsplit(css_crlf, "")[[1]][6:7], collapse = ""), 45 | "\r\n" 46 | ) 47 | 48 | css_crlf <- sass(scss, options = sass_options(linefeed = "lfcr")) 49 | 50 | expect_equal( 51 | paste0(strsplit(css_crlf, "")[[1]][6:7], collapse = ""), 52 | "\n\r" 53 | ) 54 | }) 55 | 56 | test_that("precision works", { 57 | scss <- "foo { margin: 1px * 0.1234567891; }" 58 | num_chars_no_precision <- 23 59 | css <- sass(scss) 60 | 61 | expect_equal( 62 | num_chars_no_precision + 6, 63 | nchar(css) 64 | ) 65 | 66 | css <- sass(scss, options = sass_options(precision = 0)) 67 | expect_equal( 68 | num_chars_no_precision, 69 | nchar(css) 70 | ) 71 | 72 | css <- sass(scss, options = sass_options(precision = 10)) 73 | expect_equal( 74 | num_chars_no_precision + 11, 75 | nchar(css) 76 | ) 77 | }) 78 | 79 | test_that("source_comments work", { 80 | expect_lt( 81 | nchar(sass(sass_file("test-compile.scss"))), 82 | nchar(sass(sass_file("test-compile.scss"), sass_options(source_comments = TRUE))) 83 | ) 84 | }) 85 | -------------------------------------------------------------------------------- /tests/testthat/test-output.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | test_that("writing to file works", { 5 | file_name <- tempfile(fileext = ".css") 6 | sass( 7 | sass_file("test-nesting-input.scss"), 8 | output = file_name 9 | ) 10 | on.exit(unlink(file_name)) 11 | output <- paste0(readLines(file_name), collapse = "\n") 12 | expected <- paste0(readLines("test-nesting-expected.css"), collapse = "\n") 13 | 14 | expect_true(file.exists(file_name)) 15 | expect_equal(output, expected) 16 | }) 17 | 18 | test_that("writing to invalid path fails", { 19 | expect_error( 20 | sass( 21 | sass_file("test-nesting-input.scss"), 22 | output = "not/path/output.txt" 23 | ) 24 | ) 25 | }) 26 | -------------------------------------------------------------------------------- /tests/testthat/test-shiny-devmode.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("shiny devmode shuts off default caching", { 3 | 4 | expect_equal( 5 | identical( 6 | sass_cache_get(), 7 | NULL 8 | ), 9 | FALSE 10 | ) 11 | 12 | 13 | withr::local_options(list( 14 | shiny.devmode = TRUE, 15 | shiny.devmode.verbose = FALSE 16 | )) 17 | withr::local_envvar(list( 18 | TESTTHAT = "false" 19 | )) 20 | 21 | expect_equal( 22 | identical( 23 | sass_cache_get(), 24 | NULL 25 | ), 26 | TRUE 27 | ) 28 | 29 | }) 30 | -------------------------------------------------------------------------------- /tests/testthat/test-unicode-bom-expected.css: -------------------------------------------------------------------------------- 1 | foo { 2 | bar: baz; 3 | } 4 | -------------------------------------------------------------------------------- /tests/testthat/test-unicode-bom-input.scss: -------------------------------------------------------------------------------- 1 | foo { bar: baz; } -------------------------------------------------------------------------------- /tests/testthat/test-unicode-css-expected.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | foo { 3 | bar: föö bâr 🕺; 4 | } 5 | -------------------------------------------------------------------------------- /tests/testthat/test-unicode-css-input.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | foo { 3 | bar: föö bâr 🕺; } 4 | -------------------------------------------------------------------------------- /tests/testthat/test-unicode-var-expected.css: -------------------------------------------------------------------------------- 1 | blat { 2 | a: foo; 3 | } 4 | -------------------------------------------------------------------------------- /tests/testthat/test-unicode-var-input.scss: -------------------------------------------------------------------------------- 1 | $vär: foo; 2 | 3 | blat {a: $vär} 4 | -------------------------------------------------------------------------------- /tests/testthat/test-unicode.R: -------------------------------------------------------------------------------- 1 | test_that("unicode variables work", { 2 | local_disable_cache() 3 | expected <- read_utf8("test-unicode-var-expected.css") 4 | class(expected) <- c("css", "html", "character") 5 | attr(expected, "html") <- TRUE 6 | 7 | css <- sass(sass_file("test-unicode-var-input.scss")) 8 | 9 | expect_equal(css, expected) 10 | }) 11 | 12 | test_that("unicode css works with cache enabled", { 13 | expected <- read_utf8("test-unicode-css-expected.css") 14 | class(expected) <- c("css", "html", "character") 15 | attr(expected, "html") <- TRUE 16 | 17 | css <- sass(sass_file("test-unicode-css-input.scss")) 18 | 19 | expect_equal(Encoding(css), "UTF-8") 20 | expect_equal(css, expected) 21 | }) 22 | 23 | test_that("unicode css works with cache disabled", { 24 | local_disable_cache() 25 | expected <- read_utf8("test-unicode-css-expected.css") 26 | class(expected) <- c("css", "html", "character") 27 | attr(expected, "html") <- TRUE 28 | 29 | css <- sass(sass_file("test-unicode-css-input.scss")) 30 | 31 | expect_equal(Encoding(css), "UTF-8") 32 | expect_equal(css, expected) 33 | }) 34 | 35 | test_that("unicode bom", { 36 | expected <- read_utf8("test-unicode-bom-expected.css") 37 | class(expected) <- c("css", "html", "character") 38 | attr(expected, "html") <- TRUE 39 | 40 | css <- sass(sass_file("test-unicode-bom-input.scss")) 41 | 42 | expect_equal(css, expected) 43 | }) 44 | -------------------------------------------------------------------------------- /tests/testthat/test-variables.R: -------------------------------------------------------------------------------- 1 | # Disable sass cache 2 | local_disable_cache() 3 | 4 | test_that("variables work", { 5 | css <- sass(sass_file("test-variables.scss")) 6 | expect_equal( 7 | strsplit(css, " ")[[1]][6], 8 | "Helvetica," 9 | ) 10 | }) 11 | -------------------------------------------------------------------------------- /tests/testthat/test-variables.scss: -------------------------------------------------------------------------------- 1 | $font-stack: Helvetica, sans-serif; 2 | $primary-color: #333; 3 | 4 | body { 5 | font: 100% $font-stack; 6 | color: $primary-color; 7 | } 8 | -------------------------------------------------------------------------------- /vignettes/color-contrast.scss: -------------------------------------------------------------------------------- 1 | @function color-contrast($color) { 2 | @return if( 3 | red($color) * 0.299 + green($color) * 0.587 + blue($color) * 0.114 > 186, 4 | black, white 5 | ); 6 | } 7 | -------------------------------------------------------------------------------- /vignettes/hello-pacifico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/vignettes/hello-pacifico.png -------------------------------------------------------------------------------- /vignettes/my-style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rstudio/sass/e80e8971c048f71fef1d8b1eae1799b8325dd3be/vignettes/my-style.png -------------------------------------------------------------------------------- /vignettes/my-style.scss: -------------------------------------------------------------------------------- 1 | $body-bg: red; 2 | body{ 3 | background-color: $body-bg; 4 | } 5 | --------------------------------------------------------------------------------