.
9 |
10 | .list-group {
11 | // No need to set list-style: none; since .list-group-item is block level
12 | margin-bottom: 20px;
13 | padding-left: 0; // reset padding because ul and ol
14 | }
15 |
16 |
17 | // Individual list items
18 | //
19 | // Use on `li`s or `div`s within the `.list-group` parent.
20 |
21 | .list-group-item {
22 | position: relative;
23 | display: block;
24 | padding: 10px 15px;
25 | // Place the border on the list items and negative margin up for better styling
26 | margin-bottom: -1px;
27 | background-color: @list-group-bg;
28 | border: 1px solid @list-group-border;
29 |
30 | // Round the first and last items
31 | &:first-child {
32 | .border-top-radius(@list-group-border-radius);
33 | }
34 | &:last-child {
35 | margin-bottom: 0;
36 | .border-bottom-radius(@list-group-border-radius);
37 | }
38 | }
39 |
40 |
41 | // Linked list items
42 | //
43 | // Use anchor elements instead of `li`s or `div`s to create linked list items.
44 | // Includes an extra `.active` modifier class for showing selected items.
45 |
46 | a.list-group-item {
47 | color: @list-group-link-color;
48 |
49 | .list-group-item-heading {
50 | color: @list-group-link-heading-color;
51 | }
52 |
53 | // Hover state
54 | &:hover,
55 | &:focus {
56 | text-decoration: none;
57 | color: @list-group-link-hover-color;
58 | background-color: @list-group-hover-bg;
59 | }
60 | }
61 |
62 | .list-group-item {
63 | // Disabled state
64 | &.disabled,
65 | &.disabled:hover,
66 | &.disabled:focus {
67 | background-color: @list-group-disabled-bg;
68 | color: @list-group-disabled-color;
69 | cursor: @cursor-disabled;
70 |
71 | // Force color to inherit for custom content
72 | .list-group-item-heading {
73 | color: inherit;
74 | }
75 | .list-group-item-text {
76 | color: @list-group-disabled-text-color;
77 | }
78 | }
79 |
80 | // Active class on item itself, not parent
81 | &.active,
82 | &.active:hover,
83 | &.active:focus {
84 | z-index: 2; // Place active items above their siblings for proper border styling
85 | color: @list-group-active-color;
86 | background-color: @list-group-active-bg;
87 | border-color: @list-group-active-border;
88 |
89 | // Force color to inherit for custom content
90 | .list-group-item-heading,
91 | .list-group-item-heading > small,
92 | .list-group-item-heading > .small {
93 | color: inherit;
94 | }
95 | .list-group-item-text {
96 | color: @list-group-active-text-color;
97 | }
98 | }
99 | }
100 |
101 |
102 | // Contextual variants
103 | //
104 | // Add modifier classes to change text and background color on individual items.
105 | // Organizationally, this must come after the `:hover` states.
106 |
107 | .list-group-item-variant(success; @state-success-bg; @state-success-text);
108 | .list-group-item-variant(info; @state-info-bg; @state-info-text);
109 | .list-group-item-variant(warning; @state-warning-bg; @state-warning-text);
110 | .list-group-item-variant(danger; @state-danger-bg; @state-danger-text);
111 |
112 |
113 | // Custom content options
114 | //
115 | // Extra classes for creating well-formatted content within `.list-group-item`s.
116 |
117 | .list-group-item-heading {
118 | margin-top: 0;
119 | margin-bottom: 5px;
120 | }
121 | .list-group-item-text {
122 | margin-bottom: 0;
123 | line-height: 1.3;
124 | }
125 |
--------------------------------------------------------------------------------
/doc/bootstrap/mixins/grid.less:
--------------------------------------------------------------------------------
1 | // Grid system
2 | //
3 | // Generate semantic grid columns with these mixins.
4 |
5 | // Centered container element
6 | .container-fixed(@gutter: @grid-gutter-width) {
7 | margin-right: auto;
8 | margin-left: auto;
9 | padding-left: (@gutter / 2);
10 | padding-right: (@gutter / 2);
11 | &:extend(.clearfix all);
12 | }
13 |
14 | // Creates a wrapper for a series of columns
15 | .make-row(@gutter: @grid-gutter-width) {
16 | margin-left: (@gutter / -2);
17 | margin-right: (@gutter / -2);
18 | &:extend(.clearfix all);
19 | }
20 |
21 | // Generate the extra small columns
22 | .make-xs-column(@columns; @gutter: @grid-gutter-width) {
23 | position: relative;
24 | float: left;
25 | width: percentage((@columns / @grid-columns));
26 | min-height: 1px;
27 | padding-left: (@gutter / 2);
28 | padding-right: (@gutter / 2);
29 | }
30 | .make-xs-column-offset(@columns) {
31 | margin-left: percentage((@columns / @grid-columns));
32 | }
33 | .make-xs-column-push(@columns) {
34 | left: percentage((@columns / @grid-columns));
35 | }
36 | .make-xs-column-pull(@columns) {
37 | right: percentage((@columns / @grid-columns));
38 | }
39 |
40 | // Generate the small columns
41 | .make-sm-column(@columns; @gutter: @grid-gutter-width) {
42 | position: relative;
43 | min-height: 1px;
44 | padding-left: (@gutter / 2);
45 | padding-right: (@gutter / 2);
46 |
47 | @media (min-width: @screen-sm-min) {
48 | float: left;
49 | width: percentage((@columns / @grid-columns));
50 | }
51 | }
52 | .make-sm-column-offset(@columns) {
53 | @media (min-width: @screen-sm-min) {
54 | margin-left: percentage((@columns / @grid-columns));
55 | }
56 | }
57 | .make-sm-column-push(@columns) {
58 | @media (min-width: @screen-sm-min) {
59 | left: percentage((@columns / @grid-columns));
60 | }
61 | }
62 | .make-sm-column-pull(@columns) {
63 | @media (min-width: @screen-sm-min) {
64 | right: percentage((@columns / @grid-columns));
65 | }
66 | }
67 |
68 | // Generate the medium columns
69 | .make-md-column(@columns; @gutter: @grid-gutter-width) {
70 | position: relative;
71 | min-height: 1px;
72 | padding-left: (@gutter / 2);
73 | padding-right: (@gutter / 2);
74 |
75 | @media (min-width: @screen-md-min) {
76 | float: left;
77 | width: percentage((@columns / @grid-columns));
78 | }
79 | }
80 | .make-md-column-offset(@columns) {
81 | @media (min-width: @screen-md-min) {
82 | margin-left: percentage((@columns / @grid-columns));
83 | }
84 | }
85 | .make-md-column-push(@columns) {
86 | @media (min-width: @screen-md-min) {
87 | left: percentage((@columns / @grid-columns));
88 | }
89 | }
90 | .make-md-column-pull(@columns) {
91 | @media (min-width: @screen-md-min) {
92 | right: percentage((@columns / @grid-columns));
93 | }
94 | }
95 |
96 | // Generate the large columns
97 | .make-lg-column(@columns; @gutter: @grid-gutter-width) {
98 | position: relative;
99 | min-height: 1px;
100 | padding-left: (@gutter / 2);
101 | padding-right: (@gutter / 2);
102 |
103 | @media (min-width: @screen-lg-min) {
104 | float: left;
105 | width: percentage((@columns / @grid-columns));
106 | }
107 | }
108 | .make-lg-column-offset(@columns) {
109 | @media (min-width: @screen-lg-min) {
110 | margin-left: percentage((@columns / @grid-columns));
111 | }
112 | }
113 | .make-lg-column-push(@columns) {
114 | @media (min-width: @screen-lg-min) {
115 | left: percentage((@columns / @grid-columns));
116 | }
117 | }
118 | .make-lg-column-pull(@columns) {
119 | @media (min-width: @screen-lg-min) {
120 | right: percentage((@columns / @grid-columns));
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/doc/bootstrap/scaffolding.less:
--------------------------------------------------------------------------------
1 | //
2 | // Scaffolding
3 | // --------------------------------------------------
4 |
5 |
6 | // Reset the box-sizing
7 | //
8 | // Heads up! This reset may cause conflicts with some third-party widgets.
9 | // For recommendations on resolving such conflicts, see
10 | // http://getbootstrap.com/getting-started/#third-box-sizing
11 | * {
12 | .box-sizing(border-box);
13 | }
14 | *:before,
15 | *:after {
16 | .box-sizing(border-box);
17 | }
18 |
19 |
20 | // Body reset
21 |
22 | html {
23 | font-size: 10px;
24 | -webkit-tap-highlight-color: rgba(0,0,0,0);
25 | }
26 |
27 | body {
28 | font-family: @font-family-base;
29 | font-size: @font-size-base;
30 | line-height: @line-height-base;
31 | color: @text-color;
32 | background-color: @body-bg;
33 | }
34 |
35 | // Reset fonts for relevant elements
36 | input,
37 | button,
38 | select,
39 | textarea {
40 | font-family: inherit;
41 | font-size: inherit;
42 | line-height: inherit;
43 | }
44 |
45 |
46 | // Links
47 |
48 | a {
49 | color: @link-color;
50 | text-decoration: none;
51 |
52 | &:hover,
53 | &:focus {
54 | color: @link-hover-color;
55 | text-decoration: @link-hover-decoration;
56 | }
57 |
58 | &:focus {
59 | .tab-focus();
60 | }
61 | }
62 |
63 |
64 | // Figures
65 | //
66 | // We reset this here because previously Normalize had no `figure` margins. This
67 | // ensures we don't break anyone's use of the element.
68 |
69 | figure {
70 | margin: 0;
71 | }
72 |
73 |
74 | // Images
75 |
76 | img {
77 | vertical-align: middle;
78 | }
79 |
80 | // Responsive images (ensure images don't scale beyond their parents)
81 | .img-responsive {
82 | .img-responsive();
83 | }
84 |
85 | // Rounded corners
86 | .img-rounded {
87 | border-radius: @border-radius-large;
88 | }
89 |
90 | // Image thumbnails
91 | //
92 | // Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.
93 | .img-thumbnail {
94 | padding: @thumbnail-padding;
95 | line-height: @line-height-base;
96 | background-color: @thumbnail-bg;
97 | border: 1px solid @thumbnail-border;
98 | border-radius: @thumbnail-border-radius;
99 | .transition(all .2s ease-in-out);
100 |
101 | // Keep them at most 100% wide
102 | .img-responsive(inline-block);
103 | }
104 |
105 | // Perfect circle
106 | .img-circle {
107 | border-radius: 50%; // set radius in percents
108 | }
109 |
110 |
111 | // Horizontal rules
112 |
113 | hr {
114 | margin-top: @line-height-computed;
115 | margin-bottom: @line-height-computed;
116 | border: 0;
117 | border-top: 1px solid @hr-border;
118 | }
119 |
120 |
121 | // Only display content to screen readers
122 | //
123 | // See: http://a11yproject.com/posts/how-to-hide-content/
124 |
125 | .sr-only {
126 | position: absolute;
127 | width: 1px;
128 | height: 1px;
129 | margin: -1px;
130 | padding: 0;
131 | overflow: hidden;
132 | clip: rect(0,0,0,0);
133 | border: 0;
134 | }
135 |
136 | // Use in conjunction with .sr-only to only display content when it's focused.
137 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
138 | // Credit: HTML5 Boilerplate
139 |
140 | .sr-only-focusable {
141 | &:active,
142 | &:focus {
143 | position: static;
144 | width: auto;
145 | height: auto;
146 | margin: 0;
147 | overflow: visible;
148 | clip: auto;
149 | }
150 | }
151 |
152 |
153 | // iOS "clickable elements" fix for role="button"
154 | //
155 | // Fixes "clickability" issue (and more generally, the firing of events such as focus as well)
156 | // for traditionally non-focusable elements with role="button"
157 | // see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
158 | // Upstream patch for normalize.css submitted: https://github.com/necolas/normalize.css/pull/379 - remove this fix once that is merged
159 |
160 | [role="button"] {
161 | cursor: pointer;
162 | }
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: cpp
2 | dist: trusty
3 | sudo: false
4 |
5 | os: linux
6 |
7 | git:
8 | depth: 1
9 |
10 |
11 | env:
12 | global:
13 | - secure: |-
14 | a1eovNn4uol9won7ghr67eD3/59oeESN+G9bWE+ecI1V6yRseG9whniGhIpC/YfMW/Qz5I
15 | 5sxSmFjaw9bxCISNwUIrL1O5x2AmRYTnFcXk4dFsUvlZg+WeF/aKyBYCNRM8C2ndbBmtAO
16 | o1F2EwFbiso0EmtzhAPs19ujiVxkLn4=
17 |
18 | matrix:
19 | include:
20 | # Documentation
21 | - env: BUILD=Doc
22 | sudo: required
23 | # g++ 6 on Linux with C++14
24 | - env: COMPILER=g++-6 BUILD=Debug STANDARD=14
25 | compiler: gcc
26 | addons:
27 | apt:
28 | update: true
29 | sources:
30 | - ubuntu-toolchain-r-test
31 | packages:
32 | - g++-6
33 | - env: COMPILER=g++-6 BUILD=Release STANDARD=14
34 | compiler: gcc
35 | addons:
36 | apt:
37 | update: true
38 | sources:
39 | - ubuntu-toolchain-r-test
40 | packages:
41 | - g++-6
42 | # Apple clang on OS X with C++14
43 | - env: BUILD=Debug STANDARD=14
44 | compiler: clang
45 | os: osx
46 | - env: BUILD=Release STANDARD=14
47 | compiler: clang
48 | os: osx
49 | # clang 6.0 on Linux with C++14
50 | - env: COMPILER=clang++-6.0 BUILD=Debug STANDARD=14
51 | compiler: clang
52 | addons:
53 | apt:
54 | update: true
55 | packages:
56 | - clang-6.0
57 | sources:
58 | - ubuntu-toolchain-r-test
59 | - llvm-toolchain-trusty
60 | - llvm-toolchain-trusty-6.0
61 | # clang 4.0 on Linux with C++14
62 | - env: COMPILER=clang++-4.0 BUILD=Debug STANDARD=11
63 | compiler: clang
64 | addons:
65 | apt:
66 | update: true
67 | packages:
68 | - clang-4.0
69 | sources:
70 | - ubuntu-toolchain-r-test
71 | - llvm-toolchain-trusty
72 | - llvm-toolchain-trusty-4.0
73 | # g++ 4.8 on Linux with C++11
74 | - env: COMPILER=g++-4.8 BUILD=Debug STANDARD=11
75 | compiler: gcc
76 | # g++ 4.4 on Linux with C++11
77 | - env: COMPILER=g++-4.4 BUILD=Debug STANDARD=11
78 | compiler: gcc
79 | addons:
80 | apt:
81 | update: true
82 | packages:
83 | - g++-4.4
84 | sources:
85 | - ubuntu-toolchain-r-test
86 | # Android
87 | # - language: android
88 | # android:
89 | # addons:
90 | # apt:
91 | # update: true
92 | # components:
93 | # - tools
94 | # - platform-tools
95 | # - android-21
96 | # - sys-img-armeabi-v7a-android-21
97 | # env:
98 | # - ANDROID=true
99 | # before_install:
100 | # - git submodule update --init --recursive
101 | # - sudo apt-get install wget unzip tree
102 | # install:
103 | # # Accept SDK Licenses + Install NDK
104 | # - yes | sdkmanager --update > /dev/null 2>&1
105 | # - sdkmanager ndk-bundle > /dev/null 2>&1
106 | # # Download Gradle 4.3.1
107 | # - wget https://services.gradle.org/distributions/gradle-4.3.1-bin.zip
108 | # - mkdir -p gradle
109 | # - unzip -q -d ./gradle gradle-4.3.1-bin.zip
110 | # - export GRADLE=${TRAVIS_BUILD_DIR}/gradle/gradle-4.3.1/bin/gradle
111 | # before_script:
112 | # - bash $GRADLE --version
113 | # - cd ./support
114 | # script:
115 | # - bash $GRADLE clean assemble
116 | # after_success:
117 | # - cd ${TRAVIS_BUILD_DIR}
118 | # - tree ./libs
119 | allow_failures:
120 | # Errors
121 | - env: COMPILER=g++-4.4 BUILD=Debug STANDARD=11
122 | compiler: gcc
123 |
124 | before_script:
125 | - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then export CXX=${COMPILER}; fi
126 | - if [[ "${BUILD}" != "Doc" ]]; then ${CXX} --version; fi
127 |
128 | script:
129 | - support/travis-build.py
130 |
--------------------------------------------------------------------------------
/doc/bootstrap/popovers.less:
--------------------------------------------------------------------------------
1 | //
2 | // Popovers
3 | // --------------------------------------------------
4 |
5 |
6 | .popover {
7 | position: absolute;
8 | top: 0;
9 | left: 0;
10 | z-index: @zindex-popover;
11 | display: none;
12 | max-width: @popover-max-width;
13 | padding: 1px;
14 | // Reset font and text properties given new insertion method
15 | font-family: @font-family-base;
16 | font-size: @font-size-base;
17 | font-weight: normal;
18 | line-height: @line-height-base;
19 | text-align: left;
20 | background-color: @popover-bg;
21 | background-clip: padding-box;
22 | border: 1px solid @popover-fallback-border-color;
23 | border: 1px solid @popover-border-color;
24 | border-radius: @border-radius-large;
25 | .box-shadow(0 5px 10px rgba(0,0,0,.2));
26 |
27 | // Overrides for proper insertion
28 | white-space: normal;
29 |
30 | // Offset the popover to account for the popover arrow
31 | &.top { margin-top: -@popover-arrow-width; }
32 | &.right { margin-left: @popover-arrow-width; }
33 | &.bottom { margin-top: @popover-arrow-width; }
34 | &.left { margin-left: -@popover-arrow-width; }
35 | }
36 |
37 | .popover-title {
38 | margin: 0; // reset heading margin
39 | padding: 8px 14px;
40 | font-size: @font-size-base;
41 | background-color: @popover-title-bg;
42 | border-bottom: 1px solid darken(@popover-title-bg, 5%);
43 | border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;
44 | }
45 |
46 | .popover-content {
47 | padding: 9px 14px;
48 | }
49 |
50 | // Arrows
51 | //
52 | // .arrow is outer, .arrow:after is inner
53 |
54 | .popover > .arrow {
55 | &,
56 | &:after {
57 | position: absolute;
58 | display: block;
59 | width: 0;
60 | height: 0;
61 | border-color: transparent;
62 | border-style: solid;
63 | }
64 | }
65 | .popover > .arrow {
66 | border-width: @popover-arrow-outer-width;
67 | }
68 | .popover > .arrow:after {
69 | border-width: @popover-arrow-width;
70 | content: "";
71 | }
72 |
73 | .popover {
74 | &.top > .arrow {
75 | left: 50%;
76 | margin-left: -@popover-arrow-outer-width;
77 | border-bottom-width: 0;
78 | border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback
79 | border-top-color: @popover-arrow-outer-color;
80 | bottom: -@popover-arrow-outer-width;
81 | &:after {
82 | content: " ";
83 | bottom: 1px;
84 | margin-left: -@popover-arrow-width;
85 | border-bottom-width: 0;
86 | border-top-color: @popover-arrow-color;
87 | }
88 | }
89 | &.right > .arrow {
90 | top: 50%;
91 | left: -@popover-arrow-outer-width;
92 | margin-top: -@popover-arrow-outer-width;
93 | border-left-width: 0;
94 | border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback
95 | border-right-color: @popover-arrow-outer-color;
96 | &:after {
97 | content: " ";
98 | left: 1px;
99 | bottom: -@popover-arrow-width;
100 | border-left-width: 0;
101 | border-right-color: @popover-arrow-color;
102 | }
103 | }
104 | &.bottom > .arrow {
105 | left: 50%;
106 | margin-left: -@popover-arrow-outer-width;
107 | border-top-width: 0;
108 | border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback
109 | border-bottom-color: @popover-arrow-outer-color;
110 | top: -@popover-arrow-outer-width;
111 | &:after {
112 | content: " ";
113 | top: 1px;
114 | margin-left: -@popover-arrow-width;
115 | border-top-width: 0;
116 | border-bottom-color: @popover-arrow-color;
117 | }
118 | }
119 |
120 | &.left > .arrow {
121 | top: 50%;
122 | right: -@popover-arrow-outer-width;
123 | margin-top: -@popover-arrow-outer-width;
124 | border-right-width: 0;
125 | border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback
126 | border-left-color: @popover-arrow-outer-color;
127 | &:after {
128 | content: " ";
129 | right: 1px;
130 | border-right-width: 0;
131 | border-left-color: @popover-arrow-color;
132 | bottom: -@popover-arrow-width;
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/doc/usage.rst:
--------------------------------------------------------------------------------
1 | *****
2 | Usage
3 | *****
4 |
5 | To use the fmt library, add :file:`format.h` and :file:`format.cc` from
6 | a `release archive
`_
7 | or the `Git repository `_ to your project.
8 | Alternatively, you can :ref:`build the library with CMake `.
9 |
10 | If you are using Visual C++ with precompiled headers, you might need to add
11 | the line ::
12 |
13 | #include "stdafx.h"
14 |
15 | before other includes in :file:`format.cc`.
16 |
17 | .. _building:
18 |
19 | Building the library
20 | ====================
21 |
22 | The included `CMake build script`__ can be used to build the fmt
23 | library on a wide range of platforms. CMake is freely available for
24 | download from http://www.cmake.org/download/.
25 |
26 | __ https://github.com/fmtlib/fmt/blob/master/CMakeLists.txt
27 |
28 | CMake works by generating native makefiles or project files that can
29 | be used in the compiler environment of your choice. The typical
30 | workflow starts with::
31 |
32 | mkdir build # Create a directory to hold the build output.
33 | cd build
34 | cmake # Generate native build scripts.
35 |
36 | where :file:`{}` is a path to the ``fmt`` repository.
37 |
38 | If you are on a \*nix system, you should now see a Makefile in the
39 | current directory. Now you can build the library by running :command:`make`.
40 |
41 | Once the library has been built you can invoke :command:`make test` to run
42 | the tests.
43 |
44 | You can control generation of the make ``test`` target with the ``FMT_TEST``
45 | CMake option. This can be useful if you include fmt as a subdirectory in
46 | your project but don't want to add fmt's tests to your ``test`` target.
47 |
48 | If you use Windows and have Visual Studio installed, a :file:`FORMAT.sln`
49 | file and several :file:`.vcproj` files will be created. You can then build them
50 | using Visual Studio or msbuild.
51 |
52 | On Mac OS X with Xcode installed, an :file:`.xcodeproj` file will be generated.
53 |
54 | To build a `shared library`__ set the ``BUILD_SHARED_LIBS`` CMake variable to
55 | ``TRUE``::
56 |
57 | cmake -DBUILD_SHARED_LIBS=TRUE ...
58 |
59 | __ http://en.wikipedia.org/wiki/Library_%28computing%29#Shared_libraries
60 |
61 | Header-only usage with CMake
62 | ============================
63 |
64 | You can add the ``fmt`` library directory into your project and include it in
65 | your ``CMakeLists.txt`` file::
66 |
67 | add_subdirectory(fmt)
68 |
69 | or
70 |
71 | ::
72 |
73 | add_subdirectory(fmt EXCLUDE_FROM_ALL)
74 |
75 | to exclude it from ``make``, ``make all``, or ``cmake --build .``.
76 |
77 | Settting up your target to use a header-only version of ``fmt`` is equaly easy::
78 |
79 | target_link_libraries( PRIVATE fmt-header-only)
80 |
81 | Building the documentation
82 | ==========================
83 |
84 | To build the documentation you need the following software installed on your
85 | system:
86 |
87 | * `Python `_ with pip and virtualenv
88 | * `Doxygen `_
89 | * `Less `_ with ``less-plugin-clean-css``.
90 | Ubuntu doesn't package the ``clean-css`` plugin so you should use ``npm``
91 | instead of ``apt`` to install both ``less`` and the plugin::
92 |
93 | sudo npm install -g less less-plugin-clean-css.
94 |
95 | First generate makefiles or project files using CMake as described in
96 | the previous section. Then compile the ``doc`` target/project, for example::
97 |
98 | make doc
99 |
100 | This will generate the HTML documentation in ``doc/html``.
101 |
102 | Android NDK
103 | ===========
104 |
105 | fmt provides `Android.mk file`__ that can be used to build the library
106 | with `Android NDK `_.
107 | For an example of using fmt with Android NDK, see the
108 | `android-ndk-example `_
109 | repository.
110 |
111 | __ https://github.com/fmtlib/fmt/blob/master/Android.mk
112 |
113 | Homebrew
114 | ========
115 |
116 | fmt can be installed on OS X using `Homebrew `_::
117 |
118 | brew install fmt
119 |
--------------------------------------------------------------------------------
/doc/bootstrap/modals.less:
--------------------------------------------------------------------------------
1 | //
2 | // Modals
3 | // --------------------------------------------------
4 |
5 | // .modal-open - body class for killing the scroll
6 | // .modal - container to scroll within
7 | // .modal-dialog - positioning shell for the actual modal
8 | // .modal-content - actual modal w/ bg and corners and shit
9 |
10 | // Kill the scroll on the body
11 | .modal-open {
12 | overflow: hidden;
13 | }
14 |
15 | // Container that the modal scrolls within
16 | .modal {
17 | display: none;
18 | overflow: hidden;
19 | position: fixed;
20 | top: 0;
21 | right: 0;
22 | bottom: 0;
23 | left: 0;
24 | z-index: @zindex-modal;
25 | -webkit-overflow-scrolling: touch;
26 |
27 | // Prevent Chrome on Windows from adding a focus outline. For details, see
28 | // https://github.com/twbs/bootstrap/pull/10951.
29 | outline: 0;
30 |
31 | // When fading in the modal, animate it to slide down
32 | &.fade .modal-dialog {
33 | .translate(0, -25%);
34 | .transition-transform(~"0.3s ease-out");
35 | }
36 | &.in .modal-dialog { .translate(0, 0) }
37 | }
38 | .modal-open .modal {
39 | overflow-x: hidden;
40 | overflow-y: auto;
41 | }
42 |
43 | // Shell div to position the modal with bottom padding
44 | .modal-dialog {
45 | position: relative;
46 | width: auto;
47 | margin: 10px;
48 | }
49 |
50 | // Actual modal
51 | .modal-content {
52 | position: relative;
53 | background-color: @modal-content-bg;
54 | border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)
55 | border: 1px solid @modal-content-border-color;
56 | border-radius: @border-radius-large;
57 | .box-shadow(0 3px 9px rgba(0,0,0,.5));
58 | background-clip: padding-box;
59 | // Remove focus outline from opened modal
60 | outline: 0;
61 | }
62 |
63 | // Modal background
64 | .modal-backdrop {
65 | position: fixed;
66 | top: 0;
67 | right: 0;
68 | bottom: 0;
69 | left: 0;
70 | z-index: @zindex-modal-background;
71 | background-color: @modal-backdrop-bg;
72 | // Fade for backdrop
73 | &.fade { .opacity(0); }
74 | &.in { .opacity(@modal-backdrop-opacity); }
75 | }
76 |
77 | // Modal header
78 | // Top section of the modal w/ title and dismiss
79 | .modal-header {
80 | padding: @modal-title-padding;
81 | border-bottom: 1px solid @modal-header-border-color;
82 | min-height: (@modal-title-padding + @modal-title-line-height);
83 | }
84 | // Close icon
85 | .modal-header .close {
86 | margin-top: -2px;
87 | }
88 |
89 | // Title text within header
90 | .modal-title {
91 | margin: 0;
92 | line-height: @modal-title-line-height;
93 | }
94 |
95 | // Modal body
96 | // Where all modal content resides (sibling of .modal-header and .modal-footer)
97 | .modal-body {
98 | position: relative;
99 | padding: @modal-inner-padding;
100 | }
101 |
102 | // Footer (for actions)
103 | .modal-footer {
104 | padding: @modal-inner-padding;
105 | text-align: right; // right align buttons
106 | border-top: 1px solid @modal-footer-border-color;
107 | &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons
108 |
109 | // Properly space out buttons
110 | .btn + .btn {
111 | margin-left: 5px;
112 | margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
113 | }
114 | // but override that for button groups
115 | .btn-group .btn + .btn {
116 | margin-left: -1px;
117 | }
118 | // and override it for block buttons as well
119 | .btn-block + .btn-block {
120 | margin-left: 0;
121 | }
122 | }
123 |
124 | // Measure scrollbar width for padding body during modal show/hide
125 | .modal-scrollbar-measure {
126 | position: absolute;
127 | top: -9999px;
128 | width: 50px;
129 | height: 50px;
130 | overflow: scroll;
131 | }
132 |
133 | // Scale up the modal
134 | @media (min-width: @screen-sm-min) {
135 | // Automatically set modal's width for larger viewports
136 | .modal-dialog {
137 | width: @modal-md;
138 | margin: 30px auto;
139 | }
140 | .modal-content {
141 | .box-shadow(0 5px 15px rgba(0,0,0,.5));
142 | }
143 |
144 | // Modal sizes
145 | .modal-sm { width: @modal-sm; }
146 | }
147 |
148 | @media (min-width: @screen-md-min) {
149 | .modal-lg { width: @modal-lg; }
150 | }
151 |
--------------------------------------------------------------------------------
/doc/bootstrap/buttons.less:
--------------------------------------------------------------------------------
1 | //
2 | // Buttons
3 | // --------------------------------------------------
4 |
5 |
6 | // Base styles
7 | // --------------------------------------------------
8 |
9 | .btn {
10 | display: inline-block;
11 | margin-bottom: 0; // For input.btn
12 | font-weight: @btn-font-weight;
13 | text-align: center;
14 | vertical-align: middle;
15 | touch-action: manipulation;
16 | cursor: pointer;
17 | background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
18 | border: 1px solid transparent;
19 | white-space: nowrap;
20 | .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);
21 | .user-select(none);
22 |
23 | &,
24 | &:active,
25 | &.active {
26 | &:focus,
27 | &.focus {
28 | .tab-focus();
29 | }
30 | }
31 |
32 | &:hover,
33 | &:focus,
34 | &.focus {
35 | color: @btn-default-color;
36 | text-decoration: none;
37 | }
38 |
39 | &:active,
40 | &.active {
41 | outline: 0;
42 | background-image: none;
43 | .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
44 | }
45 |
46 | &.disabled,
47 | &[disabled],
48 | fieldset[disabled] & {
49 | cursor: @cursor-disabled;
50 | pointer-events: none; // Future-proof disabling of clicks
51 | .opacity(.65);
52 | .box-shadow(none);
53 | }
54 | }
55 |
56 |
57 | // Alternate buttons
58 | // --------------------------------------------------
59 |
60 | .btn-default {
61 | .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);
62 | }
63 | .btn-primary {
64 | .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);
65 | }
66 | // Success appears as green
67 | .btn-success {
68 | .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);
69 | }
70 | // Info appears as blue-green
71 | .btn-info {
72 | .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);
73 | }
74 | // Warning appears as orange
75 | .btn-warning {
76 | .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);
77 | }
78 | // Danger and error appear as red
79 | .btn-danger {
80 | .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);
81 | }
82 |
83 |
84 | // Link buttons
85 | // -------------------------
86 |
87 | // Make a button look and behave like a link
88 | .btn-link {
89 | color: @link-color;
90 | font-weight: normal;
91 | border-radius: 0;
92 |
93 | &,
94 | &:active,
95 | &.active,
96 | &[disabled],
97 | fieldset[disabled] & {
98 | background-color: transparent;
99 | .box-shadow(none);
100 | }
101 | &,
102 | &:hover,
103 | &:focus,
104 | &:active {
105 | border-color: transparent;
106 | }
107 | &:hover,
108 | &:focus {
109 | color: @link-hover-color;
110 | text-decoration: @link-hover-decoration;
111 | background-color: transparent;
112 | }
113 | &[disabled],
114 | fieldset[disabled] & {
115 | &:hover,
116 | &:focus {
117 | color: @btn-link-disabled-color;
118 | text-decoration: none;
119 | }
120 | }
121 | }
122 |
123 |
124 | // Button Sizes
125 | // --------------------------------------------------
126 |
127 | .btn-lg {
128 | // line-height: ensure even-numbered height of button next to large input
129 | .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
130 | }
131 | .btn-sm {
132 | // line-height: ensure proper height of button next to small input
133 | .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
134 | }
135 | .btn-xs {
136 | .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);
137 | }
138 |
139 |
140 | // Block button
141 | // --------------------------------------------------
142 |
143 | .btn-block {
144 | display: block;
145 | width: 100%;
146 | }
147 |
148 | // Vertically space out multiple block buttons
149 | .btn-block + .btn-block {
150 | margin-top: 5px;
151 | }
152 |
153 | // Specificity overrides
154 | input[type="submit"],
155 | input[type="reset"],
156 | input[type="button"] {
157 | &.btn-block {
158 | width: 100%;
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/support/rst2md.py:
--------------------------------------------------------------------------------
1 | # reStructuredText (RST) to GitHub-flavored Markdown converter
2 |
3 | import re
4 | from docutils import core, nodes, writers
5 |
6 |
7 | def is_github_ref(node):
8 | return re.match('https://github.com/.*/(issues|pull)/.*', node['refuri'])
9 |
10 |
11 | class Translator(nodes.NodeVisitor):
12 | def __init__(self, document):
13 | nodes.NodeVisitor.__init__(self, document)
14 | self.output = ''
15 | self.indent = 0
16 | self.preserve_newlines = False
17 |
18 | def write(self, text):
19 | self.output += text.replace('\n', '\n' + ' ' * self.indent)
20 |
21 | def visit_document(self, node):
22 | pass
23 |
24 | def depart_document(self, node):
25 | pass
26 |
27 | def visit_section(self, node):
28 | pass
29 |
30 | def depart_section(self, node):
31 | # Skip all sections except the first one.
32 | raise nodes.StopTraversal
33 |
34 | def visit_title(self, node):
35 | self.version = re.match(r'(\d+\.\d+\.\d+).*', node.children[0]).group(1)
36 | raise nodes.SkipChildren
37 |
38 | def depart_title(self, node):
39 | pass
40 |
41 | def visit_Text(self, node):
42 | if not self.preserve_newlines:
43 | node = node.replace('\n', ' ')
44 | self.write(node)
45 |
46 | def depart_Text(self, node):
47 | pass
48 |
49 | def visit_bullet_list(self, node):
50 | pass
51 |
52 | def depart_bullet_list(self, node):
53 | pass
54 |
55 | def visit_list_item(self, node):
56 | self.write('* ')
57 | self.indent += 2
58 |
59 | def depart_list_item(self, node):
60 | self.indent -= 2
61 | self.write('\n\n')
62 |
63 | def visit_paragraph(self, node):
64 | pass
65 |
66 | def depart_paragraph(self, node):
67 | pass
68 |
69 | def visit_reference(self, node):
70 | if not is_github_ref(node):
71 | self.write('[')
72 |
73 | def depart_reference(self, node):
74 | if not is_github_ref(node):
75 | self.write('](' + node['refuri'] + ')')
76 |
77 | def visit_target(self, node):
78 | pass
79 |
80 | def depart_target(self, node):
81 | pass
82 |
83 | def visit_literal(self, node):
84 | self.write('`')
85 |
86 | def depart_literal(self, node):
87 | self.write('`')
88 |
89 | def visit_literal_block(self, node):
90 | self.write('\n\n```')
91 | if 'c++' in node['classes']:
92 | self.write('c++')
93 | self.write('\n')
94 | self.preserve_newlines = True
95 |
96 | def depart_literal_block(self, node):
97 | self.write('\n```\n')
98 | self.preserve_newlines = False
99 |
100 | def visit_inline(self, node):
101 | pass
102 |
103 | def depart_inline(self, node):
104 | pass
105 |
106 | def visit_image(self, node):
107 | self.write('')
108 |
109 | def depart_image(self, node):
110 | pass
111 |
112 | def write_row(self, row, widths):
113 | for i, entry in enumerate(row):
114 | text = entry[0][0] if len(entry) > 0 else ''
115 | if i != 0:
116 | self.write('|')
117 | self.write('{:{}}'.format(text, widths[i]))
118 | self.write('\n')
119 |
120 | def visit_table(self, node):
121 | table = node.children[0]
122 | colspecs = table[:-2]
123 | thead = table[-2]
124 | tbody = table[-1]
125 | widths = [int(cs['colwidth']) for cs in colspecs]
126 | sep = '|'.join(['-' * w for w in widths]) + '\n'
127 | self.write('\n\n')
128 | self.write_row(thead[0], widths)
129 | self.write(sep)
130 | for row in tbody:
131 | self.write_row(row, widths)
132 | raise nodes.SkipChildren
133 |
134 | def depart_table(self, node):
135 | pass
136 |
137 | class MDWriter(writers.Writer):
138 | """GitHub-flavored markdown writer"""
139 |
140 | supported = ('md',)
141 | """Formats this writer supports."""
142 |
143 | def translate(self):
144 | translator = Translator(self.document)
145 | self.document.walkabout(translator)
146 | self.output = (translator.output, translator.version)
147 |
148 |
149 | def convert(rst_path):
150 | """Converts RST file to Markdown."""
151 | return core.publish_file(source_path=rst_path, writer=MDWriter())
152 |
--------------------------------------------------------------------------------
/doc/bootstrap/mixins/gradients.less:
--------------------------------------------------------------------------------
1 | // Gradients
2 |
3 | #gradient {
4 |
5 | // Horizontal gradient, from left to right
6 | //
7 | // Creates two color stops, start and end, by specifying a color and position for each color stop.
8 | // Color stops are not available in IE9 and below.
9 | .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
10 | background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+
11 | background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12
12 | background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
13 | background-repeat: repeat-x;
14 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down
15 | }
16 |
17 | // Vertical gradient, from top to bottom
18 | //
19 | // Creates two color stops, start and end, by specifying a color and position for each color stop.
20 | // Color stops are not available in IE9 and below.
21 | .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
22 | background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+
23 | background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12
24 | background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
25 | background-repeat: repeat-x;
26 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down
27 | }
28 |
29 | .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {
30 | background-repeat: repeat-x;
31 | background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+
32 | background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12
33 | background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
34 | }
35 | .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
36 | background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
37 | background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
38 | background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);
39 | background-repeat: no-repeat;
40 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
41 | }
42 | .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
43 | background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);
44 | background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);
45 | background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);
46 | background-repeat: no-repeat;
47 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
48 | }
49 | .radial(@inner-color: #555; @outer-color: #333) {
50 | background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);
51 | background-image: radial-gradient(circle, @inner-color, @outer-color);
52 | background-repeat: no-repeat;
53 | }
54 | .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {
55 | background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
56 | background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
57 | background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/support/travis-build.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # Build the project on Travis CI.
3 |
4 | from __future__ import print_function
5 | import errno, os, shutil, subprocess, sys, urllib
6 | from subprocess import call, check_call, Popen, PIPE, STDOUT
7 |
8 | def rmtree_if_exists(dir):
9 | try:
10 | shutil.rmtree(dir)
11 | except OSError as e:
12 | if e.errno == errno.ENOENT:
13 | pass
14 |
15 | def makedirs_if_not_exist(dir):
16 | try:
17 | os.makedirs(dir)
18 | except OSError as e:
19 | if e.errno != errno.EEXIST:
20 | raise
21 |
22 | def install_dependencies():
23 | branch = os.environ['TRAVIS_BRANCH']
24 | if branch != 'master':
25 | print('Branch: ' + branch)
26 | exit(0) # Ignore non-master branches
27 | check_call('curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key ' +
28 | '| sudo apt-key add -', shell=True)
29 | check_call('echo "deb https://deb.nodesource.com/node_0.10 precise main" ' +
30 | '| sudo tee /etc/apt/sources.list.d/nodesource.list', shell=True)
31 | check_call(['sudo', 'apt-get', 'update'])
32 | check_call(['sudo', 'apt-get', 'install', 'python-virtualenv', 'nodejs'])
33 | check_call(['sudo', 'npm', 'install', '-g', 'less@2.6.1', 'less-plugin-clean-css'])
34 | deb_file = 'doxygen_1.8.6-2_amd64.deb'
35 | urllib.urlretrieve('http://mirrors.kernel.org/ubuntu/pool/main/d/doxygen/' +
36 | deb_file, deb_file)
37 | check_call(['sudo', 'dpkg', '-i', deb_file])
38 |
39 | fmt_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
40 |
41 | build = os.environ['BUILD']
42 | if build == 'Doc':
43 | travis = 'TRAVIS' in os.environ
44 | if travis:
45 | install_dependencies()
46 | sys.path.insert(0, os.path.join(fmt_dir, 'doc'))
47 | import build
48 | build.create_build_env()
49 | html_dir = build.build_docs()
50 | repo = 'fmtlib.github.io'
51 | if travis and 'KEY' not in os.environ:
52 | # Don't update the repo if building on Travis from an account that
53 | # doesn't have push access.
54 | print('Skipping update of ' + repo)
55 | exit(0)
56 | # Clone the fmtlib.github.io repo.
57 | rmtree_if_exists(repo)
58 | git_url = 'https://github.com/' if travis else 'git@github.com:'
59 | check_call(['git', 'clone', git_url + 'fmtlib/{}.git'.format(repo)])
60 | # Copy docs to the repo.
61 | target_dir = os.path.join(repo, 'dev')
62 | rmtree_if_exists(target_dir)
63 | shutil.copytree(html_dir, target_dir, ignore=shutil.ignore_patterns('.*'))
64 | if travis:
65 | check_call(['git', 'config', '--global', 'user.name', 'amplbot'])
66 | check_call(['git', 'config', '--global', 'user.email', 'viz@ampl.com'])
67 | # Push docs to GitHub pages.
68 | check_call(['git', 'add', '--all'], cwd=repo)
69 | if call(['git', 'diff-index', '--quiet', 'HEAD'], cwd=repo):
70 | check_call(['git', 'commit', '-m', 'Update documentation'], cwd=repo)
71 | cmd = 'git push'
72 | if travis:
73 | cmd += ' https://$KEY@github.com/fmtlib/fmtlib.github.io.git master'
74 | p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=repo)
75 | # Print the output without the key.
76 | print(p.communicate()[0].replace(os.environ['KEY'], '$KEY'))
77 | if p.returncode != 0:
78 | raise subprocess.CalledProcessError(p.returncode, cmd)
79 | exit(0)
80 |
81 | standard = os.environ['STANDARD']
82 | install_dir = os.path.join(fmt_dir, "_install")
83 | build_dir = os.path.join(fmt_dir, "_build")
84 | test_build_dir = os.path.join(fmt_dir, "_build_test")
85 |
86 | # Configure library.
87 | makedirs_if_not_exist(build_dir)
88 | cmake_flags = [
89 | '-DCMAKE_INSTALL_PREFIX=' + install_dir, '-DCMAKE_BUILD_TYPE=' + build,
90 | '-DCMAKE_CXX_STANDARD=' + standard
91 | ]
92 | check_call(['cmake', '-DFMT_DOC=OFF', '-DFMT_PEDANTIC=ON', '-DFMT_WERROR=ON', fmt_dir] +
93 | cmake_flags, cwd=build_dir)
94 |
95 | # Build library.
96 | check_call(['make', '-j4'], cwd=build_dir)
97 |
98 | # Test library.
99 | env = os.environ.copy()
100 | env['CTEST_OUTPUT_ON_FAILURE'] = '1'
101 | if call(['make', 'test'], env=env, cwd=build_dir):
102 | with open(os.path.join(build_dir, 'Testing', 'Temporary', 'LastTest.log'), 'r') as f:
103 | print(f.read())
104 | sys.exit(-1)
105 |
106 | # Install library.
107 | check_call(['make', 'install'], cwd=build_dir)
108 |
109 | # Test installation.
110 | makedirs_if_not_exist(test_build_dir)
111 | check_call(['cmake', os.path.join(fmt_dir, "test", "find-package-test")] +
112 | cmake_flags, cwd=test_build_dir)
113 | check_call(['make', '-j4'], cwd=test_build_dir)
114 |
--------------------------------------------------------------------------------
/doc/bootstrap/input-groups.less:
--------------------------------------------------------------------------------
1 | //
2 | // Input groups
3 | // --------------------------------------------------
4 |
5 | // Base styles
6 | // -------------------------
7 | .input-group {
8 | position: relative; // For dropdowns
9 | display: table;
10 | border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table
11 |
12 | // Undo padding and float of grid classes
13 | &[class*="col-"] {
14 | float: none;
15 | padding-left: 0;
16 | padding-right: 0;
17 | }
18 |
19 | .form-control {
20 | // Ensure that the input is always above the *appended* addon button for
21 | // proper border colors.
22 | position: relative;
23 | z-index: 2;
24 |
25 | // IE9 fubars the placeholder attribute in text inputs and the arrows on
26 | // select elements in input groups. To fix it, we float the input. Details:
27 | // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855
28 | float: left;
29 |
30 | width: 100%;
31 | margin-bottom: 0;
32 | }
33 | }
34 |
35 | // Sizing options
36 | //
37 | // Remix the default form control sizing classes into new ones for easier
38 | // manipulation.
39 |
40 | .input-group-lg > .form-control,
41 | .input-group-lg > .input-group-addon,
42 | .input-group-lg > .input-group-btn > .btn {
43 | .input-lg();
44 | }
45 | .input-group-sm > .form-control,
46 | .input-group-sm > .input-group-addon,
47 | .input-group-sm > .input-group-btn > .btn {
48 | .input-sm();
49 | }
50 |
51 |
52 | // Display as table-cell
53 | // -------------------------
54 | .input-group-addon,
55 | .input-group-btn,
56 | .input-group .form-control {
57 | display: table-cell;
58 |
59 | &:not(:first-child):not(:last-child) {
60 | border-radius: 0;
61 | }
62 | }
63 | // Addon and addon wrapper for buttons
64 | .input-group-addon,
65 | .input-group-btn {
66 | width: 1%;
67 | white-space: nowrap;
68 | vertical-align: middle; // Match the inputs
69 | }
70 |
71 | // Text input groups
72 | // -------------------------
73 | .input-group-addon {
74 | padding: @padding-base-vertical @padding-base-horizontal;
75 | font-size: @font-size-base;
76 | font-weight: normal;
77 | line-height: 1;
78 | color: @input-color;
79 | text-align: center;
80 | background-color: @input-group-addon-bg;
81 | border: 1px solid @input-group-addon-border-color;
82 | border-radius: @border-radius-base;
83 |
84 | // Sizing
85 | &.input-sm {
86 | padding: @padding-small-vertical @padding-small-horizontal;
87 | font-size: @font-size-small;
88 | border-radius: @border-radius-small;
89 | }
90 | &.input-lg {
91 | padding: @padding-large-vertical @padding-large-horizontal;
92 | font-size: @font-size-large;
93 | border-radius: @border-radius-large;
94 | }
95 |
96 | // Nuke default margins from checkboxes and radios to vertically center within.
97 | input[type="radio"],
98 | input[type="checkbox"] {
99 | margin-top: 0;
100 | }
101 | }
102 |
103 | // Reset rounded corners
104 | .input-group .form-control:first-child,
105 | .input-group-addon:first-child,
106 | .input-group-btn:first-child > .btn,
107 | .input-group-btn:first-child > .btn-group > .btn,
108 | .input-group-btn:first-child > .dropdown-toggle,
109 | .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
110 | .input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
111 | .border-right-radius(0);
112 | }
113 | .input-group-addon:first-child {
114 | border-right: 0;
115 | }
116 | .input-group .form-control:last-child,
117 | .input-group-addon:last-child,
118 | .input-group-btn:last-child > .btn,
119 | .input-group-btn:last-child > .btn-group > .btn,
120 | .input-group-btn:last-child > .dropdown-toggle,
121 | .input-group-btn:first-child > .btn:not(:first-child),
122 | .input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
123 | .border-left-radius(0);
124 | }
125 | .input-group-addon:last-child {
126 | border-left: 0;
127 | }
128 |
129 | // Button input groups
130 | // -------------------------
131 | .input-group-btn {
132 | position: relative;
133 | // Jankily prevent input button groups from wrapping with `white-space` and
134 | // `font-size` in combination with `inline-block` on buttons.
135 | font-size: 0;
136 | white-space: nowrap;
137 |
138 | // Negative margin for spacing, position for bringing hovered/focused/actived
139 | // element above the siblings.
140 | > .btn {
141 | position: relative;
142 | + .btn {
143 | margin-left: -1px;
144 | }
145 | // Bring the "active" button to the front
146 | &:hover,
147 | &:focus,
148 | &:active {
149 | z-index: 2;
150 | }
151 | }
152 |
153 | // Negative margin to only have a 1px border between the two
154 | &:first-child {
155 | > .btn,
156 | > .btn-group {
157 | margin-right: -1px;
158 | }
159 | }
160 | &:last-child {
161 | > .btn,
162 | > .btn-group {
163 | margin-left: -1px;
164 | }
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/include/fmt/time.h:
--------------------------------------------------------------------------------
1 | // Formatting library for C++ - time formatting
2 | //
3 | // Copyright (c) 2012 - 2016, Victor Zverovich
4 | // All rights reserved.
5 | //
6 | // For the license information refer to format.h.
7 |
8 | #ifndef FMT_TIME_H_
9 | #define FMT_TIME_H_
10 |
11 | #include "format.h"
12 | #include
13 |
14 | FMT_BEGIN_NAMESPACE
15 |
16 | // Prevents expansion of a preceding token as a function-style macro.
17 | // Usage: f FMT_NOMACRO()
18 | #define FMT_NOMACRO
19 |
20 | namespace internal{
21 | inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); }
22 | inline null<> localtime_s(...) { return null<>(); }
23 | inline null<> gmtime_r(...) { return null<>(); }
24 | inline null<> gmtime_s(...) { return null<>(); }
25 | }
26 |
27 | // Thread-safe replacement for std::localtime
28 | inline std::tm localtime(std::time_t time) {
29 | struct dispatcher {
30 | std::time_t time_;
31 | std::tm tm_;
32 |
33 | dispatcher(std::time_t t): time_(t) {}
34 |
35 | bool run() {
36 | using namespace fmt::internal;
37 | return handle(localtime_r(&time_, &tm_));
38 | }
39 |
40 | bool handle(std::tm *tm) { return tm != FMT_NULL; }
41 |
42 | bool handle(internal::null<>) {
43 | using namespace fmt::internal;
44 | return fallback(localtime_s(&tm_, &time_));
45 | }
46 |
47 | bool fallback(int res) { return res == 0; }
48 |
49 | bool fallback(internal::null<>) {
50 | using namespace fmt::internal;
51 | std::tm *tm = std::localtime(&time_);
52 | if (tm) tm_ = *tm;
53 | return tm != FMT_NULL;
54 | }
55 | };
56 | dispatcher lt(time);
57 | if (lt.run())
58 | return lt.tm_;
59 | // Too big time values may be unsupported.
60 | FMT_THROW(format_error("time_t value out of range"));
61 | return {};
62 | }
63 |
64 | // Thread-safe replacement for std::gmtime
65 | inline std::tm gmtime(std::time_t time) {
66 | struct dispatcher {
67 | std::time_t time_;
68 | std::tm tm_;
69 |
70 | dispatcher(std::time_t t): time_(t) {}
71 |
72 | bool run() {
73 | using namespace fmt::internal;
74 | return handle(gmtime_r(&time_, &tm_));
75 | }
76 |
77 | bool handle(std::tm *tm) { return tm != FMT_NULL; }
78 |
79 | bool handle(internal::null<>) {
80 | using namespace fmt::internal;
81 | return fallback(gmtime_s(&tm_, &time_));
82 | }
83 |
84 | bool fallback(int res) { return res == 0; }
85 |
86 | bool fallback(internal::null<>) {
87 | std::tm *tm = std::gmtime(&time_);
88 | if (tm) tm_ = *tm;
89 | return tm != FMT_NULL;
90 | }
91 | };
92 | dispatcher gt(time);
93 | if (gt.run())
94 | return gt.tm_;
95 | // Too big time values may be unsupported.
96 | FMT_THROW(format_error("time_t value out of range"));
97 | return {};
98 | }
99 |
100 | namespace internal {
101 | inline std::size_t strftime(char *str, std::size_t count, const char *format,
102 | const std::tm *time) {
103 | return std::strftime(str, count, format, time);
104 | }
105 |
106 | inline std::size_t strftime(wchar_t *str, std::size_t count,
107 | const wchar_t *format, const std::tm *time) {
108 | return std::wcsftime(str, count, format, time);
109 | }
110 | }
111 |
112 | template
113 | struct formatter {
114 | template
115 | auto parse(ParseContext &ctx) -> decltype(ctx.begin()) {
116 | auto it = internal::null_terminating_iterator(ctx);
117 | if (*it == ':')
118 | ++it;
119 | auto end = it;
120 | while (*end && *end != '}')
121 | ++end;
122 | tm_format.reserve(end - it + 1);
123 | using internal::pointer_from;
124 | tm_format.append(pointer_from(it), pointer_from(end));
125 | tm_format.push_back('\0');
126 | return pointer_from(end);
127 | }
128 |
129 | template
130 | auto format(const std::tm &tm, FormatContext &ctx) -> decltype(ctx.out()) {
131 | internal::basic_buffer &buf = internal::get_container(ctx.out());
132 | std::size_t start = buf.size();
133 | for (;;) {
134 | std::size_t size = buf.capacity() - start;
135 | std::size_t count =
136 | internal::strftime(&buf[start], size, &tm_format[0], &tm);
137 | if (count != 0) {
138 | buf.resize(start + count);
139 | break;
140 | }
141 | if (size >= tm_format.size() * 256) {
142 | // If the buffer is 256 times larger than the format string, assume
143 | // that `strftime` gives an empty result. There doesn't seem to be a
144 | // better way to distinguish the two cases:
145 | // https://github.com/fmtlib/fmt/issues/367
146 | break;
147 | }
148 | const std::size_t MIN_GROWTH = 10;
149 | buf.reserve(buf.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH));
150 | }
151 | return ctx.out();
152 | }
153 |
154 | basic_memory_buffer tm_format;
155 | };
156 | FMT_END_NAMESPACE
157 |
158 | #endif // FMT_TIME_H_
159 |
--------------------------------------------------------------------------------
/doc/bootstrap/responsive-utilities.less:
--------------------------------------------------------------------------------
1 | //
2 | // Responsive: Utility classes
3 | // --------------------------------------------------
4 |
5 |
6 | // IE10 in Windows (Phone) 8
7 | //
8 | // Support for responsive views via media queries is kind of borked in IE10, for
9 | // Surface/desktop in split view and for Windows Phone 8. This particular fix
10 | // must be accompanied by a snippet of JavaScript to sniff the user agent and
11 | // apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at
12 | // our Getting Started page for more information on this bug.
13 | //
14 | // For more information, see the following:
15 | //
16 | // Issue: https://github.com/twbs/bootstrap/issues/10497
17 | // Docs: http://getbootstrap.com/getting-started/#support-ie10-width
18 | // Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/
19 | // Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/
20 |
21 | @-ms-viewport {
22 | width: device-width;
23 | }
24 |
25 |
26 | // Visibility utilities
27 | // Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0
28 | .visible-xs,
29 | .visible-sm,
30 | .visible-md,
31 | .visible-lg {
32 | .responsive-invisibility();
33 | }
34 |
35 | .visible-xs-block,
36 | .visible-xs-inline,
37 | .visible-xs-inline-block,
38 | .visible-sm-block,
39 | .visible-sm-inline,
40 | .visible-sm-inline-block,
41 | .visible-md-block,
42 | .visible-md-inline,
43 | .visible-md-inline-block,
44 | .visible-lg-block,
45 | .visible-lg-inline,
46 | .visible-lg-inline-block {
47 | display: none !important;
48 | }
49 |
50 | .visible-xs {
51 | @media (max-width: @screen-xs-max) {
52 | .responsive-visibility();
53 | }
54 | }
55 | .visible-xs-block {
56 | @media (max-width: @screen-xs-max) {
57 | display: block !important;
58 | }
59 | }
60 | .visible-xs-inline {
61 | @media (max-width: @screen-xs-max) {
62 | display: inline !important;
63 | }
64 | }
65 | .visible-xs-inline-block {
66 | @media (max-width: @screen-xs-max) {
67 | display: inline-block !important;
68 | }
69 | }
70 |
71 | .visible-sm {
72 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
73 | .responsive-visibility();
74 | }
75 | }
76 | .visible-sm-block {
77 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
78 | display: block !important;
79 | }
80 | }
81 | .visible-sm-inline {
82 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
83 | display: inline !important;
84 | }
85 | }
86 | .visible-sm-inline-block {
87 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
88 | display: inline-block !important;
89 | }
90 | }
91 |
92 | .visible-md {
93 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
94 | .responsive-visibility();
95 | }
96 | }
97 | .visible-md-block {
98 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
99 | display: block !important;
100 | }
101 | }
102 | .visible-md-inline {
103 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
104 | display: inline !important;
105 | }
106 | }
107 | .visible-md-inline-block {
108 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
109 | display: inline-block !important;
110 | }
111 | }
112 |
113 | .visible-lg {
114 | @media (min-width: @screen-lg-min) {
115 | .responsive-visibility();
116 | }
117 | }
118 | .visible-lg-block {
119 | @media (min-width: @screen-lg-min) {
120 | display: block !important;
121 | }
122 | }
123 | .visible-lg-inline {
124 | @media (min-width: @screen-lg-min) {
125 | display: inline !important;
126 | }
127 | }
128 | .visible-lg-inline-block {
129 | @media (min-width: @screen-lg-min) {
130 | display: inline-block !important;
131 | }
132 | }
133 |
134 | .hidden-xs {
135 | @media (max-width: @screen-xs-max) {
136 | .responsive-invisibility();
137 | }
138 | }
139 | .hidden-sm {
140 | @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
141 | .responsive-invisibility();
142 | }
143 | }
144 | .hidden-md {
145 | @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
146 | .responsive-invisibility();
147 | }
148 | }
149 | .hidden-lg {
150 | @media (min-width: @screen-lg-min) {
151 | .responsive-invisibility();
152 | }
153 | }
154 |
155 |
156 | // Print utilities
157 | //
158 | // Media queries are placed on the inside to be mixin-friendly.
159 |
160 | // Note: Deprecated .visible-print as of v3.2.0
161 | .visible-print {
162 | .responsive-invisibility();
163 |
164 | @media print {
165 | .responsive-visibility();
166 | }
167 | }
168 | .visible-print-block {
169 | display: none !important;
170 |
171 | @media print {
172 | display: block !important;
173 | }
174 | }
175 | .visible-print-inline {
176 | display: none !important;
177 |
178 | @media print {
179 | display: inline !important;
180 | }
181 | }
182 | .visible-print-inline-block {
183 | display: none !important;
184 |
185 | @media print {
186 | display: inline-block !important;
187 | }
188 | }
189 |
190 | .hidden-print {
191 | @media print {
192 | .responsive-invisibility();
193 | }
194 | }
195 |
--------------------------------------------------------------------------------
/include/fmt/ostream.h:
--------------------------------------------------------------------------------
1 | // Formatting library for C++ - std::ostream support
2 | //
3 | // Copyright (c) 2012 - 2016, Victor Zverovich
4 | // All rights reserved.
5 | //
6 | // For the license information refer to format.h.
7 |
8 | #ifndef FMT_OSTREAM_H_
9 | #define FMT_OSTREAM_H_
10 |
11 | #include "format.h"
12 | #include
13 |
14 | FMT_BEGIN_NAMESPACE
15 | namespace internal {
16 |
17 | template
18 | class formatbuf : public std::basic_streambuf {
19 | private:
20 | typedef typename std::basic_streambuf::int_type int_type;
21 | typedef typename std::basic_streambuf::traits_type traits_type;
22 |
23 | basic_buffer &buffer_;
24 |
25 | public:
26 | formatbuf(basic_buffer &buffer) : buffer_(buffer) {}
27 |
28 | protected:
29 | // The put-area is actually always empty. This makes the implementation
30 | // simpler and has the advantage that the streambuf and the buffer are always
31 | // in sync and sputc never writes into uninitialized memory. The obvious
32 | // disadvantage is that each call to sputc always results in a (virtual) call
33 | // to overflow. There is no disadvantage here for sputn since this always
34 | // results in a call to xsputn.
35 |
36 | int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
37 | if (!traits_type::eq_int_type(ch, traits_type::eof()))
38 | buffer_.push_back(static_cast(ch));
39 | return ch;
40 | }
41 |
42 | std::streamsize xsputn(const Char *s, std::streamsize count) FMT_OVERRIDE {
43 | buffer_.append(s, s + count);
44 | return count;
45 | }
46 | };
47 |
48 | template
49 | struct test_stream : std::basic_ostream {
50 | private:
51 | struct null;
52 | // Hide all operator<< from std::basic_ostream.
53 | void operator<<(null);
54 | };
55 |
56 | // Checks if T has a user-defined operator<< (e.g. not a member of std::ostream).
57 | template
58 | class is_streamable {
59 | private:
60 | template
61 | static decltype(
62 | internal::declval&>()
63 | << internal::declval(), std::true_type()) test(int);
64 |
65 | template
66 | static std::false_type test(...);
67 |
68 | typedef decltype(test(0)) result;
69 |
70 | public:
71 | static const bool value = result::value;
72 | };
73 |
74 | // Write the content of buf to os.
75 | template
76 | void write(std::basic_ostream &os, basic_buffer &buf) {
77 | const Char *data = buf.data();
78 | typedef std::make_unsigned::type UnsignedStreamSize;
79 | UnsignedStreamSize size = buf.size();
80 | UnsignedStreamSize max_size =
81 | internal::to_unsigned((std::numeric_limits::max)());
82 | do {
83 | UnsignedStreamSize n = size <= max_size ? size : max_size;
84 | os.write(data, static_cast(n));
85 | data += n;
86 | size -= n;
87 | } while (size != 0);
88 | }
89 |
90 | template
91 | void format_value(basic_buffer &buffer, const T &value) {
92 | internal::formatbuf format_buf(buffer);
93 | std::basic_ostream output(&format_buf);
94 | output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
95 | output << value;
96 | buffer.resize(buffer.size());
97 | }
98 | } // namespace internal
99 |
100 | // Disable conversion to int if T has an overloaded operator<< which is a free
101 | // function (not a member of std::ostream).
102 | template
103 | struct convert_to_int {
104 | static const bool value =
105 | convert_to_int::value &&
106 | !internal::is_streamable::value;
107 | };
108 |
109 | // Formats an object of type T that has an overloaded ostream operator<<.
110 | template
111 | struct formatter::value &&
114 | !internal::format_type<
115 | typename buffer_context::type, T>::value>::type>
116 | : formatter, Char> {
117 |
118 | template
119 | auto format(const T &value, Context &ctx) -> decltype(ctx.out()) {
120 | basic_memory_buffer buffer;
121 | internal::format_value(buffer, value);
122 | basic_string_view str(buffer.data(), buffer.size());
123 | return formatter, Char>::format(str, ctx);
124 | }
125 | };
126 |
127 | template
128 | inline void vprint(std::basic_ostream &os,
129 | basic_string_view format_str,
130 | basic_format_args::type> args) {
131 | basic_memory_buffer buffer;
132 | vformat_to(buffer, format_str, args);
133 | internal::write(os, buffer);
134 | }
135 | /**
136 | \rst
137 | Prints formatted data to the stream *os*.
138 |
139 | **Example**::
140 |
141 | fmt::print(cerr, "Don't {}!", "panic");
142 | \endrst
143 | */
144 | template
145 | inline typename std::enable_if::value>::type
146 | print(std::basic_ostream &os, const S &format_str,
147 | const Args & ... args) {
148 | internal::checked_args ca(format_str, args...);
149 | vprint(os, internal::to_string_view(format_str), *ca);
150 | }
151 | FMT_END_NAMESPACE
152 |
153 | #endif // FMT_OSTREAM_H_
154 |
--------------------------------------------------------------------------------
/doc/build.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # Build the documentation.
3 |
4 | from __future__ import print_function
5 | import errno, os, shutil, sys, tempfile
6 | from subprocess import check_call, check_output, CalledProcessError, Popen, PIPE
7 | from distutils.version import LooseVersion
8 |
9 | versions = ['1.0.0', '1.1.0', '2.0.0', '3.0.2', '4.0.0', '4.1.0', '5.0.0', '5.1.0', '5.2.0', '5.2.1']
10 |
11 | def pip_install(package, commit=None, **kwargs):
12 | "Install package using pip."
13 | min_version = kwargs.get('min_version')
14 | if min_version:
15 | from pkg_resources import get_distribution, DistributionNotFound
16 | try:
17 | installed_version = get_distribution(os.path.basename(package)).version
18 | if LooseVersion(installed_version) >= min_version:
19 | print('{} {} already installed'.format(package, min_version))
20 | return
21 | except DistributionNotFound:
22 | pass
23 | if commit:
24 | package = 'git+https://github.com/{0}.git@{1}'.format(package, commit)
25 | print('Installing {0}'.format(package))
26 | check_call(['pip', 'install', package])
27 |
28 | def create_build_env(dirname='virtualenv'):
29 | # Create virtualenv.
30 | if not os.path.exists(dirname):
31 | check_call(['virtualenv', dirname])
32 | import sysconfig
33 | scripts_dir = os.path.basename(sysconfig.get_path('scripts'))
34 | activate_this_file = os.path.join(dirname, scripts_dir, 'activate_this.py')
35 | with open(activate_this_file) as f:
36 | exec(f.read(), dict(__file__=activate_this_file))
37 | # Import get_distribution after activating virtualenv to get info about
38 | # the correct packages.
39 | from pkg_resources import get_distribution, DistributionNotFound
40 | # Upgrade pip because installation of sphinx with pip 1.1 available on Travis
41 | # is broken (see #207) and it doesn't support the show command.
42 | pip_version = get_distribution('pip').version
43 | if LooseVersion(pip_version) < LooseVersion('1.5.4'):
44 | print("Updating pip")
45 | check_call(['pip', 'install', '--upgrade', 'pip'])
46 | # Upgrade distribute because installation of sphinx with distribute 0.6.24
47 | # available on Travis is broken (see #207).
48 | try:
49 | distribute_version = get_distribution('distribute').version
50 | if LooseVersion(distribute_version) <= LooseVersion('0.6.24'):
51 | print("Updating distribute")
52 | check_call(['pip', 'install', '--upgrade', 'distribute'])
53 | except DistributionNotFound:
54 | pass
55 | # Install Sphinx and Breathe.
56 | pip_install('sphinx-doc/sphinx', '12b83372ac9316e8cbe86e7fed889296a4cc29ee',
57 | min_version='1.4.1.dev20160531')
58 | pip_install('michaeljones/breathe',
59 | '129222318f7c8f865d2631e7da7b033567e7f56a',
60 | min_version='4.2.0')
61 |
62 | def build_docs(version='dev', **kwargs):
63 | doc_dir = kwargs.get('doc_dir', os.path.dirname(os.path.realpath(__file__)))
64 | work_dir = kwargs.get('work_dir', '.')
65 | include_dir = kwargs.get(
66 | 'include_dir', os.path.join(os.path.dirname(doc_dir), 'include', 'fmt'))
67 | # Build docs.
68 | cmd = ['doxygen', '-']
69 | p = Popen(cmd, stdin=PIPE)
70 | doxyxml_dir = os.path.join(work_dir, 'doxyxml')
71 | p.communicate(input=r'''
72 | PROJECT_NAME = fmt
73 | GENERATE_LATEX = NO
74 | GENERATE_MAN = NO
75 | GENERATE_RTF = NO
76 | CASE_SENSE_NAMES = NO
77 | INPUT = {0}/core.h {0}/format.h {0}/ostream.h \
78 | {0}/printf.h {0}/time.h
79 | QUIET = YES
80 | JAVADOC_AUTOBRIEF = YES
81 | AUTOLINK_SUPPORT = NO
82 | GENERATE_HTML = NO
83 | GENERATE_XML = YES
84 | XML_OUTPUT = {1}
85 | ALIASES = "rst=\verbatim embed:rst"
86 | ALIASES += "endrst=\endverbatim"
87 | MACRO_EXPANSION = YES
88 | PREDEFINED = _WIN32=1 \
89 | FMT_USE_VARIADIC_TEMPLATES=1 \
90 | FMT_USE_RVALUE_REFERENCES=1 \
91 | FMT_USE_USER_DEFINED_LITERALS=1 \
92 | FMT_USE_ALIAS_TEMPLATES=1 \
93 | FMT_API= \
94 | "FMT_BEGIN_NAMESPACE=namespace fmt {{" \
95 | "FMT_END_NAMESPACE=}}" \
96 | "FMT_STRING_ALIAS=1"
97 | EXCLUDE_SYMBOLS = fmt::internal::* StringValue write_str
98 | '''.format(include_dir, doxyxml_dir).encode('UTF-8'))
99 | if p.returncode != 0:
100 | raise CalledProcessError(p.returncode, cmd)
101 | html_dir = os.path.join(work_dir, 'html')
102 | main_versions = reversed(versions[-3:])
103 | sphinx_build = os.environ.get('SPHINX_EXECUTABLE', 'sphinx-build')
104 | check_call([sphinx_build,
105 | '-Dbreathe_projects.format=' + os.path.abspath(doxyxml_dir),
106 | '-Dversion=' + version, '-Drelease=' + version,
107 | '-Aversion=' + version, '-Aversions=' + ','.join(main_versions),
108 | '-b', 'html', doc_dir, html_dir])
109 | try:
110 | check_call(['lessc', '--clean-css',
111 | '--include-path=' + os.path.join(doc_dir, 'bootstrap'),
112 | os.path.join(doc_dir, 'fmt.less'),
113 | os.path.join(html_dir, '_static', 'fmt.css')])
114 | except OSError as e:
115 | if e.errno != errno.ENOENT:
116 | raise
117 | print('lessc not found; make sure that Less (http://lesscss.org/) ' +
118 | 'is installed')
119 | sys.exit(1)
120 | return html_dir
121 |
122 | if __name__ == '__main__':
123 | create_build_env()
124 | build_docs(sys.argv[1])
125 |
--------------------------------------------------------------------------------
/doc/bootstrap/tables.less:
--------------------------------------------------------------------------------
1 | //
2 | // Tables
3 | // --------------------------------------------------
4 |
5 |
6 | table {
7 | background-color: @table-bg;
8 | }
9 | caption {
10 | padding-top: @table-cell-padding;
11 | padding-bottom: @table-cell-padding;
12 | color: @text-muted;
13 | text-align: left;
14 | }
15 | th {
16 | text-align: left;
17 | }
18 |
19 |
20 | // Baseline styles
21 |
22 | .table {
23 | width: 100%;
24 | max-width: 100%;
25 | margin-bottom: @line-height-computed;
26 | // Cells
27 | > thead,
28 | > tbody,
29 | > tfoot {
30 | > tr {
31 | > th,
32 | > td {
33 | padding: @table-cell-padding;
34 | line-height: @line-height-base;
35 | vertical-align: top;
36 | border-top: 1px solid @table-border-color;
37 | }
38 | }
39 | }
40 | // Bottom align for column headings
41 | > thead > tr > th {
42 | vertical-align: bottom;
43 | border-bottom: 2px solid @table-border-color;
44 | }
45 | // Remove top border from thead by default
46 | > caption + thead,
47 | > colgroup + thead,
48 | > thead:first-child {
49 | > tr:first-child {
50 | > th,
51 | > td {
52 | border-top: 0;
53 | }
54 | }
55 | }
56 | // Account for multiple tbody instances
57 | > tbody + tbody {
58 | border-top: 2px solid @table-border-color;
59 | }
60 |
61 | // Nesting
62 | .table {
63 | background-color: @body-bg;
64 | }
65 | }
66 |
67 |
68 | // Condensed table w/ half padding
69 |
70 | .table-condensed {
71 | > thead,
72 | > tbody,
73 | > tfoot {
74 | > tr {
75 | > th,
76 | > td {
77 | padding: @table-condensed-cell-padding;
78 | }
79 | }
80 | }
81 | }
82 |
83 |
84 | // Bordered version
85 | //
86 | // Add borders all around the table and between all the columns.
87 |
88 | .table-bordered {
89 | border: 1px solid @table-border-color;
90 | > thead,
91 | > tbody,
92 | > tfoot {
93 | > tr {
94 | > th,
95 | > td {
96 | border: 1px solid @table-border-color;
97 | }
98 | }
99 | }
100 | > thead > tr {
101 | > th,
102 | > td {
103 | border-bottom-width: 2px;
104 | }
105 | }
106 | }
107 |
108 |
109 | // Zebra-striping
110 | //
111 | // Default zebra-stripe styles (alternating gray and transparent backgrounds)
112 |
113 | .table-striped {
114 | > tbody > tr:nth-of-type(odd) {
115 | background-color: @table-bg-accent;
116 | }
117 | }
118 |
119 |
120 | // Hover effect
121 | //
122 | // Placed here since it has to come after the potential zebra striping
123 |
124 | .table-hover {
125 | > tbody > tr:hover {
126 | background-color: @table-bg-hover;
127 | }
128 | }
129 |
130 |
131 | // Table cell sizing
132 | //
133 | // Reset default table behavior
134 |
135 | table col[class*="col-"] {
136 | position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)
137 | float: none;
138 | display: table-column;
139 | }
140 | table {
141 | td,
142 | th {
143 | &[class*="col-"] {
144 | position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)
145 | float: none;
146 | display: table-cell;
147 | }
148 | }
149 | }
150 |
151 |
152 | // Table backgrounds
153 | //
154 | // Exact selectors below required to override `.table-striped` and prevent
155 | // inheritance to nested tables.
156 |
157 | // Generate the contextual variants
158 | .table-row-variant(active; @table-bg-active);
159 | .table-row-variant(success; @state-success-bg);
160 | .table-row-variant(info; @state-info-bg);
161 | .table-row-variant(warning; @state-warning-bg);
162 | .table-row-variant(danger; @state-danger-bg);
163 |
164 |
165 | // Responsive tables
166 | //
167 | // Wrap your tables in `.table-responsive` and we'll make them mobile friendly
168 | // by enabling horizontal scrolling. Only applies <768px. Everything above that
169 | // will display normally.
170 |
171 | .table-responsive {
172 | overflow-x: auto;
173 | min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)
174 |
175 | @media screen and (max-width: @screen-xs-max) {
176 | width: 100%;
177 | margin-bottom: (@line-height-computed * 0.75);
178 | overflow-y: hidden;
179 | -ms-overflow-style: -ms-autohiding-scrollbar;
180 | border: 1px solid @table-border-color;
181 |
182 | // Tighten up spacing
183 | > .table {
184 | margin-bottom: 0;
185 |
186 | // Ensure the content doesn't wrap
187 | > thead,
188 | > tbody,
189 | > tfoot {
190 | > tr {
191 | > th,
192 | > td {
193 | white-space: nowrap;
194 | }
195 | }
196 | }
197 | }
198 |
199 | // Special overrides for the bordered tables
200 | > .table-bordered {
201 | border: 0;
202 |
203 | // Nuke the appropriate borders so that the parent can handle them
204 | > thead,
205 | > tbody,
206 | > tfoot {
207 | > tr {
208 | > th:first-child,
209 | > td:first-child {
210 | border-left: 0;
211 | }
212 | > th:last-child,
213 | > td:last-child {
214 | border-right: 0;
215 | }
216 | }
217 | }
218 |
219 | // Only nuke the last row's bottom-border in `tbody` and `tfoot` since
220 | // chances are there will be only one `tr` in a `thead` and that would
221 | // remove the border altogether.
222 | > tbody,
223 | > tfoot {
224 | > tr:last-child {
225 | > th,
226 | > td {
227 | border-bottom: 0;
228 | }
229 | }
230 | }
231 |
232 | }
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/doc/bootstrap/dropdowns.less:
--------------------------------------------------------------------------------
1 | //
2 | // Dropdown menus
3 | // --------------------------------------------------
4 |
5 |
6 | // Dropdown arrow/caret
7 | .caret {
8 | display: inline-block;
9 | width: 0;
10 | height: 0;
11 | margin-left: 2px;
12 | vertical-align: middle;
13 | border-top: @caret-width-base dashed;
14 | border-right: @caret-width-base solid transparent;
15 | border-left: @caret-width-base solid transparent;
16 | }
17 |
18 | // The dropdown wrapper (div)
19 | .dropup,
20 | .dropdown {
21 | position: relative;
22 | }
23 |
24 | // Prevent the focus on the dropdown toggle when closing dropdowns
25 | .dropdown-toggle:focus {
26 | outline: 0;
27 | }
28 |
29 | // The dropdown menu (ul)
30 | .dropdown-menu {
31 | position: absolute;
32 | top: 100%;
33 | left: 0;
34 | z-index: @zindex-dropdown;
35 | display: none; // none by default, but block on "open" of the menu
36 | float: left;
37 | min-width: 160px;
38 | padding: 5px 0;
39 | margin: 2px 0 0; // override default ul
40 | list-style: none;
41 | font-size: @font-size-base;
42 | text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
43 | background-color: @dropdown-bg;
44 | border: 1px solid @dropdown-fallback-border; // IE8 fallback
45 | border: 1px solid @dropdown-border;
46 | border-radius: @border-radius-base;
47 | .box-shadow(0 6px 12px rgba(0,0,0,.175));
48 | background-clip: padding-box;
49 |
50 | // Aligns the dropdown menu to right
51 | //
52 | // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`
53 | &.pull-right {
54 | right: 0;
55 | left: auto;
56 | }
57 |
58 | // Dividers (basically an hr) within the dropdown
59 | .divider {
60 | .nav-divider(@dropdown-divider-bg);
61 | }
62 |
63 | // Links within the dropdown menu
64 | > li > a {
65 | display: block;
66 | padding: 3px 20px;
67 | clear: both;
68 | font-weight: normal;
69 | line-height: @line-height-base;
70 | color: @dropdown-link-color;
71 | white-space: nowrap; // prevent links from randomly breaking onto new lines
72 | }
73 | }
74 |
75 | // Hover/Focus state
76 | .dropdown-menu > li > a {
77 | &:hover,
78 | &:focus {
79 | text-decoration: none;
80 | color: @dropdown-link-hover-color;
81 | background-color: @dropdown-link-hover-bg;
82 | }
83 | }
84 |
85 | // Active state
86 | .dropdown-menu > .active > a {
87 | &,
88 | &:hover,
89 | &:focus {
90 | color: @dropdown-link-active-color;
91 | text-decoration: none;
92 | outline: 0;
93 | background-color: @dropdown-link-active-bg;
94 | }
95 | }
96 |
97 | // Disabled state
98 | //
99 | // Gray out text and ensure the hover/focus state remains gray
100 |
101 | .dropdown-menu > .disabled > a {
102 | &,
103 | &:hover,
104 | &:focus {
105 | color: @dropdown-link-disabled-color;
106 | }
107 |
108 | // Nuke hover/focus effects
109 | &:hover,
110 | &:focus {
111 | text-decoration: none;
112 | background-color: transparent;
113 | background-image: none; // Remove CSS gradient
114 | .reset-filter();
115 | cursor: @cursor-disabled;
116 | }
117 | }
118 |
119 | // Open state for the dropdown
120 | .open {
121 | // Show the menu
122 | > .dropdown-menu {
123 | display: block;
124 | }
125 |
126 | // Remove the outline when :focus is triggered
127 | > a {
128 | outline: 0;
129 | }
130 | }
131 |
132 | // Menu positioning
133 | //
134 | // Add extra class to `.dropdown-menu` to flip the alignment of the dropdown
135 | // menu with the parent.
136 | .dropdown-menu-right {
137 | left: auto; // Reset the default from `.dropdown-menu`
138 | right: 0;
139 | }
140 | // With v3, we enabled auto-flipping if you have a dropdown within a right
141 | // aligned nav component. To enable the undoing of that, we provide an override
142 | // to restore the default dropdown menu alignment.
143 | //
144 | // This is only for left-aligning a dropdown menu within a `.navbar-right` or
145 | // `.pull-right` nav component.
146 | .dropdown-menu-left {
147 | left: 0;
148 | right: auto;
149 | }
150 |
151 | // Dropdown section headers
152 | .dropdown-header {
153 | display: block;
154 | padding: 3px 20px;
155 | font-size: @font-size-small;
156 | line-height: @line-height-base;
157 | color: @dropdown-header-color;
158 | white-space: nowrap; // as with > li > a
159 | }
160 |
161 | // Backdrop to catch body clicks on mobile, etc.
162 | .dropdown-backdrop {
163 | position: fixed;
164 | left: 0;
165 | right: 0;
166 | bottom: 0;
167 | top: 0;
168 | z-index: (@zindex-dropdown - 10);
169 | }
170 |
171 | // Right aligned dropdowns
172 | .pull-right > .dropdown-menu {
173 | right: 0;
174 | left: auto;
175 | }
176 |
177 | // Allow for dropdowns to go bottom up (aka, dropup-menu)
178 | //
179 | // Just add .dropup after the standard .dropdown class and you're set, bro.
180 | // TODO: abstract this so that the navbar fixed styles are not placed here?
181 |
182 | .dropup,
183 | .navbar-fixed-bottom .dropdown {
184 | // Reverse the caret
185 | .caret {
186 | border-top: 0;
187 | border-bottom: @caret-width-base solid;
188 | content: "";
189 | }
190 | // Different positioning for bottom up menu
191 | .dropdown-menu {
192 | top: auto;
193 | bottom: 100%;
194 | margin-bottom: 2px;
195 | }
196 | }
197 |
198 |
199 | // Component alignment
200 | //
201 | // Reiterate per navbar.less and the modified component alignment there.
202 |
203 | @media (min-width: @grid-float-breakpoint) {
204 | .navbar-right {
205 | .dropdown-menu {
206 | .dropdown-menu-right();
207 | }
208 | // Necessary for overrides of the default right aligned menu.
209 | // Will remove come v4 in all likelihood.
210 | .dropdown-menu-left {
211 | .dropdown-menu-left();
212 | }
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/doc/_templates/layout.html:
--------------------------------------------------------------------------------
1 | {% extends "!layout.html" %}
2 |
3 | {% block extrahead %}
4 |
5 |
6 |
7 |
8 | {# Google Analytics #}
9 |
18 | {% endblock %}
19 |
20 | {%- macro searchform(classes, button) %}
21 |
33 | {%- endmacro %}
34 |
35 | {% block header %}
36 |
37 |
38 |
39 |
40 | {# Brand and toggle get grouped for better mobile display #}
41 |
51 |
52 | {# Collect the nav links, forms, and other content for toggling #}
53 |
54 |
74 | {% if pagename != 'search' %}
75 | {{ searchform('navbar-form navbar-right', False) }}
76 | {%endif%}
77 |
{# /.navbar-collapse #}
78 |
{# /.col-md-offset-2 #}
79 |
{# /.row #}
80 |
{# /.tb-container #}
81 |
82 | {% if pagename == "index" %}
83 | {% set download_url = 'https://github.com/fmtlib/fmt/releases/download' %}
84 |
85 |
86 |
{fmt}
87 |
Small, safe and fast formatting library
88 |
89 | {% set name = 'fmt' if version.split('.')[0]|int >= 3 else 'cppformat' %}
90 |
92 | Download
93 |
94 |
96 |
103 |
104 |
105 |
106 | {% endif %}
107 | {% endblock %}
108 |
109 | {# Disable relbars. #}
110 | {% block relbar1 %}
111 | {% endblock %}
112 | {% block relbar2 %}
113 | {% endblock %}
114 |
115 | {% block content %}
116 |
117 |
118 | {# Sidebar is currently disabled.
119 |
136 | #}
137 |
138 |
139 | {% block body %} {% endblock %}
140 |
141 |
142 |
143 | {% endblock %}
144 |
145 | {% block footer %}
146 | {{ super() }}
147 | {# Placed at the end of the document so the pages load faster. #}
148 |
149 | {% endblock %}
150 |
--------------------------------------------------------------------------------
/doc/bootstrap/navs.less:
--------------------------------------------------------------------------------
1 | //
2 | // Navs
3 | // --------------------------------------------------
4 |
5 |
6 | // Base class
7 | // --------------------------------------------------
8 |
9 | .nav {
10 | margin-bottom: 0;
11 | padding-left: 0; // Override default ul/ol
12 | list-style: none;
13 | &:extend(.clearfix all);
14 |
15 | > li {
16 | position: relative;
17 | display: block;
18 |
19 | > a {
20 | position: relative;
21 | display: block;
22 | padding: @nav-link-padding;
23 | &:hover,
24 | &:focus {
25 | text-decoration: none;
26 | background-color: @nav-link-hover-bg;
27 | }
28 | }
29 |
30 | // Disabled state sets text to gray and nukes hover/tab effects
31 | &.disabled > a {
32 | color: @nav-disabled-link-color;
33 |
34 | &:hover,
35 | &:focus {
36 | color: @nav-disabled-link-hover-color;
37 | text-decoration: none;
38 | background-color: transparent;
39 | cursor: @cursor-disabled;
40 | }
41 | }
42 | }
43 |
44 | // Open dropdowns
45 | .open > a {
46 | &,
47 | &:hover,
48 | &:focus {
49 | background-color: @nav-link-hover-bg;
50 | border-color: @link-color;
51 | }
52 | }
53 |
54 | // Nav dividers (deprecated with v3.0.1)
55 | //
56 | // This should have been removed in v3 with the dropping of `.nav-list`, but
57 | // we missed it. We don't currently support this anywhere, but in the interest
58 | // of maintaining backward compatibility in case you use it, it's deprecated.
59 | .nav-divider {
60 | .nav-divider();
61 | }
62 |
63 | // Prevent IE8 from misplacing imgs
64 | //
65 | // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989
66 | > li > a > img {
67 | max-width: none;
68 | }
69 | }
70 |
71 |
72 | // Tabs
73 | // -------------------------
74 |
75 | // Give the tabs something to sit on
76 | .nav-tabs {
77 | border-bottom: 1px solid @nav-tabs-border-color;
78 | > li {
79 | float: left;
80 | // Make the list-items overlay the bottom border
81 | margin-bottom: -1px;
82 |
83 | // Actual tabs (as links)
84 | > a {
85 | margin-right: 2px;
86 | line-height: @line-height-base;
87 | border: 1px solid transparent;
88 | border-radius: @border-radius-base @border-radius-base 0 0;
89 | &:hover {
90 | border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;
91 | }
92 | }
93 |
94 | // Active state, and its :hover to override normal :hover
95 | &.active > a {
96 | &,
97 | &:hover,
98 | &:focus {
99 | color: @nav-tabs-active-link-hover-color;
100 | background-color: @nav-tabs-active-link-hover-bg;
101 | border: 1px solid @nav-tabs-active-link-hover-border-color;
102 | border-bottom-color: transparent;
103 | cursor: default;
104 | }
105 | }
106 | }
107 | // pulling this in mainly for less shorthand
108 | &.nav-justified {
109 | .nav-justified();
110 | .nav-tabs-justified();
111 | }
112 | }
113 |
114 |
115 | // Pills
116 | // -------------------------
117 | .nav-pills {
118 | > li {
119 | float: left;
120 |
121 | // Links rendered as pills
122 | > a {
123 | border-radius: @nav-pills-border-radius;
124 | }
125 | + li {
126 | margin-left: 2px;
127 | }
128 |
129 | // Active state
130 | &.active > a {
131 | &,
132 | &:hover,
133 | &:focus {
134 | color: @nav-pills-active-link-hover-color;
135 | background-color: @nav-pills-active-link-hover-bg;
136 | }
137 | }
138 | }
139 | }
140 |
141 |
142 | // Stacked pills
143 | .nav-stacked {
144 | > li {
145 | float: none;
146 | + li {
147 | margin-top: 2px;
148 | margin-left: 0; // no need for this gap between nav items
149 | }
150 | }
151 | }
152 |
153 |
154 | // Nav variations
155 | // --------------------------------------------------
156 |
157 | // Justified nav links
158 | // -------------------------
159 |
160 | .nav-justified {
161 | width: 100%;
162 |
163 | > li {
164 | float: none;
165 | > a {
166 | text-align: center;
167 | margin-bottom: 5px;
168 | }
169 | }
170 |
171 | > .dropdown .dropdown-menu {
172 | top: auto;
173 | left: auto;
174 | }
175 |
176 | @media (min-width: @screen-sm-min) {
177 | > li {
178 | display: table-cell;
179 | width: 1%;
180 | > a {
181 | margin-bottom: 0;
182 | }
183 | }
184 | }
185 | }
186 |
187 | // Move borders to anchors instead of bottom of list
188 | //
189 | // Mixin for adding on top the shared `.nav-justified` styles for our tabs
190 | .nav-tabs-justified {
191 | border-bottom: 0;
192 |
193 | > li > a {
194 | // Override margin from .nav-tabs
195 | margin-right: 0;
196 | border-radius: @border-radius-base;
197 | }
198 |
199 | > .active > a,
200 | > .active > a:hover,
201 | > .active > a:focus {
202 | border: 1px solid @nav-tabs-justified-link-border-color;
203 | }
204 |
205 | @media (min-width: @screen-sm-min) {
206 | > li > a {
207 | border-bottom: 1px solid @nav-tabs-justified-link-border-color;
208 | border-radius: @border-radius-base @border-radius-base 0 0;
209 | }
210 | > .active > a,
211 | > .active > a:hover,
212 | > .active > a:focus {
213 | border-bottom-color: @nav-tabs-justified-active-link-border-color;
214 | }
215 | }
216 | }
217 |
218 |
219 | // Tabbable tabs
220 | // -------------------------
221 |
222 | // Hide tabbable panes to start, show them when `.active`
223 | .tab-content {
224 | > .tab-pane {
225 | display: none;
226 | }
227 | > .active {
228 | display: block;
229 | }
230 | }
231 |
232 |
233 | // Dropdowns
234 | // -------------------------
235 |
236 | // Specific dropdowns
237 | .nav-tabs .dropdown-menu {
238 | // make dropdown border overlap tab border
239 | margin-top: -1px;
240 | // Remove the top rounded corners here since there is a hard edge above the menu
241 | .border-top-radius(0);
242 | }
243 |
--------------------------------------------------------------------------------
/test/gtest-extra.h:
--------------------------------------------------------------------------------
1 | // Formatting library for C++ - custom Google Test assertions
2 | //
3 | // Copyright (c) 2012 - present, Victor Zverovich
4 | // All rights reserved.
5 | //
6 | // For the license information refer to format.h.
7 |
8 | #ifndef FMT_GTEST_EXTRA_H_
9 | #define FMT_GTEST_EXTRA_H_
10 |
11 | #include
12 | #include "gmock.h"
13 |
14 | #include "fmt/core.h"
15 |
16 | #ifndef FMT_USE_FILE_DESCRIPTORS
17 | # define FMT_USE_FILE_DESCRIPTORS 0
18 | #endif
19 |
20 | #if FMT_USE_FILE_DESCRIPTORS
21 | # include "fmt/posix.h"
22 | #endif
23 |
24 | #define FMT_TEST_THROW_(statement, expected_exception, expected_message, fail) \
25 | GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
26 | if (::testing::AssertionResult gtest_ar = ::testing::AssertionSuccess()) { \
27 | std::string gtest_expected_message = expected_message; \
28 | bool gtest_caught_expected = false; \
29 | try { \
30 | GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
31 | } \
32 | catch (expected_exception const& e) { \
33 | if (gtest_expected_message != e.what()) { \
34 | gtest_ar \
35 | << #statement " throws an exception with a different message.\n" \
36 | << "Expected: " << gtest_expected_message << "\n" \
37 | << " Actual: " << e.what(); \
38 | goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
39 | } \
40 | gtest_caught_expected = true; \
41 | } \
42 | catch (...) { \
43 | gtest_ar << \
44 | "Expected: " #statement " throws an exception of type " \
45 | #expected_exception ".\n Actual: it throws a different type."; \
46 | goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
47 | } \
48 | if (!gtest_caught_expected) { \
49 | gtest_ar << \
50 | "Expected: " #statement " throws an exception of type " \
51 | #expected_exception ".\n Actual: it throws nothing."; \
52 | goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
53 | } \
54 | } else \
55 | GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
56 | fail(gtest_ar.failure_message())
57 |
58 | // Tests that the statement throws the expected exception and the exception's
59 | // what() method returns expected message.
60 | #define EXPECT_THROW_MSG(statement, expected_exception, expected_message) \
61 | FMT_TEST_THROW_(statement, expected_exception, \
62 | expected_message, GTEST_NONFATAL_FAILURE_)
63 |
64 | std::string format_system_error(int error_code, fmt::string_view message);
65 |
66 | #define EXPECT_SYSTEM_ERROR(statement, error_code, message) \
67 | EXPECT_THROW_MSG(statement, fmt::system_error, \
68 | format_system_error(error_code, message))
69 |
70 | #if FMT_USE_FILE_DESCRIPTORS
71 |
72 | // Captures file output by redirecting it to a pipe.
73 | // The output it can handle is limited by the pipe capacity.
74 | class OutputRedirect {
75 | private:
76 | FILE *file_;
77 | fmt::file original_; // Original file passed to redirector.
78 | fmt::file read_end_; // Read end of the pipe where the output is redirected.
79 |
80 | GTEST_DISALLOW_COPY_AND_ASSIGN_(OutputRedirect);
81 |
82 | void flush();
83 | void restore();
84 |
85 | public:
86 | explicit OutputRedirect(FILE *file);
87 | ~OutputRedirect() FMT_NOEXCEPT;
88 |
89 | // Restores the original file, reads output from the pipe into a string
90 | // and returns it.
91 | std::string restore_and_read();
92 | };
93 |
94 | #define FMT_TEST_WRITE_(statement, expected_output, file, fail) \
95 | GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
96 | if (::testing::AssertionResult gtest_ar = ::testing::AssertionSuccess()) { \
97 | std::string gtest_expected_output = expected_output; \
98 | OutputRedirect gtest_redir(file); \
99 | GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
100 | std::string gtest_output = gtest_redir.restore_and_read(); \
101 | if (gtest_output != gtest_expected_output) { \
102 | gtest_ar \
103 | << #statement " produces different output.\n" \
104 | << "Expected: " << gtest_expected_output << "\n" \
105 | << " Actual: " << gtest_output; \
106 | goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
107 | } \
108 | } else \
109 | GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
110 | fail(gtest_ar.failure_message())
111 |
112 | // Tests that the statement writes the expected output to file.
113 | #define EXPECT_WRITE(file, statement, expected_output) \
114 | FMT_TEST_WRITE_(statement, expected_output, file, GTEST_NONFATAL_FAILURE_)
115 |
116 | #ifdef _MSC_VER
117 |
118 | // Suppresses Windows assertions on invalid file descriptors, making
119 | // POSIX functions return proper error codes instead of crashing on Windows.
120 | class SuppressAssert {
121 | private:
122 | _invalid_parameter_handler original_handler_;
123 | int original_report_mode_;
124 |
125 | static void handle_invalid_parameter(const wchar_t *,
126 | const wchar_t *, const wchar_t *, unsigned , uintptr_t) {}
127 |
128 | public:
129 | SuppressAssert()
130 | : original_handler_(_set_invalid_parameter_handler(handle_invalid_parameter)),
131 | original_report_mode_(_CrtSetReportMode(_CRT_ASSERT, 0)) {
132 | }
133 | ~SuppressAssert() {
134 | _set_invalid_parameter_handler(original_handler_);
135 | _CrtSetReportMode(_CRT_ASSERT, original_report_mode_);
136 | }
137 | };
138 |
139 | # define SUPPRESS_ASSERT(statement) { SuppressAssert sa; statement; }
140 | #else
141 | # define SUPPRESS_ASSERT(statement) statement
142 | #endif // _MSC_VER
143 |
144 | #define EXPECT_SYSTEM_ERROR_NOASSERT(statement, error_code, message) \
145 | EXPECT_SYSTEM_ERROR(SUPPRESS_ASSERT(statement), error_code, message)
146 |
147 | // Attempts to read count characters from a file.
148 | std::string read(fmt::file &f, std::size_t count);
149 |
150 | #define EXPECT_READ(file, expected_content) \
151 | EXPECT_EQ(expected_content, read(file, std::strlen(expected_content)))
152 |
153 | #endif // FMT_USE_FILE_DESCRIPTORS
154 |
155 | template
156 | struct ScopedMock : testing::StrictMock {
157 | ScopedMock() { Mock::instance = this; }
158 | ~ScopedMock() { Mock::instance = nullptr; }
159 | };
160 |
161 | #endif // FMT_GTEST_EXTRA_H_
162 |
--------------------------------------------------------------------------------
/doc/bootstrap/carousel.less:
--------------------------------------------------------------------------------
1 | //
2 | // Carousel
3 | // --------------------------------------------------
4 |
5 |
6 | // Wrapper for the slide container and indicators
7 | .carousel {
8 | position: relative;
9 | }
10 |
11 | .carousel-inner {
12 | position: relative;
13 | overflow: hidden;
14 | width: 100%;
15 |
16 | > .item {
17 | display: none;
18 | position: relative;
19 | .transition(.6s ease-in-out left);
20 |
21 | // Account for jankitude on images
22 | > img,
23 | > a > img {
24 | &:extend(.img-responsive);
25 | line-height: 1;
26 | }
27 |
28 | // WebKit CSS3 transforms for supported devices
29 | @media all and (transform-3d), (-webkit-transform-3d) {
30 | .transition-transform(~'0.6s ease-in-out');
31 | .backface-visibility(~'hidden');
32 | .perspective(1000);
33 |
34 | &.next,
35 | &.active.right {
36 | .translate3d(100%, 0, 0);
37 | left: 0;
38 | }
39 | &.prev,
40 | &.active.left {
41 | .translate3d(-100%, 0, 0);
42 | left: 0;
43 | }
44 | &.next.left,
45 | &.prev.right,
46 | &.active {
47 | .translate3d(0, 0, 0);
48 | left: 0;
49 | }
50 | }
51 | }
52 |
53 | > .active,
54 | > .next,
55 | > .prev {
56 | display: block;
57 | }
58 |
59 | > .active {
60 | left: 0;
61 | }
62 |
63 | > .next,
64 | > .prev {
65 | position: absolute;
66 | top: 0;
67 | width: 100%;
68 | }
69 |
70 | > .next {
71 | left: 100%;
72 | }
73 | > .prev {
74 | left: -100%;
75 | }
76 | > .next.left,
77 | > .prev.right {
78 | left: 0;
79 | }
80 |
81 | > .active.left {
82 | left: -100%;
83 | }
84 | > .active.right {
85 | left: 100%;
86 | }
87 |
88 | }
89 |
90 | // Left/right controls for nav
91 | // ---------------------------
92 |
93 | .carousel-control {
94 | position: absolute;
95 | top: 0;
96 | left: 0;
97 | bottom: 0;
98 | width: @carousel-control-width;
99 | .opacity(@carousel-control-opacity);
100 | font-size: @carousel-control-font-size;
101 | color: @carousel-control-color;
102 | text-align: center;
103 | text-shadow: @carousel-text-shadow;
104 | // We can't have this transition here because WebKit cancels the carousel
105 | // animation if you trip this while in the middle of another animation.
106 |
107 | // Set gradients for backgrounds
108 | &.left {
109 | #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));
110 | }
111 | &.right {
112 | left: auto;
113 | right: 0;
114 | #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));
115 | }
116 |
117 | // Hover/focus state
118 | &:hover,
119 | &:focus {
120 | outline: 0;
121 | color: @carousel-control-color;
122 | text-decoration: none;
123 | .opacity(.9);
124 | }
125 |
126 | // Toggles
127 | .icon-prev,
128 | .icon-next,
129 | .glyphicon-chevron-left,
130 | .glyphicon-chevron-right {
131 | position: absolute;
132 | top: 50%;
133 | z-index: 5;
134 | display: inline-block;
135 | }
136 | .icon-prev,
137 | .glyphicon-chevron-left {
138 | left: 50%;
139 | margin-left: -10px;
140 | }
141 | .icon-next,
142 | .glyphicon-chevron-right {
143 | right: 50%;
144 | margin-right: -10px;
145 | }
146 | .icon-prev,
147 | .icon-next {
148 | width: 20px;
149 | height: 20px;
150 | margin-top: -10px;
151 | line-height: 1;
152 | font-family: serif;
153 | }
154 |
155 |
156 | .icon-prev {
157 | &:before {
158 | content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)
159 | }
160 | }
161 | .icon-next {
162 | &:before {
163 | content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)
164 | }
165 | }
166 | }
167 |
168 | // Optional indicator pips
169 | //
170 | // Add an unordered list with the following class and add a list item for each
171 | // slide your carousel holds.
172 |
173 | .carousel-indicators {
174 | position: absolute;
175 | bottom: 10px;
176 | left: 50%;
177 | z-index: 15;
178 | width: 60%;
179 | margin-left: -30%;
180 | padding-left: 0;
181 | list-style: none;
182 | text-align: center;
183 |
184 | li {
185 | display: inline-block;
186 | width: 10px;
187 | height: 10px;
188 | margin: 1px;
189 | text-indent: -999px;
190 | border: 1px solid @carousel-indicator-border-color;
191 | border-radius: 10px;
192 | cursor: pointer;
193 |
194 | // IE8-9 hack for event handling
195 | //
196 | // Internet Explorer 8-9 does not support clicks on elements without a set
197 | // `background-color`. We cannot use `filter` since that's not viewed as a
198 | // background color by the browser. Thus, a hack is needed.
199 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer
200 | //
201 | // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we
202 | // set alpha transparency for the best results possible.
203 | background-color: #000 \9; // IE8
204 | background-color: rgba(0,0,0,0); // IE9
205 | }
206 | .active {
207 | margin: 0;
208 | width: 12px;
209 | height: 12px;
210 | background-color: @carousel-indicator-active-bg;
211 | }
212 | }
213 |
214 | // Optional captions
215 | // -----------------------------
216 | // Hidden by default for smaller viewports
217 | .carousel-caption {
218 | position: absolute;
219 | left: 15%;
220 | right: 15%;
221 | bottom: 20px;
222 | z-index: 10;
223 | padding-top: 20px;
224 | padding-bottom: 20px;
225 | color: @carousel-caption-color;
226 | text-align: center;
227 | text-shadow: @carousel-text-shadow;
228 | & .btn {
229 | text-shadow: none; // No shadow for button elements in carousel-caption
230 | }
231 | }
232 |
233 |
234 | // Scale up controls for tablets and up
235 | @media screen and (min-width: @screen-sm-min) {
236 |
237 | // Scale up the controls a smidge
238 | .carousel-control {
239 | .glyphicon-chevron-left,
240 | .glyphicon-chevron-right,
241 | .icon-prev,
242 | .icon-next {
243 | width: 30px;
244 | height: 30px;
245 | margin-top: -15px;
246 | font-size: 30px;
247 | }
248 | .glyphicon-chevron-left,
249 | .icon-prev {
250 | margin-left: -15px;
251 | }
252 | .glyphicon-chevron-right,
253 | .icon-next {
254 | margin-right: -15px;
255 | }
256 | }
257 |
258 | // Show and left align the captions
259 | .carousel-caption {
260 | left: 20%;
261 | right: 20%;
262 | padding-bottom: 30px;
263 | }
264 |
265 | // Move up the indicators
266 | .carousel-indicators {
267 | bottom: 20px;
268 | }
269 | }
270 |
--------------------------------------------------------------------------------
/doc/bootstrap/button-groups.less:
--------------------------------------------------------------------------------
1 | //
2 | // Button groups
3 | // --------------------------------------------------
4 |
5 | // Make the div behave like a button
6 | .btn-group,
7 | .btn-group-vertical {
8 | position: relative;
9 | display: inline-block;
10 | vertical-align: middle; // match .btn alignment given font-size hack above
11 | > .btn {
12 | position: relative;
13 | float: left;
14 | // Bring the "active" button to the front
15 | &:hover,
16 | &:focus,
17 | &:active,
18 | &.active {
19 | z-index: 2;
20 | }
21 | }
22 | }
23 |
24 | // Prevent double borders when buttons are next to each other
25 | .btn-group {
26 | .btn + .btn,
27 | .btn + .btn-group,
28 | .btn-group + .btn,
29 | .btn-group + .btn-group {
30 | margin-left: -1px;
31 | }
32 | }
33 |
34 | // Optional: Group multiple button groups together for a toolbar
35 | .btn-toolbar {
36 | margin-left: -5px; // Offset the first child's margin
37 | &:extend(.clearfix all);
38 |
39 | .btn-group,
40 | .input-group {
41 | float: left;
42 | }
43 | > .btn,
44 | > .btn-group,
45 | > .input-group {
46 | margin-left: 5px;
47 | }
48 | }
49 |
50 | .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
51 | border-radius: 0;
52 | }
53 |
54 | // Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match
55 | .btn-group > .btn:first-child {
56 | margin-left: 0;
57 | &:not(:last-child):not(.dropdown-toggle) {
58 | .border-right-radius(0);
59 | }
60 | }
61 | // Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it
62 | .btn-group > .btn:last-child:not(:first-child),
63 | .btn-group > .dropdown-toggle:not(:first-child) {
64 | .border-left-radius(0);
65 | }
66 |
67 | // Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)
68 | .btn-group > .btn-group {
69 | float: left;
70 | }
71 | .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
72 | border-radius: 0;
73 | }
74 | .btn-group > .btn-group:first-child:not(:last-child) {
75 | > .btn:last-child,
76 | > .dropdown-toggle {
77 | .border-right-radius(0);
78 | }
79 | }
80 | .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
81 | .border-left-radius(0);
82 | }
83 |
84 | // On active and open, don't show outline
85 | .btn-group .dropdown-toggle:active,
86 | .btn-group.open .dropdown-toggle {
87 | outline: 0;
88 | }
89 |
90 |
91 | // Sizing
92 | //
93 | // Remix the default button sizing classes into new ones for easier manipulation.
94 |
95 | .btn-group-xs > .btn { &:extend(.btn-xs); }
96 | .btn-group-sm > .btn { &:extend(.btn-sm); }
97 | .btn-group-lg > .btn { &:extend(.btn-lg); }
98 |
99 |
100 | // Split button dropdowns
101 | // ----------------------
102 |
103 | // Give the line between buttons some depth
104 | .btn-group > .btn + .dropdown-toggle {
105 | padding-left: 8px;
106 | padding-right: 8px;
107 | }
108 | .btn-group > .btn-lg + .dropdown-toggle {
109 | padding-left: 12px;
110 | padding-right: 12px;
111 | }
112 |
113 | // The clickable button for toggling the menu
114 | // Remove the gradient and set the same inset shadow as the :active state
115 | .btn-group.open .dropdown-toggle {
116 | .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
117 |
118 | // Show no shadow for `.btn-link` since it has no other button styles.
119 | &.btn-link {
120 | .box-shadow(none);
121 | }
122 | }
123 |
124 |
125 | // Reposition the caret
126 | .btn .caret {
127 | margin-left: 0;
128 | }
129 | // Carets in other button sizes
130 | .btn-lg .caret {
131 | border-width: @caret-width-large @caret-width-large 0;
132 | border-bottom-width: 0;
133 | }
134 | // Upside down carets for .dropup
135 | .dropup .btn-lg .caret {
136 | border-width: 0 @caret-width-large @caret-width-large;
137 | }
138 |
139 |
140 | // Vertical button groups
141 | // ----------------------
142 |
143 | .btn-group-vertical {
144 | > .btn,
145 | > .btn-group,
146 | > .btn-group > .btn {
147 | display: block;
148 | float: none;
149 | width: 100%;
150 | max-width: 100%;
151 | }
152 |
153 | // Clear floats so dropdown menus can be properly placed
154 | > .btn-group {
155 | &:extend(.clearfix all);
156 | > .btn {
157 | float: none;
158 | }
159 | }
160 |
161 | > .btn + .btn,
162 | > .btn + .btn-group,
163 | > .btn-group + .btn,
164 | > .btn-group + .btn-group {
165 | margin-top: -1px;
166 | margin-left: 0;
167 | }
168 | }
169 |
170 | .btn-group-vertical > .btn {
171 | &:not(:first-child):not(:last-child) {
172 | border-radius: 0;
173 | }
174 | &:first-child:not(:last-child) {
175 | border-top-right-radius: @border-radius-base;
176 | .border-bottom-radius(0);
177 | }
178 | &:last-child:not(:first-child) {
179 | border-bottom-left-radius: @border-radius-base;
180 | .border-top-radius(0);
181 | }
182 | }
183 | .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
184 | border-radius: 0;
185 | }
186 | .btn-group-vertical > .btn-group:first-child:not(:last-child) {
187 | > .btn:last-child,
188 | > .dropdown-toggle {
189 | .border-bottom-radius(0);
190 | }
191 | }
192 | .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
193 | .border-top-radius(0);
194 | }
195 |
196 |
197 | // Justified button groups
198 | // ----------------------
199 |
200 | .btn-group-justified {
201 | display: table;
202 | width: 100%;
203 | table-layout: fixed;
204 | border-collapse: separate;
205 | > .btn,
206 | > .btn-group {
207 | float: none;
208 | display: table-cell;
209 | width: 1%;
210 | }
211 | > .btn-group .btn {
212 | width: 100%;
213 | }
214 |
215 | > .btn-group .dropdown-menu {
216 | left: auto;
217 | }
218 | }
219 |
220 |
221 | // Checkbox and radio options
222 | //
223 | // In order to support the browser's form validation feedback, powered by the
224 | // `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
225 | // `display: none;` or `visibility: hidden;` as that also hides the popover.
226 | // Simply visually hiding the inputs via `opacity` would leave them clickable in
227 | // certain cases which is prevented by using `clip` and `pointer-events`.
228 | // This way, we ensure a DOM element is visible to position the popover from.
229 | //
230 | // See https://github.com/twbs/bootstrap/pull/12794 and
231 | // https://github.com/twbs/bootstrap/pull/14559 for more information.
232 |
233 | [data-toggle="buttons"] {
234 | > .btn,
235 | > .btn-group > .btn {
236 | input[type="radio"],
237 | input[type="checkbox"] {
238 | position: absolute;
239 | clip: rect(0,0,0,0);
240 | pointer-events: none;
241 | }
242 | }
243 | }
244 |
--------------------------------------------------------------------------------