├── index.styl
├── index.scss
├── src
├── js
│ ├── outro.js
│ ├── var
│ │ ├── body.js
│ │ ├── document.js
│ │ └── root.js
│ ├── locale
│ │ ├── core.js
│ │ ├── locale.js
│ │ ├── init-cond.js
│ │ ├── detect-font.js
│ │ └── normalize.js
│ ├── typography.js
│ ├── inline.js
│ ├── global.js
│ ├── han.js
│ ├── typeface.js
│ ├── dom-ready.js
│ ├── intro.js
│ ├── locale.js
│ ├── regex.js
│ ├── typography
│ │ └── biaodian.js
│ ├── core.js
│ ├── inline
│ │ ├── hanging.js
│ │ ├── hws.js
│ │ └── jiya.js
│ └── method.js
├── sass
│ ├── _var.sass
│ ├── _locale.sass
│ ├── _typography.sass
│ ├── han.scss
│ ├── typography
│ │ ├── _ff.sass
│ │ ├── ff
│ │ │ ├── _fangsong.scss
│ │ │ ├── _italic.scss
│ │ │ ├── _ruby.scss
│ │ │ ├── _range.scss
│ │ │ ├── _kaiti.scss
│ │ │ ├── _numeral.scss
│ │ │ └── _songti.scss
│ │ ├── _extend.sass
│ │ ├── _mixin.scss
│ │ ├── extend
│ │ │ ├── _mono.scss
│ │ │ ├── _sans.scss
│ │ │ ├── _serif.scss
│ │ │ └── _cursive.scss
│ │ ├── _var.sass
│ │ └── _typography.sass
│ ├── inline
│ │ ├── _subst.sass
│ │ ├── _hws.sass
│ │ ├── _hanging.sass
│ │ ├── _em.sass
│ │ └── _jiya.sass
│ ├── _api.sass
│ ├── locale
│ │ ├── _const.sass
│ │ ├── _enhancement.sass
│ │ └── _mixin.sass
│ ├── _typeset.sass
│ ├── var
│ │ └── _internal.sass
│ ├── section
│ │ ├── _counter.sass
│ │ └── _well-knit.sass
│ └── example.sass
└── styl
│ ├── var.styl
│ ├── locale.styl
│ ├── typography.styl
│ ├── index.styl
│ ├── typography
│ ├── ff.styl
│ ├── ff
│ │ ├── range.styl
│ │ ├── fangsong.styl
│ │ ├── italic.styl
│ │ ├── ruby.styl
│ │ ├── kaiti.styl
│ │ ├── numeral.styl
│ │ └── songti.styl
│ ├── extend
│ │ ├── mono.styl
│ │ ├── sans.styl
│ │ ├── serif.styl
│ │ └── cursive.styl
│ ├── mixin.styl
│ ├── extend.styl
│ └── typography.styl
│ ├── api.styl
│ ├── inline
│ ├── subst.styl
│ ├── hws.styl
│ ├── hanging.styl
│ ├── em.styl
│ └── jiya.styl
│ ├── locale
│ ├── const.styl
│ ├── enhancement.styl
│ └── mixin.styl
│ ├── typeset.styl
│ ├── var
│ ├── internal.styl
│ └── default.styl
│ ├── section
│ ├── counter.styl
│ └── well-knit.styl
│ └── example.styl
├── index.js
├── font
├── han.otf
├── han.vfb
├── han.woff
├── han.woff2
├── han-space.otf
├── han-space.woff
└── han-space.woff2
├── demo
├── test-commonjs.ls
├── font
│ ├── han.otf
│ ├── han.woff
│ ├── han.woff2
│ ├── han-space.otf
│ ├── han-space.woff
│ └── han-space.woff2
├── test-amd.js
├── counter-han.styl
├── generics-han.styl
├── em-han.styl
├── ruby(ff)-han.styl
├── README.md
├── shs.html
├── shs.jade
├── ruby(ff).html
├── numeral.html
├── deco-line.html
├── italic.html
├── numeral.jade
├── generics.html
├── generics.jade
├── deco-line.jade
├── ruby(ff).jade
├── italic.jade
├── index.html
├── biaodian.html
├── index.jade
├── hanging.html
├── em.html
├── well-knit.html
├── hanging.jade
├── hws.html
└── jiya.html
├── .gitignore
├── .jshintrc
├── bower.json
├── .csscomb.json
├── test
├── index.html
└── qunit-assert-dom.min.js
├── LICENSE.md
├── package.json
├── README.md
└── README-ja.md
/index.styl:
--------------------------------------------------------------------------------
1 |
2 | @import 'src/styl'
3 |
4 |
--------------------------------------------------------------------------------
/index.scss:
--------------------------------------------------------------------------------
1 |
2 | @import 'src/sass/han';
3 |
4 |
--------------------------------------------------------------------------------
/src/js/outro.js:
--------------------------------------------------------------------------------
1 |
2 | return Han
3 | });
4 |
5 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = require( './dist/han' )
3 |
4 |
--------------------------------------------------------------------------------
/font/han.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/font/han.otf
--------------------------------------------------------------------------------
/font/han.vfb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/font/han.vfb
--------------------------------------------------------------------------------
/font/han.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/font/han.woff
--------------------------------------------------------------------------------
/src/sass/_var.sass:
--------------------------------------------------------------------------------
1 |
2 | @import var/default
3 | @import var/internal
4 |
--------------------------------------------------------------------------------
/demo/test-commonjs.ls:
--------------------------------------------------------------------------------
1 |
2 | Han = require \../index
3 | Han!.render!
4 |
5 |
--------------------------------------------------------------------------------
/font/han.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/font/han.woff2
--------------------------------------------------------------------------------
/src/js/var/body.js:
--------------------------------------------------------------------------------
1 | define(function() {
2 | return document.body
3 | })
4 |
--------------------------------------------------------------------------------
/demo/font/han.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/demo/font/han.otf
--------------------------------------------------------------------------------
/demo/font/han.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/demo/font/han.woff
--------------------------------------------------------------------------------
/font/han-space.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/font/han-space.otf
--------------------------------------------------------------------------------
/src/js/var/document.js:
--------------------------------------------------------------------------------
1 | define(function() {
2 | return window.document
3 | })
4 |
--------------------------------------------------------------------------------
/src/styl/var.styl:
--------------------------------------------------------------------------------
1 |
2 | @import 'var/default'
3 | @import 'var/internal'
4 |
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .sass-cache
3 | node_modules
4 | TODO
5 | dist
6 | *.vfbak
7 |
--------------------------------------------------------------------------------
/demo/font/han.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/demo/font/han.woff2
--------------------------------------------------------------------------------
/font/han-space.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/font/han-space.woff
--------------------------------------------------------------------------------
/font/han-space.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/font/han-space.woff2
--------------------------------------------------------------------------------
/src/js/var/root.js:
--------------------------------------------------------------------------------
1 | define(function() {
2 | return document.documentElement
3 | })
4 |
--------------------------------------------------------------------------------
/demo/font/han-space.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/demo/font/han-space.otf
--------------------------------------------------------------------------------
/demo/font/han-space.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/demo/font/han-space.woff
--------------------------------------------------------------------------------
/demo/font/han-space.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethantw/Han/HEAD/demo/font/han-space.woff2
--------------------------------------------------------------------------------
/demo/test-amd.js:
--------------------------------------------------------------------------------
1 | require([
2 | './han.min'
3 | ], function( Han ) {
4 | Han.init()
5 | })
6 |
--------------------------------------------------------------------------------
/src/js/locale/core.js:
--------------------------------------------------------------------------------
1 | define(function() {
2 | var Locale = {}
3 |
4 | return Locale
5 | })
6 |
--------------------------------------------------------------------------------
/src/js/typography.js:
--------------------------------------------------------------------------------
1 | define([
2 | './core',
3 | './typography/biaodian'
4 | ], function( Han ) {
5 | return Han
6 | })
7 |
--------------------------------------------------------------------------------
/src/sass/_locale.sass:
--------------------------------------------------------------------------------
1 |
2 | @import locale/const
3 | @import locale/mixin
4 | @import locale/semantics
5 | @import locale/enhancement
6 |
--------------------------------------------------------------------------------
/src/styl/locale.styl:
--------------------------------------------------------------------------------
1 |
2 | @import 'locale/const'
3 | @import 'locale/mixin'
4 | @import 'locale/semantics'
5 | @import 'locale/enhancement'
6 |
--------------------------------------------------------------------------------
/src/styl/typography.styl:
--------------------------------------------------------------------------------
1 |
2 | @import 'typography/mixin'
3 | @import 'typography/ff'
4 | @import 'typography/extend'
5 | @import 'typography/typography'
6 |
7 |
--------------------------------------------------------------------------------
/src/sass/_typography.sass:
--------------------------------------------------------------------------------
1 |
2 | @import typography/var
3 | @import typography/mixin
4 | @import typography/ff
5 | @import typography/extend
6 | @import typography/typography
7 |
--------------------------------------------------------------------------------
/src/styl/index.styl:
--------------------------------------------------------------------------------
1 |
2 | @import 'var'
3 | @import 'api'
4 |
5 | @import 'locale/normalize'
6 | @import 'locale'
7 |
8 | @import 'typography'
9 | @import 'typeset'
10 |
11 |
--------------------------------------------------------------------------------
/src/sass/han.scss:
--------------------------------------------------------------------------------
1 |
2 | @import 'var';
3 | @import 'api';
4 |
5 | @import 'locale/normalize';
6 | @import 'locale';
7 |
8 | @import 'typography';
9 | @import 'typeset';
10 |
11 |
--------------------------------------------------------------------------------
/src/js/inline.js:
--------------------------------------------------------------------------------
1 | define([
2 | './core',
3 | './inline/hws',
4 | './inline/hanging',
5 | './inline/jiya',
6 | './inline/subst'
7 | ], function( Han ) {
8 | return Han
9 | })
10 |
--------------------------------------------------------------------------------
/src/js/locale/locale.js:
--------------------------------------------------------------------------------
1 | define([
2 | './core',
3 | './detect-font',
4 | './support',
5 | './init-cond',
6 | './normalize'
7 | ], function( Locale ) {
8 | return Locale
9 | })
10 |
--------------------------------------------------------------------------------
/demo/counter-han.styl:
--------------------------------------------------------------------------------
1 |
2 | // **
3 | // * Sectional counter in articles
4 | // * `true` || `false`
5 | // *
6 | $han-section-counter = true
7 | $han-section-counter-toc = true
8 |
9 | @import '..'
10 |
11 |
--------------------------------------------------------------------------------
/src/js/global.js:
--------------------------------------------------------------------------------
1 | define([
2 | './core'
3 | ], function( Han ) {
4 |
5 | // Expose to global namespace
6 | if ( typeof noGlobalNS === 'undefined' || noGlobalNS === false ) {
7 | window.Han = Han
8 | }
9 | })
10 |
11 |
--------------------------------------------------------------------------------
/src/js/han.js:
--------------------------------------------------------------------------------
1 | define([
2 | './core',
3 | './regex',
4 | './find',
5 | './locale',
6 | './typeface',
7 | './typography',
8 | './inline',
9 | './dom-ready',
10 | './global'
11 | ], function( Han ) {
12 | return Han
13 | })
14 |
--------------------------------------------------------------------------------
/demo/generics-han.styl:
--------------------------------------------------------------------------------
1 |
2 | @import '..'
3 |
4 | .sans
5 | han-typeface-by-lang( sans )
6 |
7 | .sans-italic
8 | han-typeface-by-lang( sans-italic )
9 |
10 | .mono
11 | han-typeface-by-lang( mono )
12 |
13 | .serif
14 | han-typeface-by-lang( serif )
15 |
16 | .cursive
17 | han-typeface-by-lang( cursive )
18 |
19 | .cursive-italic
20 | han-typeface-by-lang( cursive-italic )
21 |
22 |
--------------------------------------------------------------------------------
/demo/em-han.styl:
--------------------------------------------------------------------------------
1 |
2 | @import '..'
3 |
4 | em.above
5 | han-text-emphasis( over )
6 | em.sesame
7 | han-text-emphasis( under, sesame, open, inherit, true, false )
8 | em.above-dc
9 | han-text-emphasis( over, double-circle, open, inherit, true, false )
10 | em.rebecca
11 | han-text-emphasis( under, triangle, filled, #639, true, false )
12 | em.no-skip
13 | han-text-emphasis( under, circle, open, red, false, false )
14 |
15 |
--------------------------------------------------------------------------------
/src/sass/typography/_ff.sass:
--------------------------------------------------------------------------------
1 |
2 | // * Mixins for Unicode blocks
3 | // *
4 | @import ff/range
5 |
6 | // * The Four Typefaces & biaodian
7 | // *
8 | @import ff/heiti
9 | @import ff/songti
10 | @import ff/kaiti
11 | @import ff/fangsong
12 | @import ff/biaodian
13 |
14 | // * Western Specialties & numerals
15 | // *
16 | @import ff/italic
17 | @import ff/numeral
18 |
19 | // * Zhuyin & Romanisation
20 | // *
21 | @import ff/ruby
22 |
23 |
--------------------------------------------------------------------------------
/src/styl/typography/ff.styl:
--------------------------------------------------------------------------------
1 |
2 | // * Mixins for Unicode blocks
3 | // *
4 | @import 'ff/range'
5 |
6 | // * The Four Typefaces & biaodian
7 | // *
8 | @import 'ff/heiti'
9 | @import 'ff/songti'
10 | @import 'ff/kaiti'
11 | @import 'ff/fangsong'
12 | @import 'ff/biaodian'
13 |
14 | // * Western Specialties & numerals
15 | // *
16 | @import 'ff/italic'
17 | @import 'ff/numeral'
18 |
19 | // * Zhuyin & Romanisation
20 | // *
21 | @import 'ff/ruby'
22 |
23 |
--------------------------------------------------------------------------------
/src/js/locale/init-cond.js:
--------------------------------------------------------------------------------
1 | define([
2 | '../var/root',
3 | './core'
4 | ], function( root, Locale ) {
5 |
6 | Locale.initCond = function( target ) {
7 | var target = target || root
8 | var ret = ''
9 | var clazz
10 |
11 | for ( var feature in Locale.support ) {
12 | clazz = ( Locale.support[ feature ] ? '' : 'no-' ) + feature
13 |
14 | target.classList.add( clazz )
15 | ret += clazz + ' '
16 | }
17 | return ret
18 | }
19 |
20 | return Locale
21 | })
22 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "asi": true,
3 | "boss": true,
4 | "curly": true,
5 | "eqeqeq": true,
6 | "eqnull": true,
7 | "freeze": true,
8 | "expr": true,
9 | "immed": true,
10 | "noarg": true,
11 | "onevar": true,
12 | "quotmark": "single",
13 | "trailing": true,
14 |
15 | "latedef": "nofunc",
16 | "undef": true,
17 | "unused": true,
18 | "shadow": true,
19 |
20 | "sub": true,
21 |
22 | "browser": true,
23 |
24 | "globals": {
25 | "define": true,
26 | "module": true
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/demo/ruby(ff)-han.styl:
--------------------------------------------------------------------------------
1 | // **
2 | // * Import Han module
3 | // *
4 | @import '..'
5 |
6 | #zhuyin_fuhao-heiti p
7 | @extend $han-ligature
8 | font-family: "Zhuyin Heiti", "Biaodian Pro Sans", "Helvetica Neue", Helvetica, Arial, "Han Heiti", sans-serif
9 |
10 | #zhuyin_fuhao-kaiti p
11 | @extend $han-ligature
12 | font-family: "Zhuyin Kaiti", "Biaodian Pro Serif", Georgia, "Times New Roman", "Han Kaiti", cursive, serif
13 |
14 | #luoma_pinyin p,
15 | #pua p
16 | @extend $han-ligature
17 | font-family: "Romanization Sans", "Biaodian Pro Sans", "Helvetica Neue", Helvetica, Arial, "Han Heiti", sans-serif
18 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Han",
3 | "version": "3.3.0",
4 | "homepage": "http://css.hanzi.co/",
5 | "authors": [
6 | "Chen Yijun (@ethantw)"
7 | ],
8 | "description": "The CSS typography framework optimised for Hanzi.",
9 | "main": [ "dist/han.css", "dist/han.js" ],
10 | "keywords": [
11 | "Hanzi",
12 | "CJK",
13 | "normalize",
14 | "typography",
15 | "typesetting"
16 | ],
17 | "license": "MIT",
18 | "ignore": [
19 | "**/.*",
20 | "build",
21 | "node_modules",
22 | "test",
23 | "package.json",
24 | "component.json",
25 | "CHANGELOG.md"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/src/styl/api.styl:
--------------------------------------------------------------------------------
1 |
2 | han-header-i($max = 1, $min = 6)
3 | $ret = ""
4 | for $i in ($max)..($min)
5 | if $i != $min
6 | $ret = $ret + "h" + $i + ", "
7 | else
8 | $ret = $ret + "h" + $i
9 | $ret
10 | han-text-emphasis($posi = under, $mark = circle, $shape = filled, $color = inherit, $skip = true, $extend = true)
11 | han-text-emphasis-internal($posi, $mark, $shape, $color)
12 | han-text-emphasis-pf($posi, $mark, $shape, $color, $skip, $extend)
13 |
14 | han-section-counter($toc = false)
15 | &
16 | @extend $han-section-counter
17 | if $toc
18 | ol.toc
19 | @extend $han-toc-counter
20 |
--------------------------------------------------------------------------------
/src/js/typeface.js:
--------------------------------------------------------------------------------
1 | define([
2 | './method',
3 | './core',
4 | './locale'
5 | ], function( $, Han ) {
6 |
7 | $.extend( Han.support, {
8 | // Assume that all devices support Heiti for we
9 | // use `sans-serif` to do the comparison.
10 | heiti: true,
11 | // 'heiti-gb': true,
12 |
13 | songti: Han.detectFont( '"Han Songti"' ),
14 | 'songti-gb': Han.detectFont( '"Han Songti GB"' ),
15 |
16 | kaiti: Han.detectFont( '"Han Kaiti"' ),
17 | // 'kaiti-gb': Han.detectFont( '"Han Kaiti GB"' ),
18 |
19 | fangsong: Han.detectFont( '"Han Fangsong"' )
20 | // 'fangsong-gb': Han.detectFont( '"Han Fangsong GB"' )
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/src/sass/inline/_subst.sass:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * The ‘Display-As’ feature for presentational characters
4 | */
5 |
6 | // * 1. Hidden (but copyable) in `inner` containers for
7 | // * pseudo elements to do the display.
8 | // *
9 | h-char[display-as]
10 | // position
11 | position: relative
12 | // box
13 | display: inline-block
14 |
15 | // 1
16 | h-inner
17 | color: transparent
18 |
19 | &:after
20 | // position
21 | position: absolute
22 | left: 0
23 | // box
24 | display: inline-block
25 | // typography
26 | content: attr( display-as )
27 |
28 | &.comb-liga:after
29 | font-family: 'Romanization Sans', 'Zhuyin Kaiti'
30 |
31 |
--------------------------------------------------------------------------------
/src/styl/inline/subst.styl:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * The ‘Display-As’ feature for presentational characters
4 | */
5 |
6 | // * 1. Hidden (but copyable) in `inner` containers for
7 | // * pseudo elements to do the display.
8 | // *
9 | h-char[display-as]
10 | // position
11 | position: relative
12 | // box
13 | display: inline-block
14 |
15 | // 1
16 | h-inner
17 | color: transparent
18 |
19 | &:after
20 | // position
21 | position: absolute
22 | left: 0
23 | // box
24 | display: inline-block
25 | // typography
26 | content: attr( display-as )
27 |
28 | &.comb-liga:after
29 | font-family: 'Romanization Sans', 'Zhuyin Kaiti'
30 |
31 |
--------------------------------------------------------------------------------
/src/js/dom-ready.js:
--------------------------------------------------------------------------------
1 | define([
2 | './var/root',
3 | './core',
4 | './locale'
5 | ], function( root, Han ) {
6 |
7 | window.addEventListener( 'DOMContentLoaded', function() {
8 | var initContext
9 |
10 | // Use the shortcut under the default situation
11 | if ( root.classList.contains( 'han-init' )) {
12 | Han.init()
13 |
14 | // Consider ‘a configured context’ the special
15 | // case of the default situation. Will have to
16 | // replace the `Han.init` with the instance as
17 | // well (for future usage).
18 | } else if ( initContext = document.querySelector( '.han-init-context' )) {
19 | Han.init = Han( initContext ).render()
20 | }
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/src/js/intro.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * 漢字標準格式 v@VERSION | MIT License | css.hanzi.co
3 | * Han.css: the CSS typography framework optimised for Hanzi
4 | */
5 |
6 | void function( global, factory ) {
7 |
8 | // CommonJS
9 | if ( typeof module === 'object' && typeof module.exports === 'object' ) {
10 | module.exports = factory( global, true )
11 | // AMD
12 | } else if ( typeof define === 'function' && define.amd ) {
13 | define(function() { return factory( global, true ) })
14 | // Global namespace
15 | } else {
16 | factory( global )
17 | }
18 |
19 | }( typeof window !== 'undefined' ? window : this, function( window, noGlobalNS ) {
20 |
21 | 'use strict'
22 |
23 |
--------------------------------------------------------------------------------
/src/sass/_api.sass:
--------------------------------------------------------------------------------
1 |
2 | @function han-header-i( $max: 1, $min: 6 )
3 | $ret: ''
4 | @for $i from $max through $min
5 | @if ( $i != $min )
6 | $ret: $ret + 'h' + $i + ', '
7 | @else
8 | $ret: $ret + 'h' + $i
9 | @return $ret
10 |
11 | =han-text-emphasis( $posi: under, $mark: circle, $shape: filled, $color: inherit, $skip: true, $extend: true )
12 | +han-text-emphasis-internal( $posi, $mark, $shape, $color )
13 | +han-text-emphasis-pf( $posi, $mark, $shape, $color, $skip, $extend )
14 |
15 | =han-section-counter( $toc: false )
16 | &
17 | @extend %han-section-counter
18 |
19 | @if ( $toc )
20 | ol.toc
21 | @extend %han-toc-counter
22 |
23 |
--------------------------------------------------------------------------------
/src/styl/typography/ff/range.styl:
--------------------------------------------------------------------------------
1 |
2 | // * CJK-related blocks
3 | // *
4 | han-range-cjk()
5 | unicode-range: U+4E00-9FFF, U+3400-4DB5, U+20000-2A6D6, U+2A700-2B734, U+2B740-2B81D, U+FA0E-FA0F, U+FA11, U+FA13-FA14, U+FA1F, U+FA21, U+FA23, U+FA24, U+FA27-FA29, U+3040-309F, U+30A0-30FF, U+3099-309E, U+FF66-FF9F, U+3007, U+31C0-31E3, U+2F00-2FD5, U+2E80-2EF3
6 |
7 | // * Numerals (0-9)
8 | // *
9 | han-range-numeral()
10 | unicode-range: U+0030-0039
11 |
12 | // * Zhuyin blocks
13 | // *
14 | han-range-zhuyin()
15 | unicode-range: U+3105-312D, U+31A0-31BA, U+02D9, U+02CA, U+02C5, U+02C7, U+02CB, U+02EA-02EB, U+0307, U+030D, U+0358, U+F31B4-F31B7, U+F0061, U+F0065, U+F0069, U+F006F, U+F0075
16 |
17 |
--------------------------------------------------------------------------------
/src/js/locale.js:
--------------------------------------------------------------------------------
1 | define([
2 | './core',
3 | './locale/locale'
4 | ], function( Han, Locale ) {
5 |
6 | Han.normalize = Locale
7 | Han.localize = Locale
8 | Han.support = Locale.support
9 | Han.detectFont = Locale.detectFont
10 |
11 | Han.fn.initCond = function() {
12 | this.condition.classList.add( 'han-js-rendered' )
13 | Han.normalize.initCond( this.condition )
14 | return this
15 | }
16 |
17 | void [
18 | 'Elem',
19 | 'DecoLine',
20 | 'Em',
21 | 'Ruby'
22 | ].forEach(function( elem ) {
23 | var method = 'render' + elem
24 |
25 | Han.fn[ method ] = function( target ) {
26 | Han.normalize[ method ]( this.context, target )
27 | return this
28 | }
29 | })
30 |
31 | return Han
32 | })
33 |
--------------------------------------------------------------------------------
/src/styl/locale/const.styl:
--------------------------------------------------------------------------------
1 |
2 | // *!
3 | // * **WARNING**
4 | // * Unless you knew well enough, *nothing* below should
5 | // * be modified!
6 | // *
7 |
8 | $HAN-ROOT = html
9 | $HAN-LINE-HEIGHT = 1.3
10 | $HAN-INDENT = 2em
11 | $HAN-JS-RENDERED-CLASS = '.han-js-rendered'
12 |
13 | $HAN-TEXT-EMPHASIS-SKIP = true
14 |
15 | $HAN-TEXT-EMPHASIS-SHAPE = filled
16 | $HAN-TEXT-EMPHASIS-MARK = circle
17 | $HAN-TEXT-EMPHASIS-POSI = under
18 | $HAN-TEXT-EMPHASIS-COLOR = inherit
19 |
20 | $HAN-TEXT-EMPHASIS-SHAPE-JA = filled
21 | $HAN-TEXT-EMPHASIS-MARK-JA = sesame
22 | $HAN-TEXT-EMPHASIS-POSI-JA = over
23 | $HAN-TEXT-EMPHASIS-COLOR-JA = inherit
24 |
25 | $HAN-ZHUYIN-SIZE = .4
26 |
27 |
--------------------------------------------------------------------------------
/src/styl/typography/ff/fangsong.styl:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * The Four Typefaces: Fangsong
4 | * 四大字體集・仿宋體
5 | */
6 |
7 | // * 1. Recommended (推薦傳統字形,適用繁體漢字)
8 | // * 2. CNS (台灣教育部國字標準字體[字形])
9 | // * 3. GB (中國國家標準)
10 |
11 | // 1
12 | @font-face {
13 | han-range-cjk();
14 | font-family: 'Han Fangsong';
15 | src:
16 | local(STFangsong),
17 | local(FangSong);
18 | }
19 |
20 | // 2
21 | @font-face {
22 | han-range-cjk();
23 | font-family: 'Han Fangsong CNS';
24 | src:
25 | local(STFangsong),
26 | local(FangSong);
27 | }
28 |
29 | // 3
30 | @font-face {
31 | han-range-cjk();
32 | font-family: 'Han Fangsong GB';
33 | src:
34 | local(STFangsong),
35 | local(FangSong);
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/src/sass/locale/_const.sass:
--------------------------------------------------------------------------------
1 |
2 | // *!
3 | // * **WARNING**
4 | // * Unless you knew well enough, *nothing* below should
5 | // * be modified!
6 | // *
7 |
8 | $HAN-ROOT: html
9 | $HAN-LINE-HEIGHT: 1.3
10 | $HAN-INDENT: 2em
11 | $HAN-JS-RENDERED-CLASS: '.han-js-rendered'
12 |
13 | $HAN-TEXT-EMPHASIS-SKIP: true
14 |
15 | $HAN-TEXT-EMPHASIS-SHAPE: filled
16 | $HAN-TEXT-EMPHASIS-MARK: circle
17 | $HAN-TEXT-EMPHASIS-POSI: under
18 | $HAN-TEXT-EMPHASIS-COLOR: inherit
19 |
20 | $HAN-TEXT-EMPHASIS-SHAPE-JA: filled
21 | $HAN-TEXT-EMPHASIS-MARK-JA: sesame
22 | $HAN-TEXT-EMPHASIS-POSI-JA: over
23 | $HAN-TEXT-EMPHASIS-COLOR-JA: inherit
24 |
25 | $HAN-ZHUYIN-SIZE: .4
26 |
27 |
--------------------------------------------------------------------------------
/.csscomb.json:
--------------------------------------------------------------------------------
1 | {
2 | "remove-empty-rulesets": true,
3 | "color-case": "lower",
4 | "block-indent": " ",
5 | "color-shorthand": true,
6 | "element-case": "lower",
7 | "eof-newline": true,
8 | "quotes": "double",
9 | "leading-zero": false,
10 | "sort-order-fallback": "abc",
11 | "space-after-colon": " ",
12 | "space-before-combinator": " ",
13 | "space-after-combinator": " ",
14 | "space-between-declarations": "\n",
15 | "space-before-opening-brace": " ",
16 | "space-after-opening-brace": "\n",
17 | "space-after-selector-delimiter": "\n",
18 | "space-before-selector-delimiter": "",
19 | "space-before-closing-brace": "\n",
20 | "strip-spaces": true,
21 | "tab-size": true,
22 | "unitless-zero": true,
23 | "vendor-prefix-align": false
24 | }
25 |
--------------------------------------------------------------------------------
/src/styl/inline/hws.styl:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Hanzi and Western script mixed spacing (漢字西文混排間隙)
4 | *
5 | * More discussion at:
6 | * https://github.com/ethantw/Han/issues/40
7 | */
8 | // * 1. The value is calculated with Arial, which
9 | // * makes the spacing display precisely in size
10 | // * of a quarter em.
11 | // * 2. Hidden in certain elements or situations.
12 | // *
13 | h-hws,
14 | h-hws[hidden]
15 | &
16 | // box
17 | display: inline
18 | // typography
19 | font-family: Arial
20 | &:before
21 | content: ' '
22 | // 1
23 | letter-spacing: -.04em
24 |
25 | // 2
26 | code &,
27 | kbd &,
28 | samp &,
29 | pre &,
30 | &.quote-inner,
31 | &.quote-outer:lang(zh-Hans),
32 | &.quote-outer:lang(zh-CN)
33 | display: none
34 |
--------------------------------------------------------------------------------
/src/sass/inline/_hws.sass:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Hanzi and Western script mixed spacing (漢字西文混排間隙)
4 | *
5 | * More discussion at:
6 | * https://github.com/ethantw/Han/issues/40
7 | */
8 |
9 | // * 1. The value is calculated with Arial, which
10 | // * makes the spacing display precisely in size
11 | // * of a quarter em.
12 | // * 2. Hidden in certain elements or situations.
13 | // *
14 | h-hws,
15 | h-hws[hidden]
16 | &
17 | // box
18 | display: inline
19 | // typography
20 | font-family: Arial
21 | &:before
22 | content: ' '
23 | // 1
24 | letter-spacing: -.04em
25 |
26 | // 2
27 | code &,
28 | kbd &,
29 | samp &,
30 | pre &,
31 | &.quote-inner,
32 | &.quote-outer:lang(zh-Hans),
33 | &.quote-outer:lang(zh-CN)
34 | display: none
35 |
36 |
--------------------------------------------------------------------------------
/src/sass/typography/ff/_fangsong.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * The Four Typefaces: Fangsong
4 | * 四大字體集・仿宋體
5 | */
6 |
7 | // * 1. Recommended (推薦傳統字形,適用繁體漢字)
8 | // * 2. CNS (台灣教育部國字標準字體[字形])
9 | // * 3. GB (中國國家標準)
10 |
11 | // 1
12 | @font-face {
13 | @include han-range-cjk;
14 | font-family: 'Han Fangsong';
15 | src:
16 | local(STFangsong),
17 | local(FangSong)
18 | ;
19 | }
20 |
21 | // 2
22 | @font-face {
23 | @include han-range-cjk;
24 | font-family: 'Han Fangsong CNS';
25 | src:
26 | local(STFangsong),
27 | local(FangSong)
28 | ;
29 | }
30 |
31 | // 3
32 | @font-face {
33 | @include han-range-cjk;
34 | font-family: 'Han Fangsong GB';
35 | src:
36 | local(STFangsong),
37 | local(FangSong)
38 | ;
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | API tests for han.js
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/js/regex.js:
--------------------------------------------------------------------------------
1 | define([
2 | './core',
3 | './regex/unicode',
4 | './regex/typeset'
5 | ], function( Han, UNICODE, TYPESET ) {
6 |
7 | Han.UNICODE = UNICODE
8 | Han.TYPESET = TYPESET
9 |
10 | // Aliases
11 | Han.UNICODE.cjk = Han.UNICODE.hanzi
12 | Han.UNICODE.greek = Han.UNICODE.ellinika
13 | Han.UNICODE.cyrillic = Han.UNICODE.kirillica
14 | Han.UNICODE.hangul = Han.UNICODE.eonmun
15 | Han.UNICODE.zhuyin.ruyun = Han.UNICODE.zhuyin.checked
16 |
17 | Han.TYPESET.char.cjk = Han.TYPESET.char.hanzi
18 | Han.TYPESET.char.greek = Han.TYPESET.char.ellinika
19 | Han.TYPESET.char.cyrillic = Han.TYPESET.char.kirillica
20 | Han.TYPESET.char.hangul = Han.TYPESET.char.eonmun
21 |
22 | Han.TYPESET.group.hangul = Han.TYPESET.group.eonmun
23 | Han.TYPESET.group.cjk = Han.TYPESET.group.hanzi
24 |
25 | return Han
26 | })
27 |
--------------------------------------------------------------------------------
/src/sass/_typeset.sass:
--------------------------------------------------------------------------------
1 |
2 | /* Global
3 | -------- */
4 |
5 | @if ( $han-line-height != $HAN-LINE-HEIGHT )
6 | #{$han-root}
7 | line-height: $han-line-height
8 |
9 | // * Styles for alternative voice and variables when
10 | // * Kaiti (cursive) isn't supported.
11 | // *
12 | i,
13 | var
14 | .no-kaiti &
15 | // box
16 | padding-bottom: .05em
17 | // style
18 | border-bottom: 3px double lightgrey
19 |
20 | // * Zhuyin ruby size
21 | // *
22 | @if ( $han-zhuyin-size != $HAN-ZHUYIN-SIZE )
23 | ruby.zhuyin,
24 | ruby.mps
25 | +han-scale( $han-zhuyin-size/.5, 'left center' )
26 |
27 | [zhuyin] h-zhuyin > *
28 | +han-scale( $han-zhuyin-size )
29 |
30 | /* Section-wise arrangement
31 | -------------------------- */
32 |
33 | @import section/well-knit
34 | @import section/counter
35 |
36 | /* Line composition
37 | ------------------ */
38 |
39 | @import inline/em
40 | @import inline/hws
41 | @import inline/hanging
42 | @import inline/jiya
43 | @import inline/subst
44 |
45 |
--------------------------------------------------------------------------------
/src/styl/typeset.styl:
--------------------------------------------------------------------------------
1 |
2 | /* Global
3 | * -------- */
4 |
5 | if $han-line-height != $HAN-LINE-HEIGHT
6 | {$han-root}
7 | line-height: $han-line-height
8 |
9 | // * Styles for alternative voice and variables when
10 | // * Kaiti (cursive) isn't supported.
11 | // *
12 | i,
13 | var
14 | .no-kaiti &
15 | // box
16 | padding-bottom: 0.05em
17 | // style
18 | border-bottom: 3px double lightgrey
19 |
20 | // * Zhuyin ruby size
21 | // *
22 | if $han-zhuyin-size != $HAN-ZHUYIN-SIZE
23 | ruby.zhuyin,
24 | ruby.mps
25 | han-scale( $han-zhuyin-size/.5, 'left center' )
26 |
27 | [zhuyin] h-zhuyin > *
28 | han-scale( $han-zhuyin-size )
29 |
30 | /* Section-wise arrangement
31 | * -------------------------- */
32 |
33 | @import 'section/well-knit'
34 | @import 'section/counter'
35 |
36 | /* Line composition
37 | * ------------------ */
38 |
39 | @import 'inline/em'
40 | @import 'inline/hws'
41 | @import 'inline/hanging'
42 | @import 'inline/jiya'
43 | @import 'inline/subst'
44 |
45 |
--------------------------------------------------------------------------------
/src/styl/typography/extend/mono.styl:
--------------------------------------------------------------------------------
1 |
2 | $han-mono
3 | font-family: $han-mono, han-typeface("Han Heiti", $_default-variant, $han-mono-zh), monospace, monospace, sans-serif
4 |
5 | $han-mono-hant
6 | font-family: han-biaodian(Sans, $han-biaodian-hant), $han-mono, "Zhuyin Heiti", han-typeface("Han Heiti", $han-glyph-set-hant, $han-mono-zh), monospace, monospace, sans-serif
7 |
8 | $han-mono-hant-nu
9 | font-family: $han-mono, han-typeface("Han Heiti", $han-glyph-set-hant, $han-mono-zh), monospace, monospace, sans-serif
10 |
11 | $han-mono-hans
12 | font-family: han-biaodian(Sans, $han-biaodian-hans), $han-mono, han-typeface("Han Heiti", $han-glyph-set-hans, $han-mono-zh), monospace, monospace, sans-serif
13 |
14 | $han-mono-hans-nu
15 | font-family: $han-mono, han-typeface("Han Heiti", $han-glyph-set-hans, $han-mono-zh), monospace, monospace, sans-serif
16 |
17 | $han-mono-ja
18 | font-family: "Yakumono Sans", $han-mono, monospace, monospace, sans-serif
19 |
20 | $han-mono-ja-nu
21 | font-family: $han-mono, monospace, monospace, sans-serif
22 |
--------------------------------------------------------------------------------
/src/styl/var/internal.styl:
--------------------------------------------------------------------------------
1 |
2 | // *!
3 | // * **WARNING**
4 | // * Unless you knew well enough, *nothing* below should
5 | // * be modified!
6 | // *
7 | $han-version = "@VERSION"
8 |
9 | $han-webfont ?= url($han-font-path + 'han.woff2?' + $han-version) format("woff2"), url($han-font-path + 'han.woff?' + $han-version) format("woff"), url($han-font-path + 'han.otf?' + $han-version) format("opentype")
10 | $han-space-webfont ?= url($han-font-path + 'han-space.woff2?' + $han-version) format("woff2"), url($han-font-path + 'han-space.woff?' + $han-version) format("woff"), url($han-font-path + 'han-space.otf?' + $han-version) format("opentype")
11 |
12 | $_hanging-hant = "h-char.bd-hangable:lang(zh), h-char.bd-hangable:lang(zh-Hant), h-char.bd-hangable:lang(zh-TW), h-char.bd-hangable:lang(zh-HK), "
13 | $_hanging-hans = "h-char.bd-hangable:lang(zh-Hans), h-char.bd-hangable:lang(zh-CN), "
14 | $han-hanging-selector = ($han-hanging-hant ? $_hanging-hant : "") + ($han-hanging-hans ? $_hanging-hans : "") + ($han-hanging-ja ? "h-char.bd-hangable:lang(ja)" : "")
15 |
16 |
--------------------------------------------------------------------------------
/src/sass/var/_internal.sass:
--------------------------------------------------------------------------------
1 |
2 | // *!
3 | // * **WARNING**
4 | // * Unless you knew well enough, *nothing* below should
5 | // * be modified!
6 | // *
7 |
8 | $han-version: '@VERSION'
9 |
10 | $han-webfont: url(#{$han-font-path}han.woff2?#{$han-version}) format('woff2'), url(#{$han-font-path}han.woff?#{$han-version}) format('woff'), url(#{$han-font-path}han.otf?#{$han-version}) format('opentype') !default
11 | $han-space-webfont: url(#{$han-font-path}han-space.woff2?#{$han-version}) format('woff2'), url(#{$han-font-path}han-space.woff?#{$han-version}) format('woff'), url(#{$han-font-path}han-space.otf?#{$han-version}) format('opentype') !default
12 |
13 | $_hanging-hant: 'h-char.bd-hangable:lang(zh), h-char.bd-hangable:lang(zh-Hant), h-char.bd-hangable:lang(zh-TW), h-char.bd-hangable:lang(zh-HK), '
14 | $_hanging-hans: 'h-char.bd-hangable:lang(zh-Hans), h-char.bd-hangable:lang(zh-CN), '
15 |
16 | $han-hanging-selector: if( $han-hanging-hant, $_hanging-hant, '' ) + if( $han-hanging-hans, $_hanging-hans, '' ) + if( $han-hanging-ja, 'h-char.bd-hangable:lang(ja)', '' )
17 |
18 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 |
2 | Copyright (c) 2016 Chen Yijun (陳奕鈞,http://yijun.me/)
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9 |
--------------------------------------------------------------------------------
/src/styl/typography/mixin.styl:
--------------------------------------------------------------------------------
1 |
2 | han-webfont()
3 | src: $han-webfont
4 |
5 | han-typeface-by-lang($typeface = sans, $is-root = false)
6 | &:lang(zh),
7 | &:lang(zh-Hant)
8 | @extend $han-{$typeface}-hant
9 | if $is-root
10 | &.no-unicoderange
11 | @extend $han-{$typeface}-hant-nu
12 | else
13 | .no-unicoderange &
14 | @extend $han-{$typeface}-hant-nu
15 | &:lang(zh-Hans),
16 | &:lang(zh-CN)
17 | @extend $han-{$typeface}-hans
18 | if $is-root
19 | &.no-unicoderange
20 | @extend $han-{$typeface}-hans-nu
21 | else
22 | .no-unicoderange &
23 | @extend $han-{$typeface}-hans-nu
24 | &:lang(ja)
25 | @extend $han-{$typeface}-ja
26 | if $is-root
27 | &.no-unicoderange
28 | @extend $han-{$typeface}-ja-nu
29 | else
30 | .no-unicoderange &
31 | @extend $han-{$typeface}-ja-nu
32 | &:lang(zh-Latn),
33 | &:lang(ja-Latn),
34 | &:not(:lang(zh)):not(:lang(ja)),
35 | *:lang(zh-Latn),
36 | *:lang(ja-Latn),
37 | *:not(:lang(zh)):not(:lang(ja))
38 | @extend $han-{$typeface}
39 |
--------------------------------------------------------------------------------
/demo/README.md:
--------------------------------------------------------------------------------
1 | 測試頁索引
2 | ========
3 |
4 | - [測試頁(標準,繁體中文)](test.html)
5 | - [测试页(标准,简体中文)](test-hans.html)
6 | - [測試頁(標準,日本語)](test-ja.html)
7 | - [測試頁(AMD模組)](test-amd.html)
8 | - [測試頁(CommonJS模組,browserify)](test-commonjs.html)
9 | - [測試頁(無JavaScript)](test-nojs.html)
10 |
11 | ## Normalisation(樣式標準化)
12 |
13 | - [文字裝飾線元素](./deco-line.html)
14 | - [強調元素(着重號)](./em.html)
15 | - [行間注元素](./ruby.html)
16 |
17 | ## 字體
18 | ### 漢字
19 |
20 | - [標點符號](./biaodian.html)
21 | - [四大字體集](./four.html)
22 | - [字體基型(typeface generics)與@extend](./generics.html)
23 |
24 | ### 其他
25 |
26 | - [西文意大利體](./italic.html)
27 | - [數字](./numeral.html)
28 | - [標音(注音符號、羅馬拼音)](./ruby\(ff\).html)
29 |
30 | ## 排版
31 | ### 章節的組成
32 |
33 | - [文章、章節與內容的邊界調整](./well-knit.html)
34 | - [章節與目錄的計數](./counter.html)
35 |
36 | ### 行的組成
37 |
38 | - [漢字-西文混排間隙](./hws.html)
39 | - [標點擠壓](./jiya.html)
40 | - [行尾點號懸掛](./hanging.html)
41 | - [字元的替換](./subst.html)
42 |
43 |
52 |
--------------------------------------------------------------------------------
/src/styl/inline/hanging.styl:
--------------------------------------------------------------------------------
1 |
2 | @font-face
3 | src: $han-webfont
4 | font-family: 'Han Space'
5 | unicode-range: U+20
6 |
7 | unless $han-hanging-hant
8 | {$_hanging-hant}
9 | h-cs,
10 | h-cs[hidden]
11 | // box-model
12 | display: inline
13 | visibility: inherit
14 | // typography
15 | font-family: inherit
16 | font-size: inherit
17 |
18 | h-cs.hangable-outer,
19 | h-cs.hangable-outer[hidden]
20 | display: inline
21 | font: 1em 'Han Space'
22 |
23 | unless $han-hanging-hant
24 | &:lang(zh-Hant),
25 | &:lang(zh-TW),
26 | &:lang(zh-HK)
27 | display: none
28 |
29 | {$han-hanging-selector}
30 | // positioning
31 | position: relative
32 |
33 | &:after
34 | display: none !important
35 | &:before
36 | // box-model
37 | display: inline !important
38 | // typography
39 | content: ' '
40 | font: 1em 'Han Space', $han-mono
41 | > h-inner
42 | han-typo-reset()
43 | // positioning
44 | position: absolute
45 | left: 0
46 | top: 0
47 | // box-model
48 | display: inline-block
49 | // typography
50 | line-height: 1.1
51 |
52 | ruby &,
53 | h-ru &
54 | position: relative
55 |
56 |
--------------------------------------------------------------------------------
/src/sass/inline/_hanging.sass:
--------------------------------------------------------------------------------
1 |
2 | @font-face
3 | src: $han-webfont
4 | font-family: 'Han Space'
5 | unicode-range: U+20
6 |
7 | @if ( $han-hanging-hant == false )
8 | #{$_hanging-hant}
9 | h-cs,
10 | h-cs[hidden]
11 | // box-model
12 | display: inline
13 | visibility: inherit
14 | // typography
15 | font-family: inherit
16 | font-size: inherit
17 |
18 | h-cs.hangable-outer,
19 | h-cs.hangable-outer[hidden]
20 | display: inline
21 | font: 1em 'Han Space'
22 |
23 | @if ( $han-hanging-hant == false )
24 | &:lang(zh-Hant),
25 | &:lang(zh-TW),
26 | &:lang(zh-HK)
27 | display: none
28 |
29 | #{$han-hanging-selector}
30 | // positioning
31 | position: relative
32 |
33 | &:after
34 | display: none !important
35 | &:before
36 | // box-model
37 | display: inline !important
38 | // typography
39 | content: ' '
40 | font: 1em 'Han Space', $han-mono
41 | > h-inner
42 | +han-typo-reset()
43 | // positioning
44 | position: absolute
45 | left: 0
46 | top: 0
47 | // box-model
48 | display: inline-block
49 | // typography
50 | line-height: 1.1
51 |
52 | ruby &,
53 | h-ru &
54 | position: relative
55 |
56 |
--------------------------------------------------------------------------------
/src/styl/typography/extend.styl:
--------------------------------------------------------------------------------
1 |
2 | $_default-variant = ($han-default-variant == hans ? $han-glyph-set-hans : $han-glyph-set-hant)
3 |
4 | // **
5 | // * Functions
6 | // *
7 | han-biaodian($generic = Sans, $set = Pro)
8 | if $set is simp
9 | "Biaodian " + $generic
10 | else
11 | "Biaodian Pro " + ($set is Pro ? $generic : $generic + " " + $set)
12 |
13 | han-typeface($typeface = "Han Heiti", $set = default, $pre = null)
14 | $typeface = ($set == default ? $typeface : $typeface + " " + $set)
15 | $pre-type = $pre, $typeface
16 | ($pre == null or $pre == "" ? $typeface : $pre-type)
17 |
18 | @import 'extend/sans'
19 | @import 'extend/serif'
20 | @import 'extend/cursive'
21 | @import 'extend/mono'
22 |
23 | $han-ligature
24 | -moz-font-feature-settings: "liga"
25 | -ms-font-feature-settings: "liga"
26 | -webkit-font-feature-settings: "liga"
27 | font-feature-settings: "liga"
28 |
29 | // We do not need the `locl` property of OpenType typefaces,
30 | // for we have better fallback mechanism in Han.css.
31 | // (*Internal use with Source Han Sans only)
32 | $han-no-locl
33 | -moz-font-feature-settings: "liga=1, locl=0"
34 | -ms-font-feature-settings: "liga", "locl" 0
35 | -webkit-font-feature-settings: "liga", "locl" 0
36 | font-feature-settings: "liga", "locl" 0
37 |
38 |
--------------------------------------------------------------------------------
/src/sass/typography/_extend.sass:
--------------------------------------------------------------------------------
1 |
2 | $_default-variant: if( $han-default-variant == hans, $han-glyph-set-hans, $han-glyph-set-hant )
3 |
4 | // **
5 | // * Functions
6 | // *
7 | @function han-biaodian( $generic: Sans, $set: Pro )
8 | @if ( $set == simp )
9 | @return 'Biaodian ' + $generic
10 | @return 'Biaodian Pro ' + if( $set == Pro, $generic, $generic + ' ' + $set )
11 |
12 | @function han-typeface( $typeface: 'Han Heiti', $set: default, $pre: null )
13 | $typeface: if( $set == default, $typeface, $typeface + ' ' + $set )
14 | @return if( $pre == null or $pre == '', $typeface, ($pre, $typeface))
15 |
16 | @import extend/sans
17 | @import extend/serif
18 | @import extend/cursive
19 | @import extend/mono
20 |
21 | %han-ligature
22 | -moz-font-feature-settings: 'liga'
23 | -ms-font-feature-settings: 'liga'
24 | -webkit-font-feature-settings: 'liga'
25 | font-feature-settings: 'liga'
26 |
27 | // We do not need the `locl` property of OpenType typefaces,
28 | // for we have better fallback mechanism in Han.css.
29 | // (*Internal use with Source Han Sans only)
30 | %han-no-locl
31 | -moz-font-feature-settings: 'liga=1, locl=0'
32 | -ms-font-feature-settings: 'liga', 'locl' 0
33 | -webkit-font-feature-settings: 'liga', 'locl' 0
34 | font-feature-settings: 'liga', 'locl' 0
35 |
36 |
--------------------------------------------------------------------------------
/demo/shs.html:
--------------------------------------------------------------------------------
1 | 測試・思源黑體 — 漢字標準格式測試·思源黑體
標題與內文
阿波羅11號(Apollo 11)是美國國家航空航天局的阿波羅計畫(Project Apollo)中的第五次載人任務,是人類第一次登月任務,歷時8天13小時18分35秒,繞行月球30周,在月表停留21小時36分20秒。三位執行此任務的宇航員分別為指令長尼爾·阿姆斯特朗、指令艙駕駛員邁克爾·科林斯與登月艙駕駛員巴茲·奧爾德林。1969年7月20日,阿姆斯特朗與奧爾德林成為了首次踏上月球的人類,而阿波羅11號登陸月球一事更進一步成為紀錄片和廣告常見之歷史事件。
字重
鵝,是企鵝家族中體型最大的屬種,成年皇帝企鵝身高可達120厘米,體重可達46千克。在皇帝企鵝發現之前,有一種企鵝被認為是最大的企鵝,取名為國王企鵝。
--------------------------------------------------------------------------------
/src/styl/inline/em.styl:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Customised emphasis mark (着重號)
4 | */
5 | em:lang(zh)
6 | $posi = null
7 | $mark = null
8 | $shape = null
9 | $color = null
10 | $skip = $han-text-emphasis-skip
11 | if $han-text-emphasis-mark != $HAN-TEXT-EMPHASIS-MARK or $han-text-emphasis-shape != $HAN-TEXT-EMPHASIS-SHAPE
12 | $mark = $han-text-emphasis-mark
13 | $shape = $han-text-emphasis-shape
14 | if $han-text-emphasis-posi != $HAN-TEXT-EMPHASIS-POSI
15 | $posi = $han-text-emphasis-posi
16 | if $han-text-emphasis-color != $HAN-TEXT-EMPHASIS-COLOR
17 | $color = $han-text-emphasis-color
18 | han-text-emphasis($posi, $mark, $shape, $color, $skip, false)
19 |
20 | em:lang(ja)
21 | $posi = null
22 | $mark = null
23 | $shape = null
24 | $color = null
25 | $skip = $han-text-emphasis-skip
26 | if $han-text-emphasis-mark-ja != $HAN-TEXT-EMPHASIS-MARK-JA or $han-text-emphasis-shape-ja != $HAN-TEXT-EMPHASIS-SHAPE-JA
27 | $mark = $han-text-emphasis-mark-ja
28 | $shape = $han-text-emphasis-shape-ja
29 | if $han-text-emphasis-posi-ja != $HAN-TEXT-EMPHASIS-POSI-JA
30 | $posi = $han-text-emphasis-posi-ja
31 | if $han-text-emphasis-color-ja != $HAN-TEXT-EMPHASIS-COLOR-JA
32 | $color = $han-text-emphasis-color-ja
33 | han-text-emphasis($posi, $mark, $shape, $color, $skip, false)
34 |
35 |
--------------------------------------------------------------------------------
/src/styl/typography/ff/italic.styl:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Western Italic Serif
4 | */
5 | @font-face {
6 | font-family: 'Latin Italic Serif';
7 | src:
8 | local('Georgia Italic'),
9 | local('Times New Roman Italic'),
10 | local(Georgia-Italic),
11 | local(TimesNewRomanPS-ItalicMT),
12 | local(Times-Italic);
13 | }
14 |
15 | @font-face {
16 | font-family: 'Latin Italic Serif';
17 | font-weight: 700;
18 | src:
19 | local('Georgia Bold Italic'),
20 | local('Times New Roman Bold Italic'),
21 | local(Georgia-BoldItalic),
22 | local(TimesNewRomanPS-BoldItalicMT),
23 | local(Times-Italic);
24 | }
25 |
26 | /**
27 | * Western italic sans-serif
28 | */
29 | @font-face {
30 | font-family: 'Latin Italic Sans';
31 | src:
32 | local('Helvetica Neue Italic'),
33 | local('Helvetica Oblique'),
34 | local('Arial Italic'),
35 | local(HelveticaNeue-Italic),
36 | local(Helvetica-LightOblique),
37 | local(Arial-ItalicMT);
38 | }
39 |
40 | @font-face {
41 | font-family: 'Latin Italic Sans';
42 | font-weight: 700;
43 | src:
44 | local('Helvetica Neue Bold Italic'),
45 | local('Helvetica Bold Oblique'),
46 | local('Arial Bold Italic'),
47 | local(HelveticaNeue-BoldItalic),
48 | local(Helvetica-BoldOblique),
49 | local(Arial-BoldItalicMT);
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/src/styl/typography/ff/ruby.styl:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Zhuyin Kaiti
4 | */
5 |
6 | @font-face {
7 | han-webfont();
8 | han-range-zhuyin();
9 | font-family: 'Zhuyin Kaiti';
10 | }
11 |
12 | /**
13 | * Zhuyin Heiti
14 | */
15 |
16 | // * 1. Medial ‘yi’ (介音「ㄧ」)
17 | // * 2. Tones (五聲調號)
18 | // *
19 |
20 | @font-face {
21 | han-range-zhuyin();
22 | font-family: 'Zhuyin Heiti';
23 | src:
24 | local('Hiragino Sans GB'),
25 | local('Heiti TC'),
26 | local('Microsoft Jhenghei'),
27 | $han-webfont;
28 | }
29 |
30 | // 1
31 | @font-face {
32 | font-family: 'Zhuyin Heiti';
33 | src:
34 | local('Heiti TC'),
35 | local('Microsoft Jhenghei'),
36 | $han-webfont;
37 | unicode-range: U+3127;
38 | }
39 |
40 | // 2
41 | @font-face {
42 | han-webfont();
43 | font-family: 'Zhuyin Heiti';
44 | unicode-range:
45 | U+02D9, U+02CA, U+02C5, U+02C7, U+02CB, U+02EA-02EB,
46 | U+31B4, U+31B5, U+31B6, U+31B7, U+0307, U+030D, U+0358,
47 | U+F31B4-F31B7,
48 | U+F0061, U+F0065, U+F0069, U+F006F, U+F0075;
49 | }
50 |
51 | /**
52 | * Romanisation (checked tone ligature [陽入韻連字])
53 | */
54 | @font-face {
55 | han-webfont();
56 | font-family: 'Romanization Sans';
57 | unicode-range:
58 | U+0307, U+030D, U+0358,
59 | U+F31B4-F31B7,
60 | U+F0061, U+F0065, U+F0069, U+F006F, U+F0075;
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/src/sass/typography/ff/_italic.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Western Italic Serif
4 | */
5 | @font-face {
6 | font-family: 'Latin Italic Serif';
7 | src:
8 | local('Georgia Italic'),
9 | local('Times New Roman Italic'),
10 | local(Georgia-Italic),
11 | local(TimesNewRomanPS-ItalicMT),
12 | local(Times-Italic)
13 | ;
14 | }
15 |
16 | @font-face {
17 | font-family: 'Latin Italic Serif';
18 | font-weight: 700;
19 | src:
20 | local('Georgia Bold Italic'),
21 | local('Times New Roman Bold Italic'),
22 | local(Georgia-BoldItalic),
23 | local(TimesNewRomanPS-BoldItalicMT),
24 | local(Times-Italic)
25 | ;
26 | }
27 |
28 | /**
29 | * Western italic sans-serif
30 | */
31 | @font-face {
32 | font-family: 'Latin Italic Sans';
33 | src:
34 | local('Helvetica Neue Italic'),
35 | local('Helvetica Oblique'),
36 | local('Arial Italic'),
37 | local(HelveticaNeue-Italic),
38 | local(Helvetica-LightOblique),
39 | local(Arial-ItalicMT)
40 | ;
41 | }
42 |
43 | @font-face {
44 | font-family: 'Latin Italic Sans';
45 | font-weight: 700;
46 | src:
47 | local('Helvetica Neue Bold Italic'),
48 | local('Helvetica Bold Oblique'),
49 | local('Arial Bold Italic'),
50 | local(HelveticaNeue-BoldItalic),
51 | local(Helvetica-BoldOblique),
52 | local(Arial-BoldItalicMT)
53 | ;
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/src/sass/typography/_mixin.scss:
--------------------------------------------------------------------------------
1 |
2 | @mixin han-webfont {
3 | src: $han-webfont;
4 | }
5 |
6 | @mixin han-typeface-by-lang( $typeface: sans, $is-root: false ) {
7 | &:lang(zh),
8 | &:lang(zh-Hant) {
9 | @extend %han-#{$typeface}-hant;
10 |
11 | @if ( $is-root ) {
12 | &.no-unicoderange {
13 | @extend %han-#{$typeface}-hant-nu;
14 | }
15 | } @else {
16 | .no-unicoderange & {
17 | @extend %han-#{$typeface}-hant-nu;
18 | }
19 | }
20 | }
21 | &:lang(zh-Hans),
22 | &:lang(zh-CN) {
23 | @extend %han-#{$typeface}-hans;
24 |
25 | @if ( $is-root ) {
26 | &.no-unicoderange {
27 | @extend %han-#{$typeface}-hans-nu;
28 | }
29 | } @else {
30 | .no-unicoderange & {
31 | @extend %han-#{$typeface}-hans-nu;
32 | }
33 | }
34 | }
35 | &:lang(ja) {
36 | @extend %han-#{$typeface}-ja;
37 |
38 | @if ( $is-root ) {
39 | &.no-unicoderange {
40 | @extend %han-#{$typeface}-ja-nu;
41 | }
42 | } @else {
43 | .no-unicoderange & {
44 | @extend %han-#{$typeface}-ja-nu;
45 | }
46 | }
47 | }
48 | &:lang(zh-Latn),
49 | &:lang(ja-Latn),
50 | &:not(:lang(zh)):not(:lang(ja)),
51 | *:lang(zh-Latn),
52 | *:lang(ja-Latn),
53 | *:not(:lang(zh)):not(:lang(ja)) {
54 | @extend %han-#{$typeface};
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/src/sass/typography/extend/_mono.scss:
--------------------------------------------------------------------------------
1 |
2 | %han-mono {
3 | font-family:
4 | $han-mono,
5 | han-typeface( 'Han Heiti', $_default-variant, $han-mono-zh ),
6 | monospace, monospace, sans-serif
7 | ;
8 | }
9 |
10 | %han-mono-hant {
11 | font-family:
12 | han-biaodian( Sans, $han-biaodian-hant ),
13 | $han-mono,
14 | 'Zhuyin Heiti',
15 | han-typeface( 'Han Heiti', $han-glyph-set-hant, $han-mono-zh ),
16 | monospace, monospace, sans-serif
17 | ;
18 | }
19 |
20 | %han-mono-hant-nu {
21 | font-family:
22 | $han-mono,
23 | han-typeface( 'Han Heiti', $han-glyph-set-hant, $han-mono-zh ),
24 | monospace, monospace, sans-serif
25 | ;
26 | }
27 |
28 | %han-mono-hans {
29 | font-family:
30 | han-biaodian( Sans, $han-biaodian-hans ),
31 | $han-mono,
32 | han-typeface( 'Han Heiti', $han-glyph-set-hans, $han-mono-zh ),
33 | monospace, monospace, sans-serif
34 | ;
35 | }
36 |
37 | %han-mono-hans-nu {
38 | font-family:
39 | $han-mono,
40 | han-typeface( 'Han Heiti', $han-glyph-set-hans, $han-mono-zh ),
41 | monospace, monospace, sans-serif
42 | ;
43 | }
44 |
45 | %han-mono-ja {
46 | font-family:
47 | 'Yakumono Sans',
48 | $han-mono,
49 | monospace, monospace, sans-serif
50 | ;
51 | }
52 |
53 | %han-mono-ja-nu {
54 | font-family: $han-mono, monospace, monospace, sans-serif;
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/src/sass/inline/_em.sass:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Customised emphasis mark (着重號)
4 | */
5 | em:lang(zh)
6 | $posi: null
7 | $mark: null
8 | $shape: null
9 | $color: null
10 | $skip: $han-text-emphasis-skip
11 |
12 | @if ( $han-text-emphasis-mark != $HAN-TEXT-EMPHASIS-MARK or $han-text-emphasis-shape != $HAN-TEXT-EMPHASIS-SHAPE )
13 | $mark: $han-text-emphasis-mark
14 | $shape: $han-text-emphasis-shape
15 |
16 | @if ( $han-text-emphasis-posi != $HAN-TEXT-EMPHASIS-POSI )
17 | $posi: $han-text-emphasis-posi
18 |
19 | @if ( $han-text-emphasis-color != $HAN-TEXT-EMPHASIS-COLOR )
20 | $color: $han-text-emphasis-color
21 |
22 | +han-text-emphasis( $posi, $mark, $shape, $color, $skip, false )
23 |
24 | em:lang(ja)
25 | $posi: null
26 | $mark: null
27 | $shape: null
28 | $color: null
29 | $skip: $han-text-emphasis-skip
30 |
31 | @if ( $han-text-emphasis-mark-ja != $HAN-TEXT-EMPHASIS-MARK-JA or $han-text-emphasis-shape-ja != $HAN-TEXT-EMPHASIS-SHAPE-JA )
32 | $mark: $han-text-emphasis-mark-ja
33 | $shape: $han-text-emphasis-shape-ja
34 |
35 | @if ( $han-text-emphasis-posi-ja != $HAN-TEXT-EMPHASIS-POSI-JA )
36 | $posi: $han-text-emphasis-posi-ja
37 |
38 | @if ( $han-text-emphasis-color-ja != $HAN-TEXT-EMPHASIS-COLOR-JA )
39 | $color: $han-text-emphasis-color-ja
40 |
41 | +han-text-emphasis( $posi, $mark, $shape, $color, $skip, false )
42 |
43 |
--------------------------------------------------------------------------------
/src/js/typography/biaodian.js:
--------------------------------------------------------------------------------
1 | define([
2 | '../core',
3 | '../method',
4 | '../locale/support'
5 | ], function( Han, $, support ) {
6 |
7 | Han.correctBiaodian = function( context ) {
8 | var context = context || document
9 | var finder = Han.find( context )
10 |
11 | finder
12 | .avoid( 'h-char' )
13 | .replace( /([‘“])/g, function( portion ) {
14 | var $char = Han.createBDChar( portion.text )
15 | $char.classList.add( 'bd-open', 'punct' )
16 | return $char
17 | })
18 | .replace( /([’”])/g, function( portion ) {
19 | var $char = Han.createBDChar( portion.text )
20 | $char.classList.add( 'bd-close', 'bd-end', 'punct' )
21 | return $char
22 | })
23 |
24 | return Han.support.unicoderange
25 | ? finder
26 | : finder.charify({ biaodian: true })
27 | }
28 |
29 | Han.correctBasicBD = Han.correctBiaodian
30 | Han.correctBD = Han.correctBiaodian
31 |
32 | $.extend( Han.fn, {
33 | biaodian: null,
34 |
35 | correctBiaodian: function() {
36 | this.biaodian = Han.correctBiaodian( this.context )
37 | return this
38 | },
39 |
40 | revertCorrectedBiaodian: function() {
41 | try {
42 | this.biaodian.revert( 'all' )
43 | } catch (e) {}
44 | return this
45 | }
46 | })
47 |
48 | // Legacy support (deprecated):
49 | Han.fn.correctBasicBD = Han.fn.correctBiaodian
50 | Han.fn.revertBasicBD = Han.fn.revertCorrectedBiaodian
51 |
52 | return Han
53 | })
54 |
--------------------------------------------------------------------------------
/src/sass/typography/ff/_ruby.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Zhuyin Kaiti
4 | */
5 |
6 | @font-face {
7 | @include han-webfont;
8 | @include han-range-zhuyin;
9 | font-family: 'Zhuyin Kaiti';
10 | }
11 |
12 | /**
13 | * Zhuyin Heiti
14 | */
15 |
16 | // * 1. Medial ‘yi’ (介音「ㄧ」)
17 | // * 2. Tones (五聲調號)
18 | // *
19 |
20 | @font-face {
21 | @include han-range-zhuyin;
22 | font-family: 'Zhuyin Heiti';
23 | src:
24 | local('Hiragino Sans GB'),
25 | local('Heiti TC'),
26 | local('Microsoft Jhenghei'),
27 | $han-webfont
28 | ;
29 | }
30 |
31 | // 1
32 | @font-face {
33 | font-family: 'Zhuyin Heiti';
34 | src:
35 | local('Heiti TC'),
36 | local('Microsoft Jhenghei'),
37 | $han-webfont
38 | ;
39 | unicode-range: U+"+3127";
40 | }
41 |
42 | // 2
43 | @font-face {
44 | @include han-webfont;
45 | font-family: 'Zhuyin Heiti';
46 | unicode-range:
47 | U+"+02D9", U+"+02CA", U+"+02C5", U+"+02C7", U+"+02CB", U+"+02EA-02EB",
48 | U+"+31B4", U+"+31B5", U+"+31B6", U+"+31B7", U+"+0307", U+"+030D", U+"+0358",
49 | U+"+F31B4-F31B7",
50 | U+"+F0061", U+"+F0065", U+"+F0069", U+"+F006F", U+"+F0075"
51 | ;
52 | }
53 |
54 | /**
55 | * Romanisation (checked tone ligature [陽入韻連字])
56 | */
57 | @font-face {
58 | @include han-webfont;
59 | font-family: 'Romanization Sans';
60 | unicode-range:
61 | U+"+0307", U+"+030D", U+"+0358",
62 | U+"+F31B4-F31B7",
63 | U+"+F0061", U+"+F0065", U+"+F0069", U+"+F006F", U+"+F0075"
64 | ;
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/demo/shs.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html(lang='zh-Hant').han-init
3 | head
4 | meta(charset='utf-8')
5 | title 測試・思源黑體 — 漢字標準格式
6 | link(rel='stylesheet', href='./han.min.css')
7 | style.
8 | html {
9 | /* box */
10 | overflow-x: hidden;
11 | }
12 |
13 | article {
14 | /* position */
15 | margin: 0 auto;
16 |
17 | /* box */
18 | max-width: 35em;
19 | padding: 0 .5em 15em;
20 |
21 | /* typography */
22 | font-family: 'Source Han Sans', sans-serif;
23 | font-weight: 200;
24 | }
25 |
26 | article strong:lang(zh),
27 | article strong:lang(zh-Hant) {
28 | font-family: inherit;
29 | }
30 | meta(name='viewport' content='width=device-width, initial-scale=1.0')
31 | meta(name='description' content='印刷品般的漢字網頁排版框架')
32 | meta(name='keywords' content='漢字標準格式, 中文, 排版, 排版規範, 日文, 字體排印, 文字設計, CLReq, CSS, Sass, typography')
33 | body.test
34 |
35 | article
36 | h1 測試·思源黑體
37 | section
38 | h2 標題與內文
39 | p 阿波羅11號(Apollo 11)是美國國家航空航天局的阿波羅計畫(Project Apollo)中的第五次載人任務,是人類第一次登月任務,歷時8天13小時18分35秒,繞行月球30周,在月表停留21小時36分20秒。三位執行此任務的宇航員分別為指令長尼爾·阿姆斯特朗、指令艙駕駛員邁克爾·科林斯與登月艙駕駛員巴茲·奧爾德林。1969年7月20日,阿姆斯特朗與奧爾德林成為了首次踏上月球的人類,而阿波羅11號登陸月球一事更進一步成為紀錄片和廣告常見之歷史事件。
40 |
41 | h2 字重
42 | p 鵝,是企鵝家族中體型最大的屬種,成年皇帝企鵝身高可達120厘米,體重可達46千克。在皇帝企鵝發現之前,有一種企鵝被認為是最大的企鵝,取名為國王企鵝。
43 | script(src='./han.min.js')
44 |
--------------------------------------------------------------------------------
/demo/ruby(ff).html:
--------------------------------------------------------------------------------
1 | 測試・標音(注音符號、羅馬拼音) — 漢字標準格式測試·標音(注音符號、羅馬拼音)
注音符號
黑體
ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙ
ㆠㆣㆢㆡㆭ
ㄧㄨㄩ
ㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦ
ㆤㆥㆦㆧㆨㆩㆪㆫㆬㆮㆯㆰㆱㆲㆳ
ㄪㄫㄬㄭ
ˊˇˋ˪˫˙
ㆴㆵㆶㆷㆴ̇ㆵ̇ㆶ̇ㆷ̇
楷體
ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙ
ㆠㆣㆢㆡㆭ
ㄧㄨㄩ
ㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦ
ㆤㆥㆦㆧㆨㆩㆪㆫㆬㆮㆯㆰㆱㆲㆳ
ㄪㄫㄬㄭ
ˊˇˋ˪˫˙
ㆴㆵㆶㆷㆴ̇ㆵ̇ㆶ̇ㆷ̇
萌典PUA
以下是用於「萌典」的PUA陽入韻字元,使用web字體「Romanization Sans」,可保證在所有瀏覽器下正常顯示。搭配「字元的替換」功能可提供對無障礙瀏覽器較友好、更加語意化的網頁。
(\uF31B4-7)
(\uF006x、\uF0075)
--------------------------------------------------------------------------------
/src/sass/typography/ff/_range.scss:
--------------------------------------------------------------------------------
1 |
2 | // * CJK-related blocks
3 | // *
4 | @mixin han-range-cjk {
5 | unicode-range:
6 | // Basic CJK unified ideographs
7 | // 中日韓統一意音文字
8 | U+"+4E00-9FFF",
9 |
10 | // CJK Ext-A, B, C, D
11 | // 擴展A、B、C、D(急用漢字)區
12 | U+"+3400-4DB5",
13 | U+"+20000-2A6D6",
14 | U+"+2A700-2B734",
15 | U+"+2B740-2B81D",
16 |
17 | // 12 Compatibility Ideograph characters
18 | // 12個「相容意音文字」
19 | U+"+FA0E-FA0F", U+"+FA11", U+"+FA13-FA14", U+"+FA1F", U+"+FA21", U+"+FA23", U+"+FA24", U+"+FA27-FA29",
20 |
21 | // Kana
22 | // 假名
23 | U+"+3040-309F", U+"+30A0-30FF",
24 | U+"+3099-309E",
25 | U+"+FF66-FF9F",
26 |
27 | // Ideographic number ‘zero’
28 | // 數字「〇」
29 | U+"+3007",
30 |
31 | // Strokes
32 | // 筆畫
33 | U+"+31C0-31E3",
34 |
35 | // Kangxi and supplement radicals
36 | // 康熙字典及簡化字部首
37 | U+"+2F00-2FD5", U+"+2E80-2EF3"
38 | ;
39 | }
40 |
41 | // * Numerals (0-9)
42 | // *
43 | @mixin han-range-numeral {
44 | unicode-range: U+"+0030-0039";
45 | }
46 |
47 | // * Zhuyin blocks
48 | // *
49 | @mixin han-range-zhuyin {
50 | unicode-range:
51 | // Zhuyin
52 | U+"+3105-312D", U+"+31A0-31BA",
53 |
54 | // tones
55 | U+"+02D9", U+"+02CA", U+"+02C5", U+"+02C7", U+"+02CB", U+"+02EA-02EB",
56 |
57 | // Yang checked tones (Romanisation vowels & Zhuyin)
58 | U+"+0307", U+"+030D", U+"+0358",
59 |
60 | // Yang cheked tones (Moedict.tw PUA)
61 | U+"+F31B4-F31B7",
62 | U+"+F0061", U+"+F0065", U+"+F0069", U+"+F006F", U+"+F0075"
63 | ;
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/demo/numeral.html:
--------------------------------------------------------------------------------
1 | 測試・數字 — 漢字標準格式測試·數字
等高數字
無襯線
1234567890
1234567890
1234567890
1234567890
襯線
1234567890
1234567890
1234567890
1234567890
文本數字
無襯線
1234567890
1234567890
1234567890
1234567890
襯線
1234567890
1234567890
1234567890
1234567890
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "han-css",
3 | "version": "3.3.0",
4 | "description": "The CSS typography framework optimised for Hanzi",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/ethantw/Han.git"
8 | },
9 | "main": "index.js",
10 | "keywords": [
11 | "Hanzi",
12 | "CJK",
13 | "normalize",
14 | "typography",
15 | "typesetting"
16 | ],
17 | "author": {
18 | "name": "Chen Yijun (@ethantw)",
19 | "url": "http://yijun.me/"
20 | },
21 | "license": "MIT",
22 | "bugs": {
23 | "url": "https://github.com/ethantw/Han/issues"
24 | },
25 | "scripts": {
26 | "test": "gulp test",
27 | "start": "gulp dev",
28 | "build": "gulp build",
29 | "prepublishOnly": "npm run build"
30 | },
31 | "engines": {
32 | "node": ">= 0.12"
33 | },
34 | "dependencies": {
35 | "fibre.js": "^0.2.1",
36 | "normalize.css": "^4.0.0"
37 | },
38 | "devDependencies": {
39 | "gulp": "^3.9.0",
40 | "gulp-browserify": "^0.5.0",
41 | "gulp-concat-util": "^0.5.1",
42 | "gulp-connect": "^2.2.0",
43 | "gulp-csscomb": "^3.0.3",
44 | "gulp-cssmin": "^0.1.6",
45 | "gulp-jade": "^0.10.0",
46 | "gulp-livescript": "^2.3.0",
47 | "gulp-plumber": "^1.0.1",
48 | "gulp-qunit": "^1.2.1",
49 | "gulp-requirejs-optimize": "^0.1.1",
50 | "gulp-sass": "^2.1.1",
51 | "gulp-stylus": "^2.0.4",
52 | "gulp-symlink": "^2.1.0",
53 | "gulp-uglifyjs": "^0.5.0",
54 | "gulp-util": "^3.0.7",
55 | "gulp-watch": "^3.0.0",
56 | "livescript": "~1.4.0",
57 | "qunitjs": "^1.16.0",
58 | "requirejs": "^2.1.15"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/test/qunit-assert-dom.min.js:
--------------------------------------------------------------------------------
1 | /*! qunit-assert-dom 04-09-2015 */
2 | !function(){var a=window.QUnit;if(!a)throw"QUnit needs to loaded before qunit-assert-dom";var b=function(){if("undefined"!=typeof window.DOMParser)return function(a){var b=(new window.DOMParser).parseFromString(a,"text/xml");return b};if("undefined"!=typeof window.ActiveXObject&&new window.ActiveXObject("Microsoft.XMLDOM"))return function(a){var b=new window.ActiveXObject("Microsoft.XMLDOM");return b.async="false",b.loadXML(a),b};throw new Error("No XML parser found")}(),c=function(a){for(var b=0;bb;b++)d[b]=a[b];return d}return function(e,f){"string"==typeof e&&(e=b(e),e=e.documentElement),e=e instanceof Array||e.toArray?e[0]:e,e=e.ownerDocument?e:e.documentElement,f=f||{};var g="boolean"==typeof f.prettify?f.prettify:!0,h=g?f.lineSeparator||"\n":"",i=g?f.tabSpace||" ":"",j=arguments[2]||0,k=new Array(j+1).join(i);return g&&c(e),(j>0?h:"")+k+(1===e.nodeType?"<"+e.tagName.toLowerCase()+a(e.attributes).sort(function(a,b){return a.nameb.name?1:0}).map(function(a){var b=a.name.toLowerCase(),c=a.value;return"style"===b&&(c=c.split(/\s*;\s*/).sort().join("; "))," "+b+'="'+c+'"'}).join("")+">"+a((e=e[0]||e).childNodes).map(function(a){return d(a,f,j+1)}).join("")+h+k+""+e.tagName.toLowerCase()+">":3===e.nodeType?e.nodeValue:"")}}();a.extend(a.assert,{domEqual:function(a,b,c){a=d(a),b=d(b),this.equal(a,b,c)},domNotEqual:function(a,b,c){a=d(a),b=d(b),this.notEqual(a,b,c)}})}();
--------------------------------------------------------------------------------
/src/styl/section/counter.styl:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Sectional counter for articles
4 | */
5 | $han-section-counter
6 | counter-reset: han-article-h2 han-article-h3 han-article-h4
7 | h2:not(.toc)
8 | counter-reset: han-article-h3 han-article-h4
9 | &:before
10 | content: counter(han-article-h2) "\3000"
11 | content: counter(han-article-h2, cjk-ideographic) "\3001"
12 | counter-increment: han-article-h2
13 | h3:not(.toc)
14 | counter-reset: han-article-h4
15 | &:before
16 | content: counter(han-article-h2) "." counter(han-article-h3) "\3000"
17 | counter-increment: han-article-h3
18 | h4:not(.toc)
19 | &:before
20 | content: counter(han-article-h2) "." counter(han-article-h3) "." counter(han-article-h4) "\3000"
21 | counter-increment: han-article-h4
22 |
23 | $han-toc-counter
24 | counter-reset: han-toc-h2 han-toc-h3 han-toc-h4
25 | li
26 | list-style: none
27 | > li
28 | counter-reset: han-toc-h3 han-toc-h4
29 | &:before
30 | // typography
31 | content: counter(han-toc-h2) "\3000"
32 | content: counter(han-toc-h2, cjk-ideographic) "\3001"
33 | counter-increment: han-toc-h2
34 | > li > ol > li
35 | counter-reset: han-toc-h4
36 | &:before
37 | // position
38 | margin-right: 0.5em
39 | // typography
40 | content: counter(han-toc-h2) "." counter(han-toc-h3)
41 | counter-increment: han-toc-h3
42 | ol ol > li
43 | &:before
44 | // position
45 | margin-right: 0.5em
46 | // typography
47 | content: counter(han-toc-h2) "." counter(han-toc-h3) "." counter(han-toc-h4)
48 | counter-increment: han-toc-h4
49 | if $han-section-counter
50 | {$han-article}
51 | han-section-counter($han-section-counter-toc)
52 |
--------------------------------------------------------------------------------
/src/sass/section/_counter.sass:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Sectional counter for articles
4 | */
5 |
6 | %han-section-counter
7 | counter-reset: han-article-h2 han-article-h3 han-article-h4
8 |
9 | h2:not(.toc)
10 | counter-reset: han-article-h3 han-article-h4
11 |
12 | &:before
13 | content: counter(han-article-h2) '\3000'
14 | content: counter(han-article-h2, cjk-ideographic) '\3001'
15 | counter-increment: han-article-h2
16 |
17 | h3:not(.toc)
18 | counter-reset: han-article-h4
19 |
20 | &:before
21 | content: counter(han-article-h2) '.' counter(han-article-h3) '\3000'
22 | counter-increment: han-article-h3
23 |
24 | h4:not(.toc)
25 | &:before
26 | content: counter(han-article-h2) '.' counter(han-article-h3) '.' counter(han-article-h4) '\3000'
27 | counter-increment: han-article-h4
28 |
29 | %han-toc-counter
30 | counter-reset: han-toc-h2 han-toc-h3 han-toc-h4
31 |
32 | li
33 | list-style: none
34 |
35 | > li
36 | counter-reset: han-toc-h3 han-toc-h4
37 |
38 | &:before
39 | // typography
40 | content: counter(han-toc-h2) '\3000'
41 | content: counter(han-toc-h2, cjk-ideographic) '\3001'
42 | counter-increment: han-toc-h2
43 |
44 | > li > ol > li
45 | counter-reset: han-toc-h4
46 |
47 | &:before
48 | // position
49 | margin-right: .5em
50 | // typography
51 | content: counter(han-toc-h2) '.' counter(han-toc-h3)
52 | counter-increment: han-toc-h3
53 |
54 | ol ol > li
55 | &:before
56 | // position
57 | margin-right: .5em
58 | // typography
59 | content: counter(han-toc-h2) '.' counter(han-toc-h3) '.' counter(han-toc-h4)
60 | counter-increment: han-toc-h4
61 |
62 | @if ( $han-section-counter )
63 | #{$han-article}
64 | +han-section-counter( $han-section-counter-toc )
65 |
--------------------------------------------------------------------------------
/demo/deco-line.html:
--------------------------------------------------------------------------------
1 | 測試・文字裝飾線元素 — 漢字標準格式測試·文字裝飾線元素
底線
註記元素u
詹姆斯·貝內特·麥克里是美國肯塔基州的一名律師和政治家,曾是該州在聯邦國會兩院的代表並擔任第27和第37任州長。
增訂元素ins
那個男孩說道:「¡Te quiero!」
刪除線
訛訊元素s
呼叫器(pager,又作B.B.Call)是當今世代最有效的交流、溝通設備之一。
刪訂元素del
歡迎——抄寫、列印或傳送這分文件到行動裝置以便査閱。
混用
註記元素甲增訂元素甲註記元素乙一般文字節點增訂元素乙註記元素丙增訂元素丙一般文字節點;訛訊元素甲刪訂元素甲訛訊元素乙一般文字節點刪訂元素乙訛訊元素乙刪訂元素丙。
註記元素丁訛訊元素丁增訂元素丁刪訂元素丁。
--------------------------------------------------------------------------------
/demo/italic.html:
--------------------------------------------------------------------------------
1 | 測試・西文意大利體 — 漢字標準格式測試·西文意大利體
無襯線
The quick brown fox jumps over a lazy dog.
0123456789 !§%&/()=?# @©®™ $€£¢ •°-_—
äöüß æÆ œŒ åÅ øØ çÇ ñÑ
ff fl ffl fi ffi st sst
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
The quick brown fox jumps over a lazy dog.
0123456789 !§%&/()=?# @©®™ $€£¢ •°-_—
äöüß æÆ œŒ åÅ øØ çÇ ñÑ
ff fl ffl fi ffi st sst
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
襯線
The quick brown fox jumps over a lazy dog.
0123456789 !§%&/()=?# @©®™ $€£¢ •°-_—
äöüß æÆ œŒ åÅ øØ çÇ ñÑ
ff fl ffl fi ffi st sst
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
The quick brown fox jumps over a lazy dog.
0123456789 !§%&/()=?# @©®™ $€£¢ •°-_—
äöüß æÆ œŒ åÅ øØ çÇ ñÑ
ff fl ffl fi ffi st sst
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
--------------------------------------------------------------------------------
/demo/numeral.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html(lang='zh-Hant').han-init
3 | head
4 | meta(charset='utf-8')
5 | title 測試・數字 — 漢字標準格式
6 | link(rel='stylesheet', href='./han.min.css')
7 | style.
8 | html {
9 | overflow-x: hidden;
10 | }
11 |
12 | article {
13 | /* position */
14 | margin: 0 auto;
15 |
16 | /* box */
17 | max-width: 35em;
18 | padding: 0 .5em 15em;
19 | }
20 |
21 | .bold {
22 | font-weight: bold;
23 | }
24 |
25 | .italic {
26 | font-style: italic;
27 | }
28 | meta(name='viewport' content='width=device-width, initial-scale=1.0')
29 | meta(name='description' content='印刷品般的漢字網頁排版框架')
30 | meta(name='keywords' content='漢字標準格式, 中文, 排版, 排版規範, 日文, 字體排印, 文字設計, CLReq, CSS, Sass, typography')
31 | body.test
32 |
33 | article
34 | h1 測試·數字
35 | h2 等高數字
36 | h3 無襯線
37 | p(style='font-family: "Numeral LF Sans";')
38 | | 1234567890
39 | br
40 | span.italic 1234567890
41 | br
42 | span.bold 1234567890
43 | br
44 | span.bold.italic 1234567890
45 |
46 | h3 襯線
47 | p(style='font-family: "Numeral LF Serif";')
48 | | 1234567890
49 | br
50 | span.italic 1234567890
51 | br
52 | span.bold 1234567890
53 | br
54 | span.bold.italic 1234567890
55 | h2 文本數字
56 | h3 無襯線
57 | p(style='font-family: "Numeral TF Sans";')
58 | | 1234567890
59 | br
60 | span.italic 1234567890
61 | br
62 | span.bold 1234567890
63 | br
64 | span.bold.italic 1234567890
65 | h3 襯線
66 | p(style='font-family: "Numeral TF Serif";')
67 | | 1234567890
68 | br
69 | span.italic 1234567890
70 | br
71 | span.bold 1234567890
72 | br
73 | span.bold.italic 1234567890
74 |
75 | script(src='./han.min.js')
76 |
--------------------------------------------------------------------------------
/src/styl/inline/jiya.styl:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * CJK Biaodian compression (CJK標點擠壓)
4 | */
5 | h-char.bd-jiya.bd-open:before,
6 | h-char.bd-jiya.bd-end:after,
7 | h-cs,
8 | h-cs[hidden]
9 | // box
10 | display: none
11 | visibility: hidden
12 | // typography
13 | content: ' '
14 | font: .825em Courier
15 | letter-spacing: 0
16 | white-space: normal
17 |
18 | h-cs.jinze-outer,
19 | h-cs.jinze-outer[hidden]
20 | display: inline
21 |
22 | // * Handle line start/end Biaodian (行首行尾標點擠壓)
23 | // *
24 | h-char.bd-jiya
25 | &.bd-open > h-inner
26 | margin-left: -.5em
27 |
28 | &.bd-close,
29 | &.bd-cop,
30 | &[unicode='ff0e']
31 | > h-inner
32 | letter-spacing: -.5em
33 |
34 | &.bd-open:before,
35 | &.bd-close:after,
36 | &.bd-cop:after,
37 | &[unicode='ff0e']:after
38 | display: inline
39 |
40 | &.bd-cop
41 | &:lang(zh-Hant),
42 | &:lang(zh-TW),
43 | &:lang(zh-HK)
44 | &:after
45 | display: none
46 | > h-inner
47 | letter-spacing: inherit
48 |
49 | // * Handle consecutive Biaodian (連續標點擠壓)
50 | // *
51 | h-char.bd-consecutive
52 | // * Basic situation
53 | // *
54 | &.bd-end:not(.end-portion):after,
55 | &.bd-open[prev='bd-open']:before,
56 | /h-cs.jiya-outer.bd-end:not(.end-portion)
57 | display: none
58 |
59 | /h-cs.jiya-outer.bd-end[next='bd-open']
60 | display: inline
61 |
62 | &.bd-open[prev*='bd-cop']
63 | &:lang(zh-Hant):before,
64 | &:lang(zh-TW):before,
65 | &:lang(zh-HK):before
66 | display: none
67 |
68 | /h-cs.jiya-outer[prev*='bd-cop'],
69 | /h-cs.jiya-outer.bd-end
70 | &:lang(zh-Hant),
71 | &:lang(zh-TW),
72 | &:lang(zh-HK)
73 | display: none
74 |
75 | // * Handle ‘「漢」·「字」’ situation
76 | // *
77 | &[unicode='b7'],
78 | &[unicode='30fb']
79 | &:not(.end-portion)
80 | letter-spacing: -.5em
81 |
82 | // * Handle ‘……「漢字’ situation
83 | // *
84 | &.bd-liga:not(.end-portion)
85 | margin-right: -.25em
86 |
87 |
--------------------------------------------------------------------------------
/demo/generics.html:
--------------------------------------------------------------------------------
1 | 測試・字體基型(typeface generics)與@extend — 漢字標準格式測試·字體基型與@extend
提示:「漢字標準格式」提供了四類字體基型、二個子基型共六種字體@extend,在預設的語意元素修正外,更可經由Sass模組來擴展選擇器,避免字體的重覆宣告。
提示二:本測試頁未展示其他地區變體,詳見使用手冊。
無襯線字體、黑體
LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
西文無襯線意大利體、黑體
LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
等寬字體、黑體
LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
襯線字體、宋體
LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
手寫字體、楷體
LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
西文襯線意大利體、楷體
LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
--------------------------------------------------------------------------------
/src/sass/inline/_jiya.sass:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * CJK Biaodian compression (CJK標點擠壓)
4 | */
5 |
6 | h-char.bd-jiya.bd-open:before,
7 | h-char.bd-jiya.bd-end:after,
8 | h-cs,
9 | h-cs[hidden]
10 | // box
11 | display: none
12 | visibility: hidden
13 | // typography
14 | content: ' '
15 | font: .825em Courier
16 | letter-spacing: 0
17 | white-space: normal
18 |
19 | h-cs.jinze-outer,
20 | h-cs.jinze-outer[hidden]
21 | display: inline
22 |
23 | // * Handle line start/end Biaodian (行首行尾標點擠壓)
24 | // *
25 |
26 | h-char.bd-jiya
27 | &.bd-open > h-inner
28 | margin-left: -.5em
29 |
30 | &.bd-close,
31 | &.bd-cop,
32 | &[unicode='ff0e']
33 | > h-inner
34 | letter-spacing: -.5em
35 |
36 | &.bd-open:before,
37 | &.bd-close:after,
38 | &.bd-cop:after,
39 | &[unicode='ff0e']:after
40 | display: inline
41 |
42 | &.bd-cop
43 | &:lang(zh-Hant),
44 | &:lang(zh-TW),
45 | &:lang(zh-HK)
46 | &:after
47 | display: none
48 | > h-inner
49 | letter-spacing: inherit
50 |
51 | // * Handle consecutive Biaodian (連續標點擠壓)
52 | // *
53 |
54 | h-char.bd-consecutive
55 | // * Basic situation
56 | // *
57 | &.bd-end:not(.end-portion):after,
58 | &.bd-open[prev='bd-open']:before
59 | display: none
60 |
61 | @at-root h-cs.jiya-outer.bd-end:not(.end-portion)
62 | display: none
63 |
64 | @at-root h-cs.jiya-outer.bd-end[next='bd-open']
65 | display: inline
66 |
67 | &.bd-open[prev*='bd-cop']
68 | &:lang(zh-Hant):before,
69 | &:lang(zh-TW):before,
70 | &:lang(zh-HK):before
71 | display: none
72 |
73 | @at-root h-cs.jiya-outer[prev*='bd-cop']
74 | display: none
75 |
76 | @at-root h-cs.jiya-outer.bd-end
77 | &:lang(zh-Hant),
78 | &:lang(zh-TW),
79 | &:lang(zh-HK)
80 | display: none
81 |
82 | // * Handle ‘「漢」·「字」’ situation
83 | // *
84 | &[unicode='b7'],
85 | &[unicode='30fb']
86 | &:not(.end-portion)
87 | letter-spacing: -.5em
88 |
89 | // * Handle ‘……「漢字’ situation
90 | // *
91 | &.bd-liga:not(.end-portion)
92 | margin-right: -.25em
93 |
94 |
--------------------------------------------------------------------------------
/src/js/locale/detect-font.js:
--------------------------------------------------------------------------------
1 | define([
2 | '../var/body',
3 | '../method',
4 | './core'
5 | ], function( body, $, Locale ) {
6 |
7 | function writeOnCanvas( text, font ) {
8 | var canvas = $.create( 'canvas' )
9 | var context
10 |
11 | canvas.width = '50'
12 | canvas.height = '20'
13 | canvas.style.display = 'none'
14 |
15 | body.appendChild( canvas )
16 |
17 | context = canvas.getContext( '2d' )
18 | context.textBaseline = 'top'
19 | context.font = '15px ' + font + ', sans-serif'
20 | context.fillStyle = 'black'
21 | context.strokeStyle = 'black'
22 | context.fillText( text, 0, 0 )
23 |
24 | return {
25 | node: canvas,
26 | context: context,
27 | remove: function() {
28 | $.remove( canvas, body )
29 | }
30 | }
31 | }
32 |
33 | function compareCanvases( treat, control ) {
34 | var ret
35 | var a = treat.context
36 | var b = control.context
37 |
38 | try {
39 | for ( var j = 1; j <= 20; j++ ) {
40 | for ( var i = 1; i <= 50; i++ ) {
41 | if (
42 | typeof ret === 'undefined' &&
43 | a.getImageData(i, j, 1, 1).data[3] !== b.getImageData(i, j, 1, 1).data[3]
44 | ) {
45 | ret = false
46 | break
47 | } else if ( typeof ret === 'boolean' ) {
48 | break
49 | }
50 |
51 | if ( i === 50 && j === 20 && typeof ret === 'undefined' ) {
52 | ret = true
53 | }
54 | }
55 | }
56 |
57 | // Remove and clean from memory
58 | treat.remove()
59 | control.remove()
60 | treat = null
61 | control = null
62 |
63 | return ret
64 | } catch (e) {}
65 | return false
66 | }
67 |
68 | function detectFont( treat, control, text ) {
69 | var treat = treat
70 | var control = control || 'sans-serif'
71 | var text = text || '辭Q'
72 | var ret
73 |
74 | control = writeOnCanvas( text, control )
75 | treat = writeOnCanvas( text, treat )
76 |
77 | return !compareCanvases( treat, control )
78 | }
79 |
80 | Locale.writeOnCanvas = writeOnCanvas
81 | Locale.compareCanvases = compareCanvases
82 | Locale.detectFont = detectFont
83 |
84 | return Locale
85 | })
86 |
--------------------------------------------------------------------------------
/src/styl/typography/extend/sans.styl:
--------------------------------------------------------------------------------
1 |
2 | $han-sans
3 | font-family: $han-sans, han-typeface("Han Heiti", $_default-variant, $han-sans-zh), sans-serif
4 |
5 | $han-sans-hant
6 | font-family: han-biaodian(Sans, $han-biaodian-hant), $han-sans, "Zhuyin Heiti", han-typeface("Han Heiti", $han-glyph-set-hant, $han-sans-zh), sans-serif
7 |
8 | $han-sans-hant-nu
9 | font-family: $han-sans, han-typeface("Han Heiti", $han-glyph-set-hant, $han-sans-zh), sans-serif
10 |
11 | $han-sans-hans
12 | font-family: han-biaodian(Sans, $han-biaodian-hans), $han-sans, han-typeface("Han Heiti", $han-glyph-set-hans, $han-sans-zh), sans-serif
13 |
14 | $han-sans-hans-nu
15 | font-family: $han-sans, han-typeface("Han Heiti", $han-glyph-set-hans, $han-sans-zh), sans-serif
16 |
17 | $han-sans-ja
18 | font-family: "Yakumono Sans", $han-sans, sans-serif
19 |
20 | $han-sans-ja-nu
21 | font-family: $han-sans, sans-serif
22 |
23 | /**
24 | * Sans Italic
25 | */
26 | $han-sans-italic
27 | font-family: "Latin Italic Sans", $han-sans, han-typeface("Han Heiti", $_default-variant, $han-sans-zh), sans-serif
28 |
29 | $han-sans-italic-hant
30 | font-family: han-biaodian(Sans, $han-biaodian-hant), "Latin Italic Sans", $han-sans, "Zhuyin Heiti", han-typeface("Han Heiti", $han-glyph-set-hant, $han-sans-zh), sans-serif
31 |
32 | $han-sans-italic-hant-nu
33 | font-family: "Latin Italic Sans", $han-sans, han-typeface("Han Heiti", $han-glyph-set-hant, $han-sans-zh), sans-serif
34 |
35 | $han-sans-italic-hant-nu
36 | font-family: "Latin Italic Sans", $han-sans, han-typeface("Han Heiti", $han-glyph-set-hant, $han-sans-zh), sans-serif
37 |
38 | $han-sans-italic-hans
39 | font-family: han-biaodian(Sans, $han-biaodian-hans), "Latin Italic Sans", $han-sans, han-typeface("Han Heiti", $han-glyph-set-hans, $han-sans-zh), sans-serif
40 |
41 | $han-sans-italic-hans-nu
42 | font-family: "Latin Italic Sans", $han-sans, han-typeface("Han Heiti", $han-glyph-set-hans, $han-sans-zh), sans-serif
43 |
44 | $han-sans-italic-ja
45 | font-family: "Yakumono Sans", "Latin Italic Sans", $han-sans, sans-serif
46 |
47 | $han-sans-italic-ja-nu
48 | font-family: "Latin Italic Sans", $han-sans, sans-serif
49 |
50 |
--------------------------------------------------------------------------------
/src/styl/typography/extend/serif.styl:
--------------------------------------------------------------------------------
1 |
2 | $han-serif
3 | font-family: $han-serif, han-typeface("Han Songti", $_default-variant, $han-serif-zh), cursive, serif
4 |
5 | $han-serif-hant
6 | font-family: han-biaodian(Serif, $han-biaodian-hant), "Numeral LF Serif", $han-serif, "Zhuyin Kaiti", han-typeface("Han Songti", $han-glyph-set-hant, $han-serif-zh), serif
7 |
8 | $han-serif-hant-nu
9 | font-family: "Numeral LF Serif", $han-serif, han-typeface("Han Songti", $han-glyph-set-hant, $han-serif-zh), serif
10 |
11 | $han-serif-hans
12 | font-family: han-biaodian(Serif, $han-biaodian-hans), "Numeral LF Serif", $han-serif, han-typeface("Han Songti", $han-glyph-set-hans, $han-serif-zh), serif
13 |
14 | $han-serif-hans-nu
15 | font-family: "Numeral LF Serif", $han-serif, han-typeface("Han Songti", $han-glyph-set-hans, $han-serif-zh), serif
16 |
17 | $han-serif-ja
18 | font-family: "Yakumono Serif", "Numeral LF Serif", $han-serif, serif
19 |
20 | $han-serif-ja-nu
21 | font-family: "Numeral LF Serif", $han-serif, serif
22 |
23 | /**
24 | * Serif Italic
25 | */
26 | $han-serif-italic
27 | font-family: "Latin Italic Serif", $han-serif, han-typeface("Han Songti", $_default-variant, $han-serif-zh), cursive, serif
28 |
29 | $han-serif-italic-hant
30 | font-family: han-biaodian(Serif, $han-biaodian-hant), "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, "Zhuyin Kaiti", han-typeface("Han Songti", $han-glyph-set-hant, $han-serif-zh), cursive, serif
31 |
32 | $han-serif-italic-hant-nu
33 | font-family: "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, han-typeface("Han Songti", $han-glyph-set-hant, $han-serif-zh), cursive, serif
34 |
35 | $han-serif-italic-hans
36 | font-family: han-biaodian(Serif, $han-biaodian-hans), "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, han-typeface("Han Songti", $han-glyph-set-hans, $han-serif-zh), cursive, serif
37 |
38 | $han-serif-italic-hans-nu
39 | font-family: "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, han-typeface("Han Songti", $han-glyph-set-hans, $han-serif-zh), cursive, serif
40 |
41 | $han-serif-italic-ja
42 | font-family: "Yakumono Serif", "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, cursive, serif
43 |
44 | $han-serif-italic-ja-nu
45 | font-family: "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, cursive, serif
46 |
--------------------------------------------------------------------------------
/demo/generics.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html(lang='zh-Hant').han-init
3 | head
4 | meta(charset='utf-8')
5 | title 測試・字體基型(typeface generics)與@extend — 漢字標準格式
6 | link(rel='stylesheet', href='./generics-han.css')
7 | style.
8 | html {
9 | overflow-x: hidden;
10 | }
11 |
12 | article {
13 | /* position */
14 | margin: 0 auto;
15 |
16 | /* box */
17 | max-width: 35em;
18 | padding: 0 .5em 15em;
19 | }
20 | meta(name='viewport' content='width=device-width, initial-scale=1.0')
21 | meta(name='description' content='印刷品般的漢字網頁排版框架')
22 | meta(name='keywords' content='漢字標準格式, 中文, 排版, 排版規範, 日文, 字體排印, 文字設計, CLReq, CSS, Sass, typography')
23 | body.test
24 |
25 | article
26 | h1 測試·字體基型與@extend
27 | p.noti
28 | strong 提示:
29 | | 「漢字標準格式」提供了四類字體基型、二個子基型共六種字體@extend,在預設的語意元素修正外,更可經由Sass模組來擴展選擇器,避免字體的重覆宣告。
32 | p.noti
33 | strong 提示二:
34 | | 本測試頁未展示其他地區變體,詳見使用手冊。
35 | section
36 | h2 無襯線字體、黑體
37 | p.sans
38 | | LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
39 | h3 西文無襯線意大利體、黑體
40 | p.sans-italic
41 | | LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
42 | section
43 | h2 等寬字體、黑體
44 | p.mono
45 | | LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
46 | section
47 | h2 襯線字體、宋體
48 | p.serif
49 | | LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
50 | section
51 | h2 手寫字體、楷體
52 | p.cursive
53 | | LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
54 | h3 西文襯線意大利體、楷體
55 | p.cursive-italic
56 | | LGBT是女同性戀者(Lesbians)、男同性戀者(Gays)、雙性戀者(Bisexuals)與跨性別者(Transgender)的英文首字母縮略字。1990年代,由於「同性戀社群」一詞無法完整體現相關群體,「LGBT」一詞便應運而生、並逐漸普及。
57 |
58 | script(src='./han.min.js')
59 |
--------------------------------------------------------------------------------
/demo/deco-line.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html(lang='zh-Hant').han-init
3 | head
4 | meta(charset='utf-8')
5 | title 測試・文字裝飾線元素 — 漢字標準格式
6 | link(rel='stylesheet', href='./han.min.css')
7 |
8 | style.
9 | html {
10 | overflow-x: hidden;
11 | }
12 |
13 | article {
14 | /* position */
15 | margin: 0 auto;
16 |
17 | /* box */
18 | max-width: 35em;
19 | padding: 0 .5em 15em;
20 | }
21 | meta(name='viewport' content='width=device-width, initial-scale=1.0')
22 | meta(name='description' content='印刷品般的漢字網頁排版框架')
23 | meta(name='keywords' content='漢字標準格式, 中文, 排版, 排版規範, 日文, 字體排印, 文字設計, CLReq, CSS, Sass, typography')
24 |
25 | body.test
26 |
27 | article
28 | h1 測試·文字裝飾線元素
29 | section#dixian
30 | h2 底線
31 | section#zhuji_yuansu
32 | h3 註記元素u
33 | p
34 | u.pn 詹姆斯·貝內特·麥克里
35 | | 是美國肯塔基州的一名律師和政治家,曾是該州在聯邦國會兩院的代表並擔任第27和第37任州長。
37 |
38 | section#zengding_yuansu
39 | h3 增訂元素ins
40 | p
41 | | 那個男孩說道:「¡Te quiero!」
42 |
43 | section#shanchuxian
44 | h2 刪除線
45 | section#exun_yuansu
46 | h3 訛訊元素s
47 | p
48 | | 呼叫器(pager,又作B.B.Call)是當今世代最有效的交流、溝通設備之一。
49 | section#shanding_yuansu
50 | h3 刪訂元素del
51 | p
52 | | 歡迎——抄寫、列印或傳送這分文件到行動裝置以便査閱。
57 | section#hunyong
58 | h2 混用
59 | p
60 | | 註記元素甲增訂元素甲註記元素乙一般文字節點增訂元素乙註記元素丙增訂元素丙一般文字節點;訛訊元素甲刪訂元素甲訛訊元素乙一般文字節點刪訂元素乙訛訊元素乙刪訂元素丙。
67 | p
68 | | 註記元素丁訛訊元素丁增訂元素丁刪訂元素丁。
69 |
70 | // Here goes scripts
71 | script(src='./han.min.js')
72 |
--------------------------------------------------------------------------------
/src/js/locale/normalize.js:
--------------------------------------------------------------------------------
1 | define([
2 | './core',
3 | '../method',
4 | '../regex/typeset',
5 | './h-ruby'
6 | ], function( Locale, $, TYPESET ) {
7 |
8 | /**
9 | * Normalisation rendering mechanism
10 | */
11 | $.extend( Locale, {
12 |
13 | // Render and normalise the given context by routine:
14 | //
15 | // ruby -> u, ins -> s, del -> em
16 | //
17 | renderElem: function( context ) {
18 | this.renderRuby( context )
19 | this.renderDecoLine( context )
20 | this.renderDecoLine( context, 's, del' )
21 | this.renderEm( context )
22 | },
23 |
24 | // Traverse all target elements and address
25 | // presentational corrections if any two of
26 | // them are adjacent to each other.
27 | renderDecoLine: function( context, target ) {
28 | var $$target = $.qsa( target || 'u, ins', context )
29 | var i = $$target.length
30 |
31 | traverse: while ( i-- ) {
32 | var $this = $$target[ i ]
33 | var $prev = null
34 |
35 | // Ignore all `` and comments in between,
36 | // and add class `.adjacent` once two targets
37 | // are next to each other.
38 | ignore: do {
39 | $prev = ( $prev || $this ).previousSibling
40 |
41 | if ( !$prev ) {
42 | continue traverse
43 | } else if ( $$target[ i-1 ] === $prev ) {
44 | $this.classList.add( 'adjacent' )
45 | }
46 | } while ( $.isIgnorable( $prev ))
47 | }
48 | },
49 |
50 | // Traverse all target elements to render
51 | // emphasis marks.
52 | renderEm: function( context, target ) {
53 | var method = target ? 'qsa' : 'tag'
54 | var target = target || 'em'
55 | var $target = $[ method ]( target, context )
56 |
57 | $target
58 | .forEach(function( elem ) {
59 | var $elem = Han( elem )
60 |
61 | if ( Locale.support.textemphasis ) {
62 | $elem
63 | .avoid( 'rt, h-char' )
64 | .charify({ biaodian: true, punct: true })
65 | } else {
66 | $elem
67 | .avoid( 'rt, h-char, h-char-group' )
68 | .jinzify()
69 | .groupify({ western: true })
70 | .charify({
71 | hanzi: true,
72 | biaodian: true,
73 | punct: true,
74 | latin: true,
75 | ellinika: true,
76 | kirillica: true
77 | })
78 | }
79 | })
80 | }
81 | })
82 | })
83 |
--------------------------------------------------------------------------------
/demo/ruby(ff).jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html(lang='zh-Hant').han-init
3 | head
4 | meta(charset='utf-8')
5 | title 測試・標音(注音符號、羅馬拼音) — 漢字標準格式
6 | link(rel='stylesheet', href='./ruby(ff)-han.css')
7 | style.
8 | html {
9 | overflow-x: hidden;
10 | }
11 |
12 | article {
13 | /* position */
14 | margin: 0 auto;
15 |
16 | /* box */
17 | max-width: 35em;
18 | padding: 0 .5em 15em;
19 | }
20 | meta(name='viewport' content='width=device-width, initial-scale=1.0')
21 | meta(name='description' content='印刷品般的漢字網頁排版框架')
22 | meta(name='keywords' content='漢字標準格式, 中文, 排版, 排版規範, 日文, 字體排印, 文字設計, CLReq, CSS, Sass, typography')
23 | body.test
24 |
25 | article
26 | h1 測試·標音(注音符號、羅馬拼音)
27 | section#zhuyin_fuhao
28 | h2 注音符號
29 | section#zhuyin_fuhao-heiti
30 | h3 黑體
31 | p
32 | | ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙ
33 | br
34 | | ㆠㆣㆢㆡㆭ
35 | br
36 | | ㄧㄨㄩ
37 | br
38 | | ㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦ
39 | br
40 | | ㆤㆥㆦㆧㆨㆩㆪㆫㆬㆮㆯㆰㆱㆲㆳ
41 | br
42 | | ㄪㄫㄬㄭ
43 | br
44 | | ˊˇˋ˪˫˙
45 | br
46 | | ㆴㆵㆶㆷㆴ̇ㆵ̇ㆶ̇ㆷ̇
47 | section#zhuyin_fuhao-kaiti
48 | h3 楷體
49 | p
50 | | ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙ
51 | br
52 | | ㆠㆣㆢㆡㆭ
53 | br
54 | | ㄧㄨㄩ
55 | br
56 | | ㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦ
57 | br
58 | | ㆤㆥㆦㆧㆨㆩㆪㆫㆬㆮㆯㆰㆱㆲㆳ
59 | br
60 | | ㄪㄫㄬㄭ
61 | br
62 | | ˊˇˋ˪˫˙
63 | br
64 | | ㆴㆵㆶㆷㆴ̇ㆵ̇ㆶ̇ㆷ̇
65 | section#luoma_pinyin
66 | h2 羅馬拼音
67 | section#yuanyin
68 | h3 元音(陰、陽入韻)
69 | p aeioua̍e̍i̍o̍u̍
70 | section#pua
71 | h2 萌典PUA
72 | p.noti
73 | | 以下是用於「
74 | a(href='//moedict.tw') 萌典
75 | | 」的PUA陽入韻字元,使用web字體「Romanization Sans」,可保證在所有瀏覽器下正常顯示。搭配「
77 | a(href='./subst.html') 字元的替換
78 | | 」功能可提供對無障礙瀏覽器較友好、更加語意化的網頁。
79 | p
80 | | (\uF31B4-7)
81 | br
82 | | (\uF006x、\uF0075)
83 |
84 | script(src='./han.min.js')
85 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | - 中文
3 | - [日本語](https://github.com/ethantw/Han/blob/master/README-ja.md)
4 | - [English](https://github.com/ethantw/Han/blob/master/README-en.md)
5 |
6 |
7 | 漢字標準格式
8 | ==========
9 |
10 | 「漢字標準格式」是一個集「語意樣式標準化」「文字設計」「高階排版功能」三大概念的Sass/Stylus、JavaScript排版框架。其專為漢字網頁提供的美觀而標準化的環境,不僅符合傳統閱讀習慣、更為螢幕閱讀提供了既成標準,得以完整解決現今漢字網頁設計的排版需求。
11 |
12 | 「漢字標準格式」完整支援繁體中文、簡體中文及日文等三個採用漢字的語言文字。
13 |
14 | [檢視範例測試頁](http://ethantw.github.io/Han/latest/)
15 |
16 | ## 安裝
17 | - NPM `npm install --save han-css`
18 | - Bower `bower install --save Han`
19 | - Rails `gem install 'hanzi-rails'`([詳細說明](https://github.com/billy3321/hanzi-rails))
20 |
21 | ### 定製
22 | 「漢字標準格式」提供多項定製功能,可經由變數設定、模組引用等方式定製專屬的樣式表。詳情請見[使用手冊][api]。
23 |
24 | [api]: http://hanzi.pro/manual/sass-api
25 |
26 | ### 使用CDN文件
27 | 若毋須特別定製,你也可以直接使用以預設値編譯的CDN外連樣式表、腳本及網頁字體,以求高速下載及快取。[此服務由cdnjs.com提供][cdnjs]。
28 |
29 | [cdnjs]: http://cdnjs.com/libraries/han
30 |
31 | ````html
32 |
33 | ````
34 |
35 | 腳本,
36 |
37 | ````html
38 |
39 | ````
40 |
41 | Web字體,
42 |
43 | - WOFF `//cdnjs.cloudflare.com/ajax/libs/Han/3.3.0/font/han.woff`
44 | - OTF `//cdnjs.cloudflare.com/ajax/libs/Han/3.3.0/font/han.otf`
45 |
46 | ## 使用方式
47 |
48 | 1. 在網頁所有樣式表*前*引用經編譯的`han.min.css`(或使用Sass/Stylus匯入)。
49 | 2. 依需求選用腳本`han.min.js`,並在``元素標籤上加入類別`han-init`以啓用DOM-ready渲染。
50 | 3. 或依需求定製渲染方式,詳見[使用手冊][rendering]。
51 |
52 | [rendering]: http://css.hanzi.co/manual/js-api#rendering
53 |
54 | ### 可選用的腳本
55 | 「漢字標準格式」具低耦合、高度語意化等特性,樣式表與腳本各司其職、相互依賴性極低,並有多級樣式回退(fallback),故可依需求選用腳本。
56 |
57 | ## 常見問題
58 |
59 | - [樣式的覆蓋](http://css.hanzi.co/manual/faq#yangshi_de_fugai)
60 | - [`han.js`腳本的運行環境](http://css.hanzi.co/manual/faq#han-js_de_yunxing_huanjing)
61 |
62 | ## 瀏覽器支援
63 |
64 | - Chrome(最新版)
65 | - Edge(最新版)
66 | - Firefox(最新版)
67 | - Firefox ESR+
68 | - Internet Explorer 11
69 | - Opera(最新版)
70 | - Safari 9
71 |
72 | ## 開發需求與指令
73 |
74 | - Node.js
75 | - LiveScript 1.4.0(`sudo npm install -g livescript`)
76 |
77 | 下列清單展示了部分常用的開發指令,
78 |
79 | - 安裝需要的開發模組:`sudo npm install`
80 | - 啓動開發環境:`npm start`或`gulp dev`(包含本機運行及自動編譯)
81 | - 編譯發布文件:`gulp build`
82 | - 測試`han.js`API:`gulp test`(PhantomJS)
83 | - 更新依賴模組:`sudo npm update && gulp dep`
84 |
85 | * * *
86 | 「漢字標準格式」版本:v3.3.0
87 | 本頁最後修改於:2016-3-19 00:11(UTC+8)
88 |
89 |
--------------------------------------------------------------------------------
/src/sass/typography/_var.sass:
--------------------------------------------------------------------------------
1 |
2 | // *!
3 | // * **WARNING**
4 | // * It is recommended to overwrite the variables before
5 | // * including the module, instead of modifying them here.
6 | // *
7 |
8 | // **
9 | // * The root element
10 | // * `html` || `'*:root'`
11 | // *
12 | $han-root: html !default
13 |
14 | // **
15 | // * The article selector
16 | // * Possible values: `article` || `.article` || `.post` || `.entry`
17 | // *
18 | $han-article: article !default
19 |
20 | // **
21 | // * Default Chinese locale variant
22 | // * (Traditional or simplified characters)
23 | // * `hant` || `hans`
24 | // *
25 | $han-default-variant: hant !default
26 |
27 | // **
28 | // * Chinese glyph set in general
29 | // * `default` || `CNS` || `GB`
30 | // *
31 | $han-glyph-set-hant: default !default
32 |
33 | // **
34 | // * Simplified Chinese glyph set
35 | // * `default` || `GB`
36 | // *
37 | $han-glyph-set-hans: GB !default
38 |
39 | // **
40 | // * Chinese Biaodian set in general
41 | // * `Pro` || `CNS` || `GB` || `simp`
42 | // *
43 | $han-biaodian-hant: CNS !default
44 |
45 | // **
46 | // * Biaodian set for Simplified Chinese
47 | // * `default` || `Pro` || `CNS` || `GB`
48 | // *
49 | $han-biaodian-hans: GB !default
50 |
51 | // **
52 | // * Generic typefaces for Western (Latin-based)
53 | // * characters
54 | // *
55 | $han-sans: 'Helvetica Neue', Helvetica, Arial !default
56 | $han-serif: Georgia, 'Times New Roman' !default
57 | $han-cursive: 'Apple Chancery', 'Snell Roundhand' !default
58 | $han-mono: Menlo, Consolas, Courier !default
59 |
60 | // **
61 | // * Generic typefaces for Chinese
62 | // *
63 | $han-sans-zh: '' !default
64 | $han-serif-zh: '' !default
65 | $han-cursive-zh: '' !default
66 | $han-mono-zh: $han-sans-zh !default
67 |
68 | // **
69 | // * Web font paths
70 | // * (Zhuyin, checked-toned romanisation and
71 | // * partial CJK biaodian correction)
72 | // *
73 | $han-font-woff: './font/han.woff' !default
74 | $han-font-otf: './font/han.otf' !default
75 | $han-version: 'v1.0.0' !default
76 |
77 | $han-webfont: url(#{$han-font-woff}?#{$han-version}) format('woff'), url(#{$han-font-otf}?#{$han-version}) format('opentype') !default
78 |
79 |
--------------------------------------------------------------------------------
/src/styl/typography/extend/cursive.styl:
--------------------------------------------------------------------------------
1 |
2 | $han-cursive
3 | font-family: $han-serif, han-typeface("Han Kaiti", $_default-variant, $han-cursive-zh), cursive, serif
4 |
5 | $han-cursive-hant
6 | font-family: han-biaodian(Serif, $han-biaodian-hant), "Numeral LF Serif", $han-serif, "Zhuyin Kaiti", han-typeface("Han Kaiti", $han-glyph-set-hant, $han-cursive-zh), cursive, serif
7 |
8 | $han-cursive-hant-nu
9 | font-family: "Numeral LF Serif", $han-serif, han-typeface("Han Kaiti", $han-glyph-set-hant, $han-cursive-zh), cursive, serif
10 |
11 | $han-cursive-hans
12 | font-family: han-biaodian(Serif, $han-biaodian-hans), "Numeral LF Serif", $han-serif, han-typeface("Han Kaiti", $han-glyph-set-hans, $han-cursive-zh), cursive, serif
13 |
14 | $han-cursive-hans-nu
15 | font-family: "Numeral LF Serif", $han-serif, han-typeface("Han Kaiti", $han-glyph-set-hans, $han-cursive-zh), cursive, serif
16 |
17 | $han-cursive-ja
18 | font-family: "Yakumono Serif", "Numeral LF Serif", $han-serif, cursive, serif
19 |
20 | $han-cursive-ja-nu
21 | font-family: "Numeral LF Serif", $han-serif, cursive, serif
22 |
23 | /**
24 | * Cursive Italic
25 | */
26 | $han-cursive-italic
27 | font-family: "Latin Italic Serif", $han-serif, han-typeface("Han Kaiti", $_default-variant, $han-cursive-zh), cursive, serif
28 |
29 | $han-cursive-italic-hant
30 | font-family: han-biaodian(Serif, $han-biaodian-hant), "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, "Zhuyin Kaiti", han-typeface("Han Kaiti", $han-glyph-set-hant, $han-cursive-zh), cursive, serif
31 |
32 | $han-cursive-italic-hant-nu
33 | font-family: "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, han-typeface("Han Kaiti", $han-glyph-set-hant, $han-cursive-zh), cursive, serif
34 |
35 | $han-cursive-italic-hans
36 | font-family: han-biaodian(Serif, $han-biaodian-hans), "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, han-typeface("Han Kaiti", $han-glyph-set-hans, $han-cursive-zh), cursive, serif
37 |
38 | $han-cursive-italic-hans-nu
39 | font-family: "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, han-typeface("Han Kaiti", $han-glyph-set-hans, $han-cursive-zh), cursive, serif
40 |
41 | $han-cursive-italic-ja
42 | font-family: "Yakumono Serif", "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, cursive, serif
43 |
44 | $han-cursive-italic-ja-nu
45 | font-family: "Numeral LF Italic Serif", "Latin Italic Serif", $han-serif, cursive, serif
46 |
--------------------------------------------------------------------------------
/src/styl/section/well-knit.styl:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Well-knit sections for articles
4 | */
5 |
6 | // * Address well-knit sections in articles.
7 | // *
8 | $han-well-knit-section
9 | margin-top: -1*1em
10 |
11 | {$han-article}
12 | // typography
13 | line-height: $han-article-line-height
14 | if $han-article-justify
15 | &
16 | -moz-hyphens: auto
17 | -ms-hyphens: auto
18 | -webkit-hyphens: auto
19 | hyphens: auto
20 | p,
21 | li
22 | text-align: justify
23 | text-justify: inter-ideograph
24 |
25 | {han-header-i()}
26 | + blockquote,
27 | + p,
28 | + ol,
29 | + ul,
30 | + h6,
31 | + section > h6:first-child,
32 | + section > p:first-child,
33 | + section > ol:first-child,
34 | + section > ul:first-child,
35 | + section > blockquote:first-child
36 | @extend $han-well-knit-section
37 | {han-header-i(1, 5)}
38 | + h5,
39 | + section > h5:first-child
40 | @extend $han-well-knit-section
41 | {han-header-i(1, 4)}
42 | + h4,
43 | + section > h4:first-child
44 | @extend $han-well-knit-section
45 | {han-header-i(1, 3)}
46 | + h3,
47 | + section > h3:first-child
48 | @extend $han-well-knit-section
49 | {han-header-i(1, 2)}
50 | + h2,
51 | + section > h2:first-child
52 | @extend $han-well-knit-section
53 |
54 | // * Overwrite the default normalisation of indent alignment
55 | // *
56 | if $han-indent != $HAN-INDENT
57 | ol,
58 | ul
59 | padding-left: $han-indent
60 | figure,
61 | blockquote
62 | margin-left: $han-indent
63 | margin-right: $han-indent
64 | // * Position poem-like paragraphs with `em`-unit (Hanzi),
65 | // * in pursuit of alignments.
66 | // *
67 | p.poem-like,
68 | .poem-like p
69 | margin-left: $han-indent
70 |
71 | @media only screen and (max-width: $han-mobile-device-width)
72 | margin-left: $han-indent-md
73 |
74 | // * 1. Different alignment in different situations.
75 | // * 2. Blockquotes in blockquotes (opinionated).
76 | // *
77 | blockquote
78 | // 1
79 | {$han-article} &
80 | margin-right: 0
81 | @media only screen and (max-width: $han-mobile-device-width)
82 | margin-left: $han-indent-md
83 | // 1
84 | figure &
85 | margin: 0
86 | // 2
87 | blockquote &
88 | margin-left: ($han-indent / 2)
89 | margin-right: ($han-indent / 2)
90 | {$han-article} &
91 | margin-right: 0
92 |
93 | @media only screen and (max-width: $han-mobile-device-width)
94 | blockquote,
95 | figure
96 | margin-left: $han-indent-md
97 | margin-right: $han-indent-md
98 |
--------------------------------------------------------------------------------
/demo/italic.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html(lang='zh-Hant').han-init
3 | head
4 | meta(charset='utf-8')
5 | title 測試・西文意大利體 — 漢字標準格式
6 | link(rel='stylesheet', href='./han.min.css')
7 | style.
8 | html {
9 | overflow-x: hidden;
10 | }
11 |
12 | article {
13 | /* position */
14 | margin: 0 auto;
15 |
16 | /* box */
17 | max-width: 35em;
18 | padding: 0 .5em 15em;
19 | }
20 |
21 | .bold {
22 | font-weight: bold;
23 | }
24 |
25 | .italic {
26 | font-style: italic;
27 | }
28 | meta(name='viewport' content='width=device-width, initial-scale=1.0')
29 | meta(name='description' content='印刷品般的漢字網頁排版框架')
30 | meta(name='keywords' content='漢字標準格式, 中文, 排版, 排版規範, 日文, 字體排印, 文字設計, CLReq, CSS, Sass, typography')
31 | body.test
32 |
33 | article
34 | h1 測試·西文意大利體
35 | h2 無襯線
36 | p(style='font-family: "Latin Italic Sans";')
37 | | The quick brown fox jumps over a lazy dog.
38 | br
39 | | 0123456789 !§%&/()=?# @©®™ $€£¢ •°-_—
40 | br
41 | | äöüß æÆ œŒ åÅ øØ çÇ ñÑ
42 | br
43 | | ff fl ffl fi ffi st sst
44 | br
45 | | abcdefghijklmnopqrstuvwxyz
46 | br
47 | | ABCDEFGHIJKLMNOPQRSTUVWXYZ
48 | p.bold(style='font-family: "Latin Italic Sans";')
49 | | The quick brown fox jumps over a lazy dog.
50 | br
51 | | 0123456789 !§%&/()=?# @©®™ $€£¢ •°-_—
52 | br
53 | | äöüß æÆ œŒ åÅ øØ çÇ ñÑ
54 | br
55 | | ff fl ffl fi ffi st sst
56 | br
57 | | abcdefghijklmnopqrstuvwxyz
58 | br
59 | | ABCDEFGHIJKLMNOPQRSTUVWXYZ
60 |
61 | h2 襯線
62 | p(style='font-family: "Numeral LF Italic Serif", "Latin Italic Serif";')
63 | | The quick brown fox jumps over a lazy dog.
64 | br
65 | | 0123456789 !§%&/()=?# @©®™ $€£¢ •°-_—
66 | br
67 | | äöüß æÆ œŒ åÅ øØ çÇ ñÑ
68 | br
69 | | ff fl ffl fi ffi st sst
70 | br
71 | | abcdefghijklmnopqrstuvwxyz
72 | br
73 | | ABCDEFGHIJKLMNOPQRSTUVWXYZ
74 | p.bold(style='font-family: "Numeral LF Italic Serif", "Latin Italic Serif";')
75 | | The quick brown fox jumps over a lazy dog.
76 | br
77 | | 0123456789 !§%&/()=?# @©®™ $€£¢ •°-_—
78 | br
79 | | äöüß æÆ œŒ åÅ øØ çÇ ñÑ
80 | br
81 | | ff fl ffl fi ffi st sst
82 | br
83 | | abcdefghijklmnopqrstuvwxyz
84 | br
85 | | ABCDEFGHIJKLMNOPQRSTUVWXYZ
86 |
87 | script(src='./han.min.js')
88 |
--------------------------------------------------------------------------------
/src/styl/locale/enhancement.styl:
--------------------------------------------------------------------------------
1 |
2 | // * Address a preciser adjancent underlined text run
3 | // * with JS rendered.
4 | // *
5 | $han-reset-adjacent-deco-line
6 | margin-left: auto
7 |
8 | {$HAN-JS-RENDERED-CLASS}
9 | u,
10 | ins
11 | & + u,
12 | & + ins
13 | @extend $han-reset-adjacent-deco-line
14 |
15 | &.adjacent
16 | @extend $han-adjacent-deco-line
17 |
18 | s,
19 | del
20 | & + s,
21 | & + del
22 | @extend $han-reset-adjacent-deco-line
23 |
24 | &.adjacent
25 | @extend $han-adjacent-deco-line
26 |
27 | // * - Polyfill implementation for Firefox and IE;
28 | // * - Remove emphasis mark under punctuation.
29 | // *
30 | // * 1. Polyfill for browsers that support no `text-emphasis`.
31 | // * 2. Although han is a project for normalisation and
32 | // * fonts ain't supposed to be assigned specifically,
33 | // * we need the emphasis marks to fallback properly;
34 | // * hence, one exception is hereby made.
35 | // * 3. Skip emphasis mark while under punctuation.
36 | // *
37 | $han-need-no-jinze
38 | h-jinze
39 | display: inline
40 |
41 | $han-text-emphasis-pf
42 | {$HAN-JS-RENDERED-CLASS} &
43 | padding-bottom: auto
44 | border-bottom-width: 0
45 |
46 | // 1
47 | .no-textemphasis &
48 | line-height: 2
49 |
50 | h-char
51 | // position
52 | position: relative
53 | // typography
54 | font-style: inherit
55 |
56 | &:after
57 | han-typo-reset()
58 | han-scale-center( .5 )
59 | // position
60 | position: absolute
61 | left: 50%
62 | top: 0
63 | margin-left: -250%
64 | overflow: hidden
65 | // box
66 | display: inline-block
67 | height: 1em
68 | width: 500%
69 | // typography
70 | line-height: 1
71 | text-align: center
72 | text-indent: 0
73 | // 2
74 | font-family: Georgia, 'Times New Roman', Arial, !important
75 |
76 | // 3
77 | $han-text-emphasis-skip
78 | h-char.punct,
79 | h-char.biaodian
80 | han-text-emphasis-internal(none)
81 | .no-textemphasis &:after
82 | content: none !important
83 | em
84 | &:lang(zh)
85 | han-text-emphasis-pf()
86 | &:lang(ja)
87 | han-text-emphasis-pf($HAN-TEXT-EMPHASIS-POSI-JA, $HAN-TEXT-EMPHASIS-MARK-JA)
88 |
89 | // * Simple and complex ruby polyfill
90 | // *
91 | @import 'h-ruby'
92 |
93 | // * Punctuation rules (禁則)
94 | // *
95 | h-jinze,
96 | h-word
97 | // box
98 | display: inline-block
99 | text-indent: 0
100 |
101 |
--------------------------------------------------------------------------------
/src/sass/locale/_enhancement.sass:
--------------------------------------------------------------------------------
1 |
2 | // * Address a preciser adjancent underlined text run
3 | // * with JS rendered.
4 | // *
5 | %han-reset-adjacent-deco-line
6 | margin-left: auto
7 |
8 | #{$HAN-JS-RENDERED-CLASS}
9 | u,
10 | ins
11 | & + u,
12 | & + ins
13 | @extend %han-reset-adjacent-deco-line
14 |
15 | &.adjacent
16 | @extend %han-adjacent-deco-line
17 |
18 | s,
19 | del
20 | & + s,
21 | & + del
22 | @extend %han-reset-adjacent-deco-line
23 |
24 | &.adjacent
25 | @extend %han-adjacent-deco-line
26 |
27 | // * - Polyfill implementation for Firefox and IE;
28 | // * - Remove emphasis mark under punctuation.
29 | // *
30 | // * 1. Polyfill for browsers that support no `text-emphasis`.
31 | // * 2. Although han is a project for normalisation and
32 | // * fonts ain't supposed to be assigned specifically,
33 | // * we need the emphasis marks to fallback properly;
34 | // * hence, one exception is hereby made.
35 | // * 3. Skip emphasis mark while under punctuation.
36 | // *
37 | %han-need-no-jinze
38 | h-jinze
39 | display: inline
40 |
41 | %han-text-emphasis-pf
42 | #{$HAN-JS-RENDERED-CLASS} &
43 | padding-bottom: auto
44 | border-bottom-width: 0
45 |
46 | // 1
47 | .no-textemphasis &
48 | line-height: 2
49 |
50 | h-char
51 | // position
52 | position: relative
53 | // typography
54 | font-style: inherit
55 |
56 | &:after
57 | +han-typo-reset
58 | +han-scale-center( .5 )
59 | // position
60 | position: absolute
61 | left: 50%
62 | top: 0
63 | margin-left: -250%
64 | overflow: hidden
65 | // box
66 | display: inline-block
67 | height: 1em
68 | width: 500%
69 | // typography
70 | line-height: 1
71 | text-align: center
72 | text-indent: 0
73 | // 2
74 | font-family: Georgia, 'Times New Roman', Arial, !important
75 |
76 | // 3
77 | %han-text-emphasis-skip
78 | h-char.punct,
79 | h-char.biaodian
80 | +han-text-emphasis-internal( none )
81 |
82 | .no-textemphasis &:after
83 | content: none !important
84 |
85 | em
86 | &:lang(zh)
87 | +han-text-emphasis-pf
88 |
89 | &:lang(ja)
90 | +han-text-emphasis-pf( $HAN-TEXT-EMPHASIS-POSI-JA, $HAN-TEXT-EMPHASIS-MARK-JA )
91 |
92 | // * Simple and complex ruby polyfill
93 | // *
94 | @import h-ruby
95 |
96 | // * Punctuation rules (禁則)
97 | // *
98 | h-jinze,
99 | h-word
100 | // box
101 | display: inline-block
102 | text-indent: 0
103 |
104 |
--------------------------------------------------------------------------------
/src/styl/typography/ff/kaiti.styl:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * The Four Typefaces: Kaiti (Cursive);
4 | * 四大字體集・楷體
5 | */
6 |
7 | // * 1. Recommended (適用繁體漢字)
8 | // * 2. CNS (台灣教育部國字標準字體[字形])
9 | // * 3. GB (中國國家標準)
10 |
11 | // 1
12 | @font-face {
13 | font-family: cursive;
14 | src:
15 | local('Kaiti TC Regular'),
16 | local(STKaiTi-TC-Regular),
17 | local('Kaiti TC'),
18 | local('Kaiti SC'),
19 | local(STKaiti),
20 |
21 | local(BiauKai),
22 | local('標楷體'),
23 | local(DFKaiShu-SB-Estd-BF),
24 |
25 | local(Kaiti),
26 | local(DFKai-SB);
27 | }
28 |
29 | // 1
30 | @font-face {
31 | han-range-cjk();
32 | font-family: 'Han Kaiti';
33 | src:
34 | local('Kaiti TC Regular'),
35 | local(STKaiTi-TC-Regular),
36 | local('Kaiti TC'),
37 | local('Kaiti SC'),
38 | local(STKaiti),
39 |
40 | local(BiauKai),
41 | local('標楷體'),
42 | local(DFKaiShu-SB-Estd-BF),
43 |
44 | local(Kaiti),
45 | local(DFKai-SB);
46 | }
47 |
48 | // 2
49 | @font-face {
50 | han-range-cjk();
51 | font-family: 'Han Kaiti CNS';
52 | src:
53 | local(BiauKai),
54 | local('標楷體'),
55 | local(DFKaiShu-SB-Estd-BF),
56 | local('Kaiti TC Regular'),
57 | local(STKaiTi-TC-Regular),
58 | local('Kaiti TC');
59 | }
60 |
61 | // 3
62 | @font-face {
63 | han-range-cjk();
64 | font-family: 'Han Kaiti GB';
65 | src:
66 | local('Kaiti SC Regular'),
67 | local(STKaiTi-SC-Regular),
68 | local('Kaiti SC'),
69 | local(STKaiti),
70 | local(Kai),
71 | local(Kaiti),
72 | local(DFKai-SB);
73 | }
74 |
75 | /*
76 | * Bold
77 | */
78 |
79 | // 1
80 | @font-face {
81 | font-family: cursive;
82 | font-weight: 600;
83 | src:
84 | local('Kaiti TC Bold'),
85 | local(STKaiTi-TC-Bold),
86 | local('Kaiti SC Bold'),
87 | local(STKaiti-SC-Bold),
88 | local('Kaiti TC'),
89 | local('Kaiti SC');
90 | }
91 |
92 | // 1
93 | @font-face {
94 | font-family: 'Han Kaiti';
95 | font-weight: 600;
96 | src:
97 | local('Kaiti TC Bold'),
98 | local(STKaiTi-TC-Bold),
99 | local('Kaiti SC Bold'),
100 | local(STKaiti-SC-Bold),
101 | local('Kaiti TC'),
102 | local('Kaiti SC');
103 | }
104 |
105 | // 2
106 | @font-face {
107 | font-family: 'Han Kaiti CNS';
108 | font-weight: 600;
109 | src:
110 | local('Kaiti TC Bold'),
111 | local(STKaiTi-TC-Bold),
112 | local('Kaiti TC');
113 | }
114 |
115 | // 3
116 | @font-face {
117 | font-family: 'Han Kaiti GB';
118 | font-weight: 600;
119 | src:
120 | local('Kaiti SC Bold'),
121 | local(STKaiti-SC-Bold);
122 | }
123 |
124 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 | 測試頁索引 — 漢字標準格式測試頁索引
Normalisation(樣式標準化)
毋須配合JavaScript的元素樣式修正
見上列測試頁。
--------------------------------------------------------------------------------
/src/styl/typography/ff/numeral.styl:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Numerals: text figures
4 | */
5 | @font-face {
6 | han-range-numeral();
7 | font-family: 'Numeral TF Sans';
8 | src:
9 | local(Skia),
10 | local('Neutraface 2 Text'),
11 | local(Candara),
12 | local(Corbel);
13 | }
14 |
15 | @font-face {
16 | han-range-numeral();
17 | font-family: 'Numeral TF Serif';
18 | src:
19 | local(Georgia),
20 | local('Hoefler Text'),
21 | local('Big Caslon');
22 | }
23 |
24 | @font-face {
25 | han-range-numeral();
26 | font-family: 'Numeral TF Italic Serif';
27 | src:
28 | local('Georgia Italic'),
29 | local('Hoefler Text Italic'),
30 | local(Georgia-Italic),
31 | local(HoeflerText-Italic);
32 | }
33 |
34 | /**
35 | * Numerals: lining figures
36 | */
37 | @font-face {
38 | han-range-numeral();
39 | font-family: 'Numeral LF Sans';
40 | src:
41 | local('Helvetica Neue'),
42 | local(Helvetica),
43 | local(Arial);
44 | }
45 |
46 | @font-face {
47 | han-range-numeral();
48 | font-family: 'Numeral LF Italic Sans';
49 | src:
50 | local('Helvetica Neue Italic'),
51 | local('Helvetica Oblique'),
52 | local('Arial Italic'),
53 | local(HelveticaNeue-Italic),
54 | local(Helvetica-LightOblique),
55 | local(Arial-ItalicMT);
56 | }
57 |
58 | @font-face {
59 | han-range-numeral();
60 | font-family: 'Numeral LF Italic Sans';
61 | font-weight: bold;
62 | src:
63 | local('Helvetica Neue Bold Italic'),
64 | local('Helvetica Bold Oblique'),
65 | local('Arial Bold Italic'),
66 | local(HelveticaNeue-BoldItalic),
67 | local(Helvetica-BoldOblique),
68 | local(Arial-BoldItalicMT);
69 | }
70 |
71 | @font-face {
72 | han-range-numeral();
73 | font-family: 'Numeral LF Serif';
74 | src:
75 | local(Palatino),
76 | local('Palatino Linotype'),
77 | local('Times New Roman');
78 | }
79 |
80 | @font-face {
81 | han-range-numeral();
82 | font-family: 'Numeral LF Italic Serif';
83 | src:
84 | local('Palatino Italic'),
85 | local('Palatino Italic Linotype'),
86 | local('Times New Roman Italic'),
87 | local(Palatino-Italic),
88 | local(Palatino-Italic-Linotype),
89 | local(TimesNewRomanPS-ItalicMT);
90 | }
91 |
92 | @font-face {
93 | han-range-numeral();
94 | font-family: 'Numeral LF Italic Serif';
95 | font-weight: bold;
96 | src:
97 | local('Palatino Bold Italic'),
98 | local('Palatino Bold Italic Linotype'),
99 | local('Times New Roman Bold Italic'),
100 | local(Palatino-BoldItalic),
101 | local(Palatino-BoldItalic-Linotype),
102 | local(TimesNewRomanPS-BoldItalicMT);
103 | }
104 |
105 |
--------------------------------------------------------------------------------
/src/sass/typography/ff/_kaiti.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * The Four Typefaces: Kaiti (Cursive)
4 | * 四大字體集・楷體
5 | */
6 |
7 | // * 1. Recommended (適用繁體漢字)
8 | // * 2. CNS (台灣教育部國字標準字體[字形])
9 | // * 3. GB (中國國家標準)
10 |
11 | // 1
12 | @font-face {
13 | font-family: cursive;
14 | src:
15 | local('Kaiti TC Regular'),
16 | local(STKaiTi-TC-Regular),
17 | local('Kaiti TC'),
18 | local('Kaiti SC'),
19 | local(STKaiti),
20 |
21 | local(BiauKai),
22 | local('標楷體'),
23 | local(DFKaiShu-SB-Estd-BF),
24 |
25 | local(Kaiti),
26 | local(DFKai-SB)
27 | ;
28 | }
29 |
30 | // 1
31 | @font-face {
32 | @include han-range-cjk;
33 | font-family: 'Han Kaiti';
34 | src:
35 | local('Kaiti TC Regular'),
36 | local(STKaiTi-TC-Regular),
37 | local('Kaiti TC'),
38 | local('Kaiti SC'),
39 | local(STKaiti),
40 |
41 | local(BiauKai),
42 | local('標楷體'),
43 | local(DFKaiShu-SB-Estd-BF),
44 |
45 | local(Kaiti),
46 | local(DFKai-SB)
47 | ;
48 | }
49 |
50 | // 2
51 | @font-face {
52 | @include han-range-cjk;
53 | font-family: 'Han Kaiti CNS';
54 | src:
55 | local(BiauKai),
56 | local('標楷體'),
57 | local(DFKaiShu-SB-Estd-BF),
58 | local('Kaiti TC Regular'),
59 | local(STKaiTi-TC-Regular),
60 | local('Kaiti TC')
61 | ;
62 | }
63 |
64 | // 3
65 | @font-face {
66 | @include han-range-cjk;
67 | font-family: 'Han Kaiti GB';
68 | src:
69 | local('Kaiti SC Regular'),
70 | local(STKaiTi-SC-Regular),
71 | local('Kaiti SC'),
72 | local(STKaiti),
73 | local(Kai),
74 | local(Kaiti),
75 | local(DFKai-SB)
76 | ;
77 | }
78 |
79 | /*
80 | * Bold
81 | */
82 |
83 | // 1
84 | @font-face {
85 | font-family: cursive;
86 | font-weight: 600;
87 | src:
88 | local('Kaiti TC Bold'),
89 | local(STKaiTi-TC-Bold),
90 | local('Kaiti SC Bold'),
91 | local(STKaiti-SC-Bold),
92 | local('Kaiti TC'),
93 | local('Kaiti SC')
94 | ;
95 | }
96 |
97 | // 1
98 | @font-face {
99 | font-family: 'Han Kaiti';
100 | font-weight: 600;
101 | src:
102 | local('Kaiti TC Bold'),
103 | local(STKaiTi-TC-Bold),
104 | local('Kaiti SC Bold'),
105 | local(STKaiti-SC-Bold),
106 | local('Kaiti TC'),
107 | local('Kaiti SC')
108 | ;
109 | }
110 |
111 | // 2
112 | @font-face {
113 | font-family: 'Han Kaiti CNS';
114 | font-weight: 600;
115 | src:
116 | local('Kaiti TC Bold'),
117 | local(STKaiTi-TC-Bold),
118 | local('Kaiti TC')
119 | ;
120 | }
121 |
122 | // 3
123 | @font-face {
124 | font-family: 'Han Kaiti GB';
125 | font-weight: 600;
126 | src:
127 | local('Kaiti SC Bold'),
128 | local(STKaiti-SC-Bold)
129 | ;
130 | }
131 |
132 |
--------------------------------------------------------------------------------
/src/sass/section/_well-knit.sass:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Well-knit sections for articles
4 | */
5 |
6 | #{$han-article}
7 | // typography
8 | line-height: $han-article-line-height
9 |
10 | @if ( $han-article-justify )
11 | &
12 | -moz-hyphens: auto
13 | -ms-hyphens: auto
14 | -webkit-hyphens: auto
15 | hyphens: auto
16 | p,
17 | li
18 | text-align: justify
19 | text-justify: inter-ideograph
20 |
21 | // * Address well-knit sections in articles.
22 | // *
23 | %han-well-knit-section
24 | margin-top: -1em
25 |
26 | #{han-header-i()}
27 | + blockquote,
28 | + p,
29 | + ol,
30 | + ul,
31 | + h6,
32 | + section > h6:first-child,
33 | + section > p:first-child,
34 | + section > ol:first-child,
35 | + section > ul:first-child,
36 | + section > blockquote:first-child
37 | @extend %han-well-knit-section
38 |
39 | #{han-header-i( 1, 5 )}
40 | + h5,
41 | + section > h5:first-child
42 | @extend %han-well-knit-section
43 |
44 | #{han-header-i( 1, 4 )}
45 | + h4,
46 | + section > h4:first-child
47 | @extend %han-well-knit-section
48 |
49 | #{han-header-i( 1, 3 )}
50 | + h3,
51 | + section > h3:first-child
52 | @extend %han-well-knit-section
53 |
54 | #{han-header-i( 1, 2 )}
55 | + h2,
56 | + section > h2:first-child
57 | @extend %han-well-knit-section
58 |
59 | // * Overwrite the default normalisation of indent alignment
60 | // *
61 | @if ( $han-indent != $HAN-INDENT )
62 | ol,
63 | ul
64 | padding-left: $han-indent
65 |
66 | figure,
67 | blockquote
68 | margin-left: $han-indent
69 | margin-right: $han-indent
70 |
71 | // * Position poem-like paragraphs with `em`-unit (Hanzi),
72 | // * in pursuit of alignments.
73 | // *
74 | p.poem-like,
75 | .poem-like p
76 | margin-left: $han-indent
77 |
78 | @media only screen and (max-width: $han-mobile-device-width)
79 | margin-left: $han-indent-md
80 |
81 | // * 1. Different alignment in different situations.
82 | // * 2. Blockquotes in blockquotes (opinionated).
83 | // *
84 | blockquote
85 | // 1
86 | #{$han-article} &
87 | margin-right: 0
88 |
89 | @media only screen and (max-width: $han-mobile-device-width)
90 | margin-left: $han-indent-md
91 |
92 | // 1
93 | figure &
94 | margin: 0
95 |
96 | // 2
97 | blockquote &
98 | margin-left: $han-indent/2
99 | margin-right: $han-indent/2
100 |
101 | #{$han-article} &
102 | margin-right: 0
103 |
104 | @media only screen and (max-width: $han-mobile-device-width)
105 | blockquote,
106 | figure
107 | margin-left: $han-indent-md
108 | margin-right: $han-indent-md
109 |
--------------------------------------------------------------------------------
/src/sass/typography/ff/_numeral.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Numerals: text figures
4 | */
5 | @font-face {
6 | @include han-range-numeral;
7 | font-family: 'Numeral TF Sans';
8 | src:
9 | local(Skia),
10 | local('Neutraface 2 Text'),
11 | local(Candara),
12 | local(Corbel)
13 | ;
14 | }
15 |
16 | @font-face {
17 | @include han-range-numeral;
18 | font-family: 'Numeral TF Serif';
19 | src:
20 | local(Georgia),
21 | local('Hoefler Text'),
22 | local('Big Caslon')
23 | ;
24 | }
25 |
26 | @font-face {
27 | @include han-range-numeral;
28 | font-family: 'Numeral TF Italic Serif';
29 | src:
30 | local('Georgia Italic'),
31 | local('Hoefler Text Italic'),
32 | local(Georgia-Italic),
33 | local(HoeflerText-Italic)
34 | ;
35 | }
36 |
37 | /**
38 | * Numerals: lining figures
39 | */
40 | @font-face {
41 | @include han-range-numeral;
42 | font-family: 'Numeral LF Sans';
43 | src:
44 | local('Helvetica Neue'),
45 | local(Helvetica),
46 | local(Arial)
47 | ;
48 | }
49 |
50 | @font-face {
51 | @include han-range-numeral;
52 | font-family: 'Numeral LF Italic Sans';
53 | src:
54 | local('Helvetica Neue Italic'),
55 | local('Helvetica Oblique'),
56 | local('Arial Italic'),
57 | local(HelveticaNeue-Italic),
58 | local(Helvetica-LightOblique),
59 | local(Arial-ItalicMT)
60 | ;
61 | }
62 |
63 | @font-face {
64 | @include han-range-numeral;
65 | font-family: 'Numeral LF Italic Sans';
66 | font-weight: bold;
67 | src:
68 | local('Helvetica Neue Bold Italic'),
69 | local('Helvetica Bold Oblique'),
70 | local('Arial Bold Italic'),
71 | local(HelveticaNeue-BoldItalic),
72 | local(Helvetica-BoldOblique),
73 | local(Arial-BoldItalicMT)
74 | ;
75 | }
76 |
77 | @font-face {
78 | @include han-range-numeral;
79 | font-family: 'Numeral LF Serif';
80 | src:
81 | local(Palatino),
82 | local('Palatino Linotype'),
83 | local('Times New Roman')
84 | ;
85 | }
86 |
87 | @font-face {
88 | @include han-range-numeral;
89 | font-family: 'Numeral LF Italic Serif';
90 | src:
91 | local('Palatino Italic'),
92 | local('Palatino Italic Linotype'),
93 | local('Times New Roman Italic'),
94 | local(Palatino-Italic),
95 | local(Palatino-Italic-Linotype),
96 | local(TimesNewRomanPS-ItalicMT)
97 | ;
98 | }
99 |
100 | @font-face {
101 | @include han-range-numeral;
102 | font-family: 'Numeral LF Italic Serif';
103 | font-weight: bold;
104 | src:
105 | local('Palatino Bold Italic'),
106 | local('Palatino Bold Italic Linotype'),
107 | local('Times New Roman Bold Italic'),
108 | local(Palatino-BoldItalic),
109 | local(Palatino-BoldItalic-Linotype),
110 | local(TimesNewRomanPS-BoldItalicMT)
111 | ;
112 | }
113 |
114 |
--------------------------------------------------------------------------------
/src/styl/typography/ff/songti.styl:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * The Four Typefaces: Songti (serif)
4 | * 四大字體集・宋體
5 | */
6 |
7 | // * 1. Recommended (推薦傳統字形,適用繁體漢字)
8 | // * 2. CNS (台灣教育部國字標準字體[字形])
9 | // * 3. GB (中國國家標準)
10 |
11 | // 1
12 | @font-face {
13 | font-family: 'Han Songti';
14 | src:
15 | local('Songti SC Regular'),
16 | local(STSongti-SC-Regular),
17 | local('Songti SC'),
18 | local('Songti TC Regular'),
19 | local(STSongti-TC-Regular),
20 | local('Songti TC'),
21 |
22 | local(STSong),
23 | local('Lisong Pro'),
24 |
25 | local(SimSun),
26 | local(PMingLiU);
27 | }
28 |
29 | @font-face {
30 | han-range-cjk();
31 | font-family: 'Han Songti';
32 | src:
33 | local(YuMincho),
34 | local('Hiragino Mincho ProN'),
35 | local('Hiragino Mincho Pro'),
36 | local('MS Mincho');
37 | }
38 |
39 | // 2
40 | @font-face {
41 | font-family: 'Han Songti CNS';
42 | src:
43 | local('Songti TC Regular'),
44 | local(STSongti-TC-Regular),
45 | local('Songti TC'),
46 | local('Lisong Pro'),
47 |
48 | local('Songti SC Regular'),
49 | local(STSongti-SC-Regular),
50 | local('Songti SC'),
51 | local(STSong),
52 |
53 | local(PMingLiU),
54 | local(SimSun);
55 | }
56 |
57 | // 3
58 | @font-face {
59 | font-family: 'Han Songti GB';
60 | src:
61 | local('Songti SC Regular'),
62 | local(STSongti-SC-Regular),
63 | local('Songti SC'),
64 | local(STSong),
65 | local(SimSun),
66 | local(PMingLiU);
67 | }
68 |
69 | /*
70 | * Bold
71 | */
72 |
73 | // 1
74 | @font-face {
75 | font-family: 'Han Songti';
76 | font-weight: 600;
77 | src:
78 | local('STSongti SC Bold'),
79 | local('STSongti TC Bold'),
80 | local(STSongti-SC-Bold),
81 | local(STSongti-TC-Bold),
82 | local('STSongti SC'),
83 | local('STSongti TC');
84 | }
85 |
86 | @font-face {
87 | han-range-cjk();
88 | font-family: 'Han Songti';
89 | font-weight: 600;
90 | src:
91 | local('YuMincho Demibold'),
92 | local('Hiragino Mincho ProN W6'),
93 | local('Hiragino Mincho Pro W6'),
94 | local(YuMin-Demibold),
95 | local(HiraMinProN-W6),
96 | local(HiraMinPro-W6),
97 | local(YuMincho),
98 | local('Hiragino Mincho ProN'),
99 | local('Hiragino Mincho Pro');
100 | }
101 |
102 | // 2
103 | @font-face {
104 | font-family: 'Han Songti CNS';
105 | font-weight: 600;
106 | src:
107 | local('STSongti TC Bold'),
108 | local('STSongti SC Bold'),
109 | local(STSongti-TC-Bold),
110 | local(STSongti-SC-Bold),
111 | local('STSongti TC'),
112 | local('STSongti SC');
113 | }
114 |
115 | // 3
116 | @font-face {
117 | font-family: 'Han Songti GB';
118 | font-weight: 600;
119 | src:
120 | local('STSongti SC Bold'),
121 | local(STSongti-SC-Bold),
122 | local('STSongti SC');
123 | }
124 |
125 |
--------------------------------------------------------------------------------
/src/styl/typography/typography.styl:
--------------------------------------------------------------------------------
1 |
2 | // Root
3 | // ------
4 | {$han-root}
5 | han-typeface-by-lang(sans, true)
6 | @extend $han-ligature, $han-no-locl
7 | [lang^='zh'],
8 | [lang*='Hant'],
9 | [lang='zh-TW'],
10 | [lang='zh-HK']
11 | @extend $han-sans-hant, $han-no-locl
12 | .no-unicoderange &
13 | @extend $han-sans-hant-nu
14 | [lang*='Hans'],
15 | [lang='zh-CN']
16 | @extend $han-sans-hans, $han-no-locl
17 | .no-unicoderange &
18 | @extend $han-sans-hans-nu
19 | [lang^='ja']
20 | @extend $han-sans-ja
21 | .no-unicoderange &
22 | @extend $han-sans-ja-nu
23 |
24 | // Biaodian correction (for non-unicode-range browsers)
25 | // ---------------------
26 | .no-unicoderange h-char
27 | &.bd-cop
28 | &:lang(zh-Hant),
29 | &:lang(zh-TW),
30 | &:lang(zh-HK)
31 | font-family: -apple-system, 'Han Heiti CNS'
32 | &.bd-liga,
33 | &[unicode='b7']
34 | @extend $han-ligature
35 | font-family: 'Biaodian Basic', 'Han Heiti'
36 | &[unicode='2018'],
37 | &[unicode='2019'],
38 | &[unicode='201c'],
39 | &[unicode='201d']
40 | &:lang(zh-Hans),
41 | &:lang(zh-CN)
42 | font-family: 'Han Heiti GB'
43 |
44 | // Sections & grouping content
45 | // -----------------------------
46 |
47 | // * Different typefaces in different situations.
48 | // *
49 | blockquote
50 | {$han-article} &
51 | han-typeface-by-lang(cursive)
52 | figure &
53 | {$han-article} &
54 | han-typeface-by-lang(serif)
55 |
56 | // Text-level semantics
57 | // ----------------------
58 |
59 | // * Importance in articles should be in sans-serif
60 | // * (opinionated).
61 | // *
62 | {$han-article} strong
63 | han-typeface-by-lang(sans)
64 | @extend $han-no-locl
65 | // * Correct Chinese monospace typeface issue in WebKit.
66 | // *
67 | code,
68 | kbd,
69 | samp,
70 | pre
71 | han-typeface-by-lang(mono)
72 | @extend $han-no-locl
73 |
74 | // * Fonts for alternative voice and variable
75 | // * in different situations.
76 | i,
77 | var
78 | han-typeface-by-lang(cursive-italic)
79 | font-style: inherit
80 | // 1
81 | {$han-article} blockquote &
82 | han-typeface-by-lang(sans-italic)
83 | @extend $han-no-locl
84 |
85 | // * 1. Use `Zhuyin Kaiti` for non-checked tones.
86 | // * 2. Zhuyin: checked tone ligatures (方言音符號入聲連字).
87 | // * 3. Romanisation: checked tone ligatures (拉丁字母入聲連字).
88 | // *
89 | ruby,
90 | h-ruby
91 | h-zhuyin,
92 | h-zhuyin h-diao
93 | // 1, 2
94 | @extend $han-ligature
95 | .no-unicoderange &
96 | font-family: "Zhuyin Kaiti", cursive, serif
97 | h-diao
98 | font-family: "Zhuyin Kaiti", cursive, serif
99 | &.romanization rt,
100 | [annotation] rt
101 | // 3
102 | @extend $han-ligature
103 | font-family: "Romanization Sans", $han-sans, han-typeface("Han Heiti", $han-glyph-set-hant, $han-sans-zh), sans-serif
104 |
105 |
--------------------------------------------------------------------------------
/src/js/core.js:
--------------------------------------------------------------------------------
1 | define([
2 | './var/document',
3 | './var/root',
4 | './var/body'
5 | ], function( document, root, body ) {
6 |
7 | var VERSION = '@VERSION'
8 |
9 | var ROUTINE = [
10 | // Initialise the condition with feature-detecting
11 | // classes (Modernizr-alike), binding onto the root
12 | // element, possibly ``.
13 | 'initCond',
14 |
15 | // Address element normalisation
16 | 'renderElem',
17 |
18 | // Handle Biaodian
19 | /* 'jinzify', */
20 | 'renderJiya',
21 | 'renderHanging',
22 |
23 | // Address Biaodian correction
24 | 'correctBiaodian',
25 |
26 | // Address Hanzi and Western script mixed spacing
27 | 'renderHWS',
28 |
29 | // Address presentational correction to combining ligatures
30 | 'substCombLigaWithPUA'
31 |
32 | // Address semantic correction to inaccurate characters
33 | // **Note:** inactivated by default
34 | /* 'substInaccurateChar', */
35 | ]
36 |
37 | // Define Han
38 | var Han = function( context, condition ) {
39 | return new Han.fn.init( context, condition )
40 | }
41 |
42 | var init = function() {
43 | if ( arguments[ 0 ] ) {
44 | this.context = arguments[ 0 ]
45 | }
46 | if ( arguments[ 1 ] ) {
47 | this.condition = arguments[ 1 ]
48 | }
49 | return this
50 | }
51 |
52 | Han.version = VERSION
53 |
54 | Han.fn = Han.prototype = {
55 | version: VERSION,
56 |
57 | constructor: Han,
58 |
59 | // Body as the default target context
60 | context: body,
61 |
62 | // Root element as the default condition
63 | condition: root,
64 |
65 | // Default rendering routine
66 | routine: ROUTINE,
67 |
68 | init: init,
69 |
70 | setRoutine: function( routine ) {
71 | if ( Array.isArray( routine )) {
72 | this.routine = routine
73 | }
74 | return this
75 | },
76 |
77 | // Note that the routine set up here will execute
78 | // only once. The method won't alter the routine in
79 | // the instance or in the prototype chain.
80 | render: function( routine ) {
81 | var it = this
82 | var routine = Array.isArray( routine )
83 | ? routine
84 | : this.routine
85 |
86 | routine
87 | .forEach(function( method ) {
88 | if (
89 | typeof method === 'string' &&
90 | typeof it[ method ] === 'function'
91 | ) {
92 | it[ method ]()
93 | } else if (
94 | Array.isArray( method ) &&
95 | typeof it[ method[0] ] === 'function'
96 | ) {
97 | it[ method.shift() ].apply( it, method )
98 | }
99 | })
100 | return this
101 | }
102 | }
103 |
104 | Han.fn.init.prototype = Han.fn
105 |
106 | /**
107 | * Shortcut for `render()` under the default
108 | * situation.
109 | *
110 | * Once initialised, replace `Han.init` with the
111 | * instance for future usage.
112 | */
113 | Han.init = function() {
114 | return Han.init = Han().render()
115 | }
116 |
117 | return Han
118 | })
119 |
--------------------------------------------------------------------------------
/src/sass/typography/ff/_songti.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * The Four Typefaces: Songti (serif)
4 | * 四大字體集・宋體
5 | */
6 |
7 | // * 1. Recommended (推薦傳統字形,適用繁體漢字)
8 | // * 2. CNS (台灣教育部國字標準字體[字形])
9 | // * 3. GB (中國國家標準)
10 |
11 | // 1
12 | @font-face {
13 | font-family: 'Han Songti';
14 | src:
15 | local('Songti SC Regular'),
16 | local(STSongti-SC-Regular),
17 | local('Songti SC'),
18 | local('Songti TC Regular'),
19 | local(STSongti-TC-Regular),
20 | local('Songti TC'),
21 |
22 | local(STSong),
23 | local('Lisong Pro'),
24 |
25 | local(SimSun),
26 | local(PMingLiU)
27 | ;
28 | }
29 |
30 | @font-face {
31 | @include han-range-cjk;
32 | font-family: 'Han Songti';
33 | src:
34 | local(YuMincho),
35 | local('Hiragino Mincho ProN'),
36 | local('Hiragino Mincho Pro'),
37 | local('MS Mincho')
38 | ;
39 | }
40 |
41 | // 2
42 | @font-face {
43 | font-family: 'Han Songti CNS';
44 | src:
45 | local('Songti TC Regular'),
46 | local(STSongti-TC-Regular),
47 | local('Songti TC'),
48 | local('Lisong Pro'),
49 |
50 | local('Songti SC Regular'),
51 | local(STSongti-SC-Regular),
52 | local('Songti SC'),
53 | local(STSong),
54 |
55 | local(PMingLiU),
56 | local(SimSun)
57 | ;
58 | }
59 |
60 | // 3
61 | @font-face {
62 | font-family: 'Han Songti GB';
63 | src:
64 | local('Songti SC Regular'),
65 | local(STSongti-SC-Regular),
66 | local('Songti SC'),
67 | local(STSong),
68 | local(SimSun),
69 | local(PMingLiU)
70 | ;
71 | }
72 |
73 | /*
74 | * Bold
75 | */
76 |
77 | // 1
78 | @font-face {
79 | font-family: 'Han Songti';
80 | font-weight: 600;
81 | src:
82 | local('STSongti SC Bold'),
83 | local('STSongti TC Bold'),
84 | local(STSongti-SC-Bold),
85 | local(STSongti-TC-Bold),
86 | local('STSongti SC'),
87 | local('STSongti TC')
88 | ;
89 | }
90 |
91 | @font-face {
92 | @include han-range-cjk;
93 | font-family: 'Han Songti';
94 | font-weight: 600;
95 | src:
96 | local('YuMincho Demibold'),
97 | local('Hiragino Mincho ProN W6'),
98 | local('Hiragino Mincho Pro W6'),
99 | local(YuMin-Demibold),
100 | local(HiraMinProN-W6),
101 | local(HiraMinPro-W6),
102 | local(YuMincho),
103 | local('Hiragino Mincho ProN'),
104 | local('Hiragino Mincho Pro')
105 | ;
106 | }
107 |
108 | // 2
109 | @font-face {
110 | font-family: 'Han Songti CNS';
111 | font-weight: 600;
112 | src:
113 | local('STSongti TC Bold'),
114 | local('STSongti SC Bold'),
115 | local(STSongti-TC-Bold),
116 | local(STSongti-SC-Bold),
117 | local('STSongti TC'),
118 | local('STSongti SC')
119 | ;
120 | }
121 |
122 | // 3
123 | @font-face {
124 | font-family: 'Han Songti GB';
125 | font-weight: 600;
126 | src:
127 | local('STSongti SC Bold'),
128 | local(STSongti-SC-Bold),
129 | local('STSongti SC')
130 | ;
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/src/sass/typography/_typography.sass:
--------------------------------------------------------------------------------
1 |
2 | // Root
3 | // ------
4 |
5 | #{$han-root}
6 | +han-typeface-by-lang( sans, true )
7 | @extend %han-ligature, %han-no-locl
8 |
9 | [lang^='zh'],
10 | [lang*='Hant'],
11 | [lang='zh-TW'],
12 | [lang='zh-HK']
13 | @extend %han-sans-hant, %han-no-locl
14 |
15 | .no-unicoderange &
16 | @extend %han-sans-hant-nu
17 |
18 | [lang*='Hans'],
19 | [lang='zh-CN']
20 | @extend %han-sans-hans, %han-no-locl
21 |
22 | .no-unicoderange &
23 | @extend %han-sans-hans-nu
24 |
25 | [lang^='ja']
26 | @extend %han-sans-ja
27 |
28 | .no-unicoderange &
29 | @extend %han-sans-ja-nu
30 |
31 | // Biaodian correction (for non-unicode-range browsers)
32 | // ---------------------
33 | .no-unicoderange h-char
34 | &.bd-cop
35 | &:lang(zh-Hant),
36 | &:lang(zh-TW),
37 | &:lang(zh-HK)
38 | font-family: -apple-system, 'Han Heiti CNS'
39 | &.bd-liga,
40 | &[unicode='b7']
41 | @extend %han-ligature
42 | font-family: 'Biaodian Basic', 'Han Heiti'
43 | &[unicode='2018'],
44 | &[unicode='2019'],
45 | &[unicode='201c'],
46 | &[unicode='201d']
47 | &:lang(zh-Hans),
48 | &:lang(zh-CN)
49 | font-family: 'Han Heiti GB'
50 |
51 | // Sections & grouping content
52 | // -----------------------------
53 |
54 | // * Different typefaces in different situations.
55 | // *
56 | blockquote
57 | #{$han-article} &
58 | +han-typeface-by-lang( cursive )
59 |
60 | figure &
61 | #{$han-article} &,
62 | &
63 | +han-typeface-by-lang( serif )
64 |
65 | // Text-level semantics
66 | // ----------------------
67 |
68 | // * Importance in articles should be in sans-serif
69 | // * (opinionated).
70 | // *
71 | #{$han-article} strong
72 | +han-typeface-by-lang( sans )
73 | @extend %han-no-locl
74 |
75 | // * Correct Chinese monospace typeface issue in WebKit.
76 | // *
77 | code,
78 | kbd,
79 | samp,
80 | pre
81 | +han-typeface-by-lang( mono )
82 | @extend %han-no-locl
83 |
84 | // * Fonts for alternative voice and variable
85 | // * in different situations.
86 | i,
87 | var
88 | +han-typeface-by-lang( cursive-italic )
89 | font-style: inherit
90 |
91 | // 1
92 | #{$han-article} blockquote &
93 | +han-typeface-by-lang( sans-italic )
94 | @extend %han-no-locl
95 |
96 | // * 1. Use `Zhuyin Kaiti` for non-checked tones.
97 | // * 2. Zhuyin: checked tone ligatures (方言音符號入聲連字).
98 | // * 3. Romanisation: checked tone ligatures (拉丁字母入聲連字).
99 | // *
100 | ruby,
101 | h-ruby
102 | h-zhuyin,
103 | h-diao
104 | // 1, 2
105 | @extend %han-ligature
106 |
107 | .no-unicoderange &
108 | font-family: 'Zhuyin Kaiti', cursive, serif
109 |
110 | h-diao
111 | font-family: 'Zhuyin Kaiti', cursive, serif
112 |
113 | &.romanization rt,
114 | [annotation] rt
115 | // 3
116 | @extend %han-ligature
117 | font-family: 'Romanization Sans', $han-sans, han-typeface( 'Han Heiti', $han-glyph-set-hant, $han-sans-zh ), sans-serif
118 |
119 |
--------------------------------------------------------------------------------
/src/sass/typography/extend/_sans.scss:
--------------------------------------------------------------------------------
1 |
2 | %han-sans {
3 | font-family:
4 | $han-sans,
5 | han-typeface( 'Han Heiti', $_default-variant, $han-sans-zh ),
6 | sans-serif
7 | ;
8 | }
9 |
10 | %han-sans-hant {
11 | font-family:
12 | han-biaodian( Sans, $han-biaodian-hant ),
13 | //'Numeral LF Sans',
14 | $han-sans,
15 | 'Zhuyin Heiti',
16 | han-typeface( 'Han Heiti', $han-glyph-set-hant, $han-sans-zh ),
17 | sans-serif
18 | ;
19 | }
20 |
21 | %han-sans-hant-nu {
22 | font-family:
23 | $han-sans,
24 | han-typeface( 'Han Heiti', $han-glyph-set-hant, $han-sans-zh ),
25 | sans-serif
26 | ;
27 | }
28 |
29 | %han-sans-hans {
30 | font-family:
31 | han-biaodian( Sans, $han-biaodian-hans ),
32 | //'Numeral LF Sans',
33 | $han-sans,
34 | han-typeface( 'Han Heiti', $han-glyph-set-hans, $han-sans-zh ),
35 | sans-serif
36 | ;
37 | }
38 |
39 | %han-sans-hans-nu {
40 | font-family:
41 | $han-sans,
42 | han-typeface( 'Han Heiti', $han-glyph-set-hans, $han-sans-zh ),
43 | sans-serif
44 | ;
45 | }
46 |
47 | %han-sans-ja {
48 | font-family:
49 | 'Yakumono Sans',
50 | //'Numeral LF Sans',
51 | $han-sans,
52 | sans-serif
53 | ;
54 | }
55 |
56 | %han-sans-ja-nu {
57 | font-family: $han-sans, sans-serif;
58 | }
59 |
60 | /**
61 | * Sans Italic
62 | */
63 | %han-sans-italic {
64 | font-family:
65 | 'Latin Italic Sans',
66 | $han-sans,
67 | han-typeface( 'Han Heiti', $_default-variant, $han-sans-zh ),
68 | sans-serif
69 | ;
70 | }
71 |
72 | %han-sans-italic-hant {
73 | font-family:
74 | han-biaodian( Sans, $han-biaodian-hant ),
75 | 'Latin Italic Sans',
76 | $han-sans,
77 | 'Zhuyin Heiti',
78 | han-typeface( 'Han Heiti', $han-glyph-set-hant, $han-sans-zh ),
79 | sans-serif
80 | ;
81 | }
82 |
83 | %han-sans-italic-hant-nu {
84 | font-family:
85 | 'Latin Italic Sans',
86 | $han-sans,
87 | han-typeface( 'Han Heiti', $han-glyph-set-hant, $han-sans-zh ),
88 | sans-serif
89 | ;
90 | }
91 |
92 | %han-sans-italic-hant-nu {
93 | font-family:
94 | 'Latin Italic Sans',
95 | $han-sans,
96 | han-typeface( 'Han Heiti', $han-glyph-set-hant, $han-sans-zh ),
97 | sans-serif
98 | ;
99 | }
100 |
101 | %han-sans-italic-hans {
102 | font-family:
103 | han-biaodian( Sans, $han-biaodian-hans ),
104 | 'Latin Italic Sans',
105 | $han-sans,
106 | han-typeface( 'Han Heiti', $han-glyph-set-hans, $han-sans-zh ),
107 | sans-serif
108 | ;
109 | }
110 |
111 | %han-sans-italic-hans-nu {
112 | font-family:
113 | 'Latin Italic Sans',
114 | $han-sans,
115 | han-typeface( 'Han Heiti', $han-glyph-set-hans, $han-sans-zh ),
116 | sans-serif
117 | ;
118 | }
119 |
120 | %han-sans-italic-ja {
121 | font-family:
122 | 'Yakumono Sans',
123 | 'Latin Italic Sans',
124 | $han-sans,
125 | sans-serif
126 | ;
127 | }
128 |
129 | %han-sans-italic-ja-nu {
130 | font-family: 'Latin Italic Sans', $han-sans, sans-serif;
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/demo/biaodian.html:
--------------------------------------------------------------------------------
1 | 測試・標點符號 — 漢字標準格式測試·標點符號
提示:此測試頁需在支援CSS3 @font-face屬性unicode-range的瀏覽器下方可正常顯示。其餘瀏覽器僅支援基本符號(間隔號、刪節號、破折號)修正。
推薦
句號。點式全形句號.逗號,頓號、分號;冒號:問號?嘆號!
連接號〇-九 斜線/或\
「『內容』内容」‘內“內容”容’《內容》〈內容〉(內〔內容〕容)
間隔號甲·乙
連字時:破折號——刪節號……
單獨存在時:破拆號— 刪節號…
台灣教育部式(CNS)
句號。點式全形句號.逗號,頓號、分號;冒號:問號?嘆號!
連接號〇-九 斜線/或\
「『內容』内容」‘內“內容”容’《內容》〈內容〉(內〔內容〕容)
間隔號甲·乙
連字時:破折號——刪節號……
單獨存在時:破拆號— 刪節號…
中國國家標準(GB)
句号。点式全形句号.逗号,顿号、分号;冒号:问号?叹号!
连接号〇-九 斜线/或\
「『内容』内容」‘内“内容”容’《内容》〈内容〉(内〔内容〕容)
間隔號甲·乙
連字時:破折號——刪節號……
單獨存在時:破拆號— 刪節號…
襯線標點
推薦
句號。點式全形句號.逗號,頓號、分號;冒號:問號?嘆號!
連接號〇-九 斜線/或\
「『內容』内容」‘內“內容”容’《內容》〈內容〉(內〔內容〕容)
間隔號甲·乙
連字時:破折號——刪節號……
單獨存在時:破拆號— 刪節號…
台灣教育部式(CNS)
句號。點式全形句號.逗號,頓號、分號;冒號:問號?嘆號!
連接號〇-九 斜線/或\
「『內容』内容」‘內“內容”容’《內容》〈內容〉(內〔內容〕容)
間隔號甲·乙
連字時:破折號——刪節號……
單獨存在時:破拆號— 刪節號…
中國國家標準(GB)
句号。点式全形句号.逗号,顿号、分号;冒号:问号?叹号!
连接号〇-九 斜线/或\
「『内容』内容」‘内“内容”容’《内容》〈内容〉(内〔内容〕容)
間隔號甲·乙
連字時:破折號——刪節號……
單獨存在時:破拆號— 刪節號…
--------------------------------------------------------------------------------
/demo/index.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html(lang='zh-Hant').han-init
3 | head
4 | meta(charset='utf-8')
5 | title 測試頁索引 — 漢字標準格式
6 | link(rel='stylesheet', href='./han.min.css')
7 |
8 | style.
9 | html {
10 | overflow-x: hidden;
11 | }
12 |
13 | article {
14 | /* position */
15 | margin: 0 auto;
16 |
17 | /* box */
18 | max-width: 35em;
19 | padding: 0 .5em 15em;
20 | }
21 | meta(name='viewport' content='width=device-width, initial-scale=1.0')
22 | meta(name='description' content='印刷品般的漢字網頁排版框架')
23 | meta(name='keywords' content='漢字標準格式, 中文, 排版, 排版規範, 日文, 字體排印, 文字設計, CLReq, CSS, Sass, typography')
24 |
25 | body.test
26 | article
27 | h1 測試頁索引
28 | ul#test-pages
29 | li: a(href='../test') JavaScript APIs
30 | li: a(href='test.html') 測試頁(標準,繁體中文)
31 | li: a(href='test-hans.html' lang='zh-Hans') 测试页(标准,简体中文)
32 | li: a(href='test-ja.html' lang='ja') 測試頁(標準,日本語)
33 | li: a(href='test-amd.html') 測試頁(AMD模組)
34 | li: a(href='test-commonjs.html') 測試頁(CommonJS模組,browserify)
35 | li: a(href='test-nojs.html') 測試頁(無JavaScript)
36 | section#normalisation
37 | h2 Normalisation(樣式標準化)
38 | section#wuxu_peihe_js_de_yuansu_yangshi_xiuzheng
39 | h3 毋須配合JavaScript的元素樣式修正
40 | p 見
41 | a(href='#test-pages') 上列測試頁
42 | | 。
43 | section#peihe_js_de_yuansu_yangshi_xiuzheng
44 | h3 配合JavaScript的元素樣式修正
45 | ul
46 | li: a(href='./deco-line.html') 文字裝飾線元素
47 | li: a(href='./em.html') 強調元素(着重號)
48 | li: a(href='./ruby.html') 行間注元素
49 | section#ziti
50 | h2 字體
51 | section#hanzi
52 | h3 漢字字體
53 | ul
54 | li: a(href='./biaodian.html') 標點符號
55 | li: a(href='./four.html') 四大字體集
56 | li: a(href='generics.html') 字體基型(
57 | span(lang='en') typeface generics
58 | | )與
59 | code @extend
60 | section#qita
61 | h3 其他
62 | ul
63 | li: a(href='./italic.html') 西文意大利體
64 | li: a(href='./numeral.html') 數字
65 | li: a(href='./ruby(ff).html') 標音(注音符號、羅馬拼音)
66 | section#paiban
67 | h2 排版
68 | section#zhangjie_de_zucheng
69 | h3 章節的組成
70 | ul
71 | li: a(href='./well-knit.html') 文章、章節與內容的邊界調整
72 | li: a(href='./counter.html') 章節與目錄的計數
73 | section#hang_de_zucheng
74 | h3 行的組成
75 | ul
76 | li: a(href='./hws.html') 漢字-西文混排間隙
77 | li: a(href='./jiya.html') 標點擠壓
78 | li: a(href='./hanging.html') 行尾點號懸掛
79 | li: a(href='./subst.html') 字元的替換
80 | //
81 | section#api
82 | h2 API
83 | ul
84 | li: a(href='./api/jinzify.html') 強制標點禁則
85 | li: a(href='./api/charify.html') 字元級選擇器
86 | li: a(href='./api/deco-line.html') 相鄰文字裝飾線
87 | li: a(href='./api/em.html') 着重號
88 | li: a(href='./api/ruby.html') 行間注元素
89 |
90 | // Here goes scripts
91 | script(src='./han.min.js')
92 |
--------------------------------------------------------------------------------
/src/sass/typography/extend/_serif.scss:
--------------------------------------------------------------------------------
1 |
2 | %han-serif {
3 | font-family:
4 | $han-serif,
5 | han-typeface( 'Han Songti', $_default-variant, $han-serif-zh ),
6 | cursive, serif
7 | ;
8 | }
9 |
10 | %han-serif-hant {
11 | font-family:
12 | han-biaodian( Serif, $han-biaodian-hant ),
13 | 'Numeral LF Serif',
14 | $han-serif,
15 | 'Zhuyin Kaiti',
16 | han-typeface( 'Han Songti', $han-glyph-set-hant, $han-serif-zh ),
17 | serif
18 | ;
19 | }
20 |
21 | %han-serif-hant-nu {
22 | font-family:
23 | 'Numeral LF Serif',
24 | $han-serif,
25 | han-typeface( 'Han Songti', $han-glyph-set-hant, $han-serif-zh ),
26 | serif
27 | ;
28 | }
29 |
30 | %han-serif-hans {
31 | font-family:
32 | han-biaodian( Serif, $han-biaodian-hans ),
33 | 'Numeral LF Serif',
34 | $han-serif,
35 | han-typeface( 'Han Songti', $han-glyph-set-hans, $han-serif-zh ),
36 | serif
37 | ;
38 | }
39 |
40 | %han-serif-hans-nu {
41 | font-family:
42 | 'Numeral LF Serif',
43 | $han-serif,
44 | han-typeface( 'Han Songti', $han-glyph-set-hans, $han-serif-zh ),
45 | serif
46 | ;
47 | }
48 |
49 | %han-serif-ja {
50 | font-family:
51 | 'Yakumono Serif',
52 | 'Numeral LF Serif',
53 | $han-serif,
54 | serif
55 | ;
56 | }
57 |
58 | %han-serif-ja-nu {
59 | font-family: 'Numeral LF Serif', $han-serif, serif;
60 | }
61 |
62 | /**
63 | * Serif Italic
64 | */
65 | %han-serif-italic {
66 | font-family:
67 | 'Latin Italic Serif',
68 | $han-serif,
69 | han-typeface( 'Han Songti', $_default-variant, $han-serif-zh ),
70 | cursive, serif
71 | ;
72 | }
73 |
74 | %han-serif-italic-hant {
75 | font-family:
76 | han-biaodian( Serif, $han-biaodian-hant ),
77 | 'Numeral LF Italic Serif',
78 | 'Latin Italic Serif',
79 | $han-serif,
80 | 'Zhuyin Kaiti',
81 | han-typeface( 'Han Songti', $han-glyph-set-hant, $han-serif-zh ),
82 | cursive, serif
83 | ;
84 | }
85 |
86 | %han-serif-italic-hant-nu {
87 | font-family:
88 | 'Numeral LF Italic Serif',
89 | 'Latin Italic Serif',
90 | $han-serif,
91 | han-typeface( 'Han Songti', $han-glyph-set-hant, $han-serif-zh ),
92 | cursive, serif
93 | ;
94 | }
95 |
96 | %han-serif-italic-hans {
97 | font-family:
98 | han-biaodian( Serif, $han-biaodian-hans ),
99 | 'Numeral LF Italic Serif',
100 | 'Latin Italic Serif',
101 | $han-serif,
102 | han-typeface( 'Han Songti', $han-glyph-set-hans, $han-serif-zh ),
103 | cursive, serif
104 | ;
105 | }
106 |
107 | %han-serif-italic-hans-nu {
108 | font-family:
109 | 'Numeral LF Italic Serif',
110 | 'Latin Italic Serif',
111 | $han-serif,
112 | han-typeface( 'Han Songti', $han-glyph-set-hans, $han-serif-zh ),
113 | cursive, serif
114 | ;
115 | }
116 |
117 | %han-serif-italic-ja {
118 | font-family:
119 | 'Yakumono Serif',
120 | 'Numeral LF Italic Serif',
121 | 'Latin Italic Serif',
122 | $han-serif,
123 | cursive, serif
124 | ;
125 | }
126 |
127 | %han-serif-italic-ja-nu {
128 | font-family: 'Numeral LF Italic Serif', 'Latin Italic Serif', $han-serif, cursive, serif;
129 | }
130 |
131 |
--------------------------------------------------------------------------------
/src/sass/typography/extend/_cursive.scss:
--------------------------------------------------------------------------------
1 |
2 | %han-cursive {
3 | font-family:
4 | $han-serif,
5 | han-typeface( 'Han Kaiti', $_default-variant, $han-cursive-zh ),
6 | cursive, serif
7 | ;
8 | }
9 |
10 | %han-cursive-hant {
11 | font-family:
12 | han-biaodian( Serif, $han-biaodian-hant ),
13 | 'Numeral LF Serif',
14 | $han-serif,
15 | 'Zhuyin Kaiti',
16 | han-typeface( 'Han Kaiti', $han-glyph-set-hant, $han-cursive-zh ),
17 | cursive, serif
18 | ;
19 | }
20 |
21 | %han-cursive-hant-nu {
22 | font-family:
23 | 'Numeral LF Serif',
24 | $han-serif,
25 | han-typeface( 'Han Kaiti', $han-glyph-set-hant, $han-cursive-zh ),
26 | cursive, serif
27 | ;
28 | }
29 |
30 | %han-cursive-hans {
31 | font-family:
32 | han-biaodian( Serif, $han-biaodian-hans ),
33 | 'Numeral LF Serif',
34 | $han-serif,
35 | han-typeface( 'Han Kaiti', $han-glyph-set-hans, $han-cursive-zh ),
36 | cursive, serif
37 | ;
38 | }
39 |
40 | %han-cursive-hans-nu {
41 | font-family:
42 | 'Numeral LF Serif',
43 | $han-serif,
44 | han-typeface( 'Han Kaiti', $han-glyph-set-hans, $han-cursive-zh ),
45 | cursive, serif
46 | ;
47 | }
48 |
49 | %han-cursive-ja {
50 | font-family:
51 | 'Yakumono Serif',
52 | 'Numeral LF Serif',
53 | $han-serif,
54 | cursive, serif
55 | ;
56 | }
57 |
58 | %han-cursive-ja-nu {
59 | font-family: 'Numeral LF Serif', $han-serif, cursive, serif;
60 | }
61 |
62 | /**
63 | * Cursive Italic
64 | */
65 | %han-cursive-italic {
66 | font-family:
67 | 'Latin Italic Serif',
68 | $han-serif,
69 | han-typeface( 'Han Kaiti', $_default-variant, $han-cursive-zh ),
70 | cursive, serif
71 | ;
72 | }
73 |
74 | %han-cursive-italic-hant {
75 | font-family:
76 | han-biaodian( Serif, $han-biaodian-hant ),
77 | 'Numeral LF Italic Serif',
78 | 'Latin Italic Serif',
79 | $han-serif,
80 | 'Zhuyin Kaiti',
81 | han-typeface( 'Han Kaiti', $han-glyph-set-hant, $han-cursive-zh ),
82 | cursive, serif
83 | ;
84 | }
85 |
86 | %han-cursive-italic-hant-nu {
87 | font-family:
88 | 'Numeral LF Italic Serif',
89 | 'Latin Italic Serif',
90 | $han-serif,
91 | han-typeface( 'Han Kaiti', $han-glyph-set-hant, $han-cursive-zh ),
92 | cursive, serif
93 | ;
94 | }
95 |
96 | %han-cursive-italic-hans {
97 | font-family:
98 | han-biaodian( Serif, $han-biaodian-hans ),
99 | 'Numeral LF Italic Serif',
100 | 'Latin Italic Serif',
101 | $han-serif,
102 | han-typeface( 'Han Kaiti', $han-glyph-set-hans, $han-cursive-zh ),
103 | cursive, serif
104 | ;
105 | }
106 |
107 | %han-cursive-italic-hans-nu {
108 | font-family:
109 | 'Numeral LF Italic Serif',
110 | 'Latin Italic Serif',
111 | $han-serif,
112 | han-typeface( 'Han Kaiti', $han-glyph-set-hans, $han-cursive-zh ),
113 | cursive, serif
114 | ;
115 | }
116 |
117 | %han-cursive-italic-ja {
118 | font-family:
119 | 'Yakumono Serif',
120 | 'Numeral LF Italic Serif',
121 | 'Latin Italic Serif',
122 | $han-serif,
123 | cursive, serif
124 | ;
125 | }
126 |
127 | %han-cursive-italic-ja-nu {
128 | font-family: 'Numeral LF Italic Serif', 'Latin Italic Serif', $han-serif, cursive, serif;
129 | }
130 |
131 |
--------------------------------------------------------------------------------
/src/js/inline/hanging.js:
--------------------------------------------------------------------------------
1 | define([
2 | '../core',
3 | '../method',
4 | '../find'
5 | ], function( Han, $ ) {
6 |
7 | var HANGABLE_CLASS = 'bd-hangable'
8 | var HANGABLE_AVOID = 'h-char.bd-hangable'
9 | var HANGABLE_CS_HTML = ' '
10 |
11 | var matches = Han.find.matches
12 |
13 | function detectSpaceFont() {
14 | var div = $.create( 'div' )
15 | var ret
16 |
17 | div.innerHTML = 'a ba b'
18 | body.appendChild( div )
19 | ret = div.firstChild.offsetWidth !== div.lastChild.offsetWidth
20 | $.remove( div )
21 | return ret
22 | }
23 |
24 | function insertHangableCS( $jinze ) {
25 | var $cs = $jinze.nextSibling
26 |
27 | if ( $cs && matches( $cs, 'h-cs.jinze-outer' )) {
28 | $cs.classList.add( 'hangable-outer' )
29 | } else {
30 | $jinze.insertAdjacentHTML(
31 | 'afterend',
32 | HANGABLE_CS_HTML
33 | )
34 | }
35 | }
36 |
37 | Han.support['han-space'] = detectSpaceFont()
38 |
39 | $.extend( Han, {
40 | detectSpaceFont: detectSpaceFont,
41 | isSpaceFontLoaded: detectSpaceFont(),
42 |
43 | renderHanging: function( context ) {
44 | var context = context || document
45 | var finder = Han.find( context )
46 |
47 | finder
48 | .avoid( 'textarea, code, kbd, samp, pre' )
49 | .avoid( HANGABLE_AVOID )
50 | .replace(
51 | TYPESET.jinze.hanging,
52 | function( portion ) {
53 | if ( /^[\x20\t\r\n\f]+$/.test( portion.text )) {
54 | return ''
55 | }
56 |
57 | var $elmt = portion.node.parentNode
58 | var $jinze, $new, $bd, biaodian
59 |
60 |
61 | if ( $jinze = $.parent( $elmt, 'h-jinze' )) {
62 | insertHangableCS( $jinze )
63 | }
64 |
65 | biaodian = portion.text.trim()
66 |
67 | $new = Han.createBDChar( biaodian )
68 | $new.innerHTML = '' + biaodian + ''
69 | $new.classList.add( HANGABLE_CLASS )
70 |
71 | $bd = $.parent( $elmt, 'h-char.biaodian' )
72 |
73 | return !$bd
74 | ? $new
75 | : (function() {
76 | $bd.classList.add( HANGABLE_CLASS )
77 |
78 | return matches( $elmt, 'h-inner, h-inner *' )
79 | ? biaodian
80 | : $new.firstChild
81 | })()
82 | }
83 | )
84 | return finder
85 | }
86 | })
87 |
88 | $.extend( Han.fn, {
89 | renderHanging: function() {
90 | var classList = this.condition.classList
91 | Han.isSpaceFontLoaded = detectSpaceFont()
92 |
93 | if (
94 | Han.isSpaceFontLoaded &&
95 | classList.contains( 'no-han-space' )
96 | ) {
97 | classList.remove( 'no-han-space' )
98 | classList.add( 'han-space' )
99 | }
100 |
101 | Han.renderHanging( this.context )
102 | return this
103 | },
104 |
105 | revertHanging: function() {
106 | $.qsa(
107 | 'h-char.bd-hangable, h-cs.hangable-outer',
108 | this.context
109 | ).forEach(function( $elmt ) {
110 | var classList = $elmt.classList
111 | classList.remove( 'bd-hangable' )
112 | classList.remove( 'hangable-outer' )
113 | })
114 | return this
115 | }
116 | })
117 |
118 | return Han
119 | })
120 |
121 |
--------------------------------------------------------------------------------
/src/sass/example.sass:
--------------------------------------------------------------------------------
1 |
2 | // **
3 | // * 設定
4 | // * Config
5 |
6 | // **
7 | // * 根元素
8 | // * `html` || `'*:root'`
9 | // *
10 | $han-root: html
11 |
12 | // **
13 | // * 文章選擇器
14 | // * 可能的選項:
15 | // * `article` || `.article` || `.post` || `.entry`
16 | // *
17 | $han-article: article
18 |
19 | // **
20 | // * 全域行高
21 | // * 推薦値:`1.2-1.7(em)`
22 | // *
23 | $han-line-height: 1.3
24 |
25 | // **
26 | // * 文章區塊行高
27 | // * 推薦値:`1.5-2(em)`
28 | // *
29 | $han-article-line-height: 1.7
30 |
31 | // **
32 | // * 文章區塊頭尾對齊
33 | // * `true` || `false`
34 | // *
35 | $han-article-justify: true
36 |
37 | // **
38 | // * [高級排版功能]
39 | // * 文章章節的計數
40 | // * `true` || `false`
41 | // *
42 | $han-section-counter: false
43 | // * 開啓文章章節的目錄計數
44 | $han-section-counter-toc: false
45 |
46 | // **
47 | // * 縮進
48 | // * 推薦値:`1em` || `2em`
49 | // *
50 | $han-indent: 2em
51 |
52 | // **
53 | // * 行動裝置上的縮進
54 | // * 推薦値:`1em` || `2em`
55 | // *
56 | $han-indent-md: 1em
57 |
58 | // **
59 | // * 行動裝置最大寬度(彈性設計,responsive web design)
60 | // * 推薦値:`480px` || `30em`
61 | // *
62 | $han-mobile-device-width: 480px
63 |
64 | // **
65 | // * 着重號
66 | // * 見:http://w3.org/TR/css-text-decor-3/#emphasis-marks
67 | // *
68 | // * `none` || `biaodian`
69 | $han-text-emphasis-skip: biaodian
70 | // * `none` || `filled` || `open`
71 | $han-text-emphasis-shape: filled
72 | // * `dot` || `circle` || `double-circle` || `triangle` || `sesame` ||
73 | $han-text-emphasis-mark: circle
74 | // * `over` || `under`
75 | $han-text-emphasis-posi: under
76 | // * `inherit` ||
77 | $han-text-emphasis-color: inherit
78 |
79 | // *
80 | // * 着重號(日文)
81 | // *
82 | $han-text-emphasis-shape-ja: filled
83 | $han-text-emphasis-mark-ja: sesame
84 | $han-text-emphasis-posi-ja: over
85 | $han-text-emphasis-color-ja: inherit
86 |
87 | // **
88 | // * 注音行間注字體大小(單位:em)
89 | // * http://www.w3.org/TR/clreq/#positioning_of_zhuyin
90 | // * 推薦値:`.25-.5(em)`
91 | // *
92 | $han-zhuyin-size: .4
93 |
94 | // **
95 | // * 中文地區變體預設値
96 | // *(繁體中文、簡體中文)
97 | // * `hant` || `hans`
98 | // *
99 | $han-default-variant: hant
100 |
101 | // **
102 | // * 繁體中文字形
103 | // * `default` || `CNS` || `GB`
104 | // *
105 | $han-glyph-set-hant: default
106 |
107 | // **
108 | // * 簡體中文字形
109 | // * `default` || `GB`
110 | // *
111 | $han-glyph-set-hans: GB
112 |
113 | // **
114 | // * 繁體中文標點
115 | // * `Pro` || `CNS` || `GB` || `simp`
116 | // *
117 | $han-biaodian-hant: Pro
118 |
119 | // **
120 | // * 簡體中文標點
121 | // * `Pro` || `CNS` || `GB` || `simp`
122 | // *
123 | $han-biaodian-hans: GB
124 |
125 | // **
126 | // * 各語言文字的標點懸掛與否
127 | // *
128 | $han-hanging-hant: false
129 | $han-hanging-hans: true
130 | $han-hanging-ja: true
131 |
132 | // **
133 | // * 西文(拉丁字母等)通用字體
134 | // *
135 | $han-sans: 'Helvetica Neue', Helvetica, Arial
136 | $han-serif: Georgia, 'Times New Roman'
137 | $han-cursive: 'Apple Chancery', 'Snell Roundhand'
138 | $han-mono: Menlo, Courier
139 |
140 | // **
141 | // * 中文通用字體
142 | // *
143 | $han-sans-zh: ''
144 | $han-serif-zh: ''
145 | $han-cursive-zh: ''
146 | $han-mono-zh: $han-sans-zh
147 |
148 | // **
149 | // * Web font路徑
150 | // *(注音符號、羅馬拼音陽入韻連字、部分標點修正、標點懸掛所需的空格)
151 | // *
152 | $han-font-path: './font/'
153 |
154 | // **
155 | // * 在所有樣式前滙入`_han.sass`
156 | // * Import `_han.sass` before anything else
157 | @import han
158 |
159 |
--------------------------------------------------------------------------------
/src/styl/example.styl:
--------------------------------------------------------------------------------
1 |
2 | // **
3 | // * 設定
4 | // * Config
5 | // **
6 | // * 根元素
7 | // * `html` || `'*:root'`
8 | // *
9 | $han-root = html
10 |
11 | // **
12 | // * 文章選擇器
13 | // * 可能的選項:
14 | // * `article` || `.article` || `.post` || `.entry`
15 | // *
16 | $han-article = article
17 |
18 | // **
19 | // * 全域行高
20 | // * 推薦値:`1.2-1.7(em)`
21 | // *
22 | $han-line-height = 1.3
23 |
24 | // **
25 | // * 文章區塊行高
26 | // * 推薦値:`1.5-2(em)`
27 | // *
28 | $han-article-line-height = 1.7
29 |
30 | // **
31 | // * 文章區塊頭尾對齊
32 | // * `true` || `false`
33 | // *
34 | $han-article-justify = true
35 |
36 | // **
37 | // * [高級排版功能]
38 | // * 文章章節的計數
39 | // * `true` || `false`
40 | // *
41 | $han-section-counter = false
42 |
43 | // * 開啓文章章節的目錄計數
44 | $han-section-counter-toc = false
45 |
46 | // **
47 | // * 縮進
48 | // * 推薦値:`1em` || `2em`
49 | // *
50 | $han-indent = 2em
51 |
52 | // **
53 | // * 行動裝置上的縮進
54 | // * 推薦値:`1em` || `2em`
55 | // *
56 | $han-indent-md = 1em
57 |
58 | // **
59 | // * 行動裝置最大寬度(彈性設計,responsive web design)
60 | // * 推薦値:`480px` || `30em`
61 | // *
62 | $han-mobile-device-width = 480px
63 | // **
64 | // * 着重號
65 | // * 見:http://w3.org/TR/css-text-decor-3/#emphasis-marks
66 | // *
67 | // * `none` || `biaodian`
68 | $han-text-emphasis-skip = biaodian
69 | // * `none` || `filled` || `open`
70 | $han-text-emphasis-shape = filled
71 | // * `dot` || `circle` || `double-circle` || `triangle` || `sesame` ||
72 | $han-text-emphasis-mark = circle
73 | // * `over` || `under`
74 | $han-text-emphasis-posi = under
75 | // * `inherit` ||
76 | $han-text-emphasis-color = inherit
77 |
78 | // *
79 | // * 着重號(日文)
80 | // *
81 | $han-text-emphasis-shape-ja = filled
82 | $han-text-emphasis-mark-ja = sesame
83 | $han-text-emphasis-posi-ja = over
84 | $han-text-emphasis-color-ja = inherit
85 |
86 | // **
87 | // * 注音行間注字體大小(單位:em)
88 | // * http://www.w3.org/TR/clreq/#positioning_of_zhuyin
89 | // * 推薦値:`.25-.5(em)`
90 | // *
91 | $han-zhuyin-ruby = .4
92 |
93 | // **
94 | // * 中文地區變體預設値
95 | // *(繁體中文、簡體中文)
96 | // * `hant` || `hans`
97 | // *
98 | $han-default-variant = hant
99 |
100 | // **
101 | // * 繁體中文字形
102 | // * `default` || `CNS` || `GB`
103 | // *
104 | $han-glyph-set-hant = default
105 |
106 | // **
107 | // * 簡體中文字形
108 | // * `default` || `GB`
109 | // *
110 | $han-glyph-set-hans = GB
111 |
112 | // **
113 | // * 繁體中文標點
114 | // * `Pro` || `CNS` || `GB` || `simp`
115 | // *
116 | $han-biaodian-hant = Pro
117 |
118 | // **
119 | // * 簡體中文標點
120 | // * `Pro` || `CNS` || `GB` || `simp`
121 | // *
122 | $han-biaodian-hans = GB
123 |
124 | // **
125 | // * 各語言文字的標點懸掛與否
126 | // *
127 | $han-hanging-hant = false
128 | $han-hanging-hans = true
129 | $han-hanging-ja = true
130 |
131 | // **
132 | // * 西文(拉丁字母等)通用字體
133 | // *
134 | $han-sans = "Helvetica Neue", Helvetica, Arial
135 | $han-serif = Georgia, "Times New Roman"
136 | $han-cursive = "Apple Chancery", "Snell Roundhand"
137 | $han-mono = Menlo, Courier
138 |
139 | // **
140 | // * 中文通用字體
141 | // *
142 | $han-sans-zh = ""
143 | $han-serif-zh = ""
144 | $han-cursive-zh = ""
145 | $han-mono-zh = $han-sans-zh
146 |
147 | // **
148 | // * Web font路徑
149 | // *(注音符號、羅馬拼音陽入韻連字、部分標點修正、標點懸掛所需的空格)
150 | // *
151 | $han-font-path = "./font/"
152 |
153 | // **
154 | // * 在所有樣式前滙入`src/styl`
155 | // * Import `src/styl` before anything else
156 | @import 'index'
157 |
158 |
--------------------------------------------------------------------------------
/demo/hanging.html:
--------------------------------------------------------------------------------
1 | 測試・行尾點號懸掛 — 漢字標準格式測試·行尾點號懸掛
提示:調整瀏覽器視窗寬度來觀看各種標點在行間的擠壓及懸掛行為。
提示二:文字橫排時,使用繁體中文的網頁或元素預設不開啓行尾點號懸掛,可透過相應的Sass變數啓用。
繁體中文標點
點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。
「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。
標、「點」標、「點」標、「點」標、「點」。
「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕
《書名》、「強調」、『重點』。
《書名》、「強調」、『重點』。
简体中文标点
点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。
「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。
标、「点」标、「点」标、「点」标、「点」。
「标点。」「『标』点,」《标点。》(Biao、)〔Dian、〕「标点。」「『标』点,」《标点。》(Biao、)〔Dian、〕「标点。」「『标』点,」《标点。》(Biao、)〔Dian、〕
Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。
「Biao」Dian,「〔Biao〕」Dian,[Biao]。「Biao」Dian,「〔Biao〕」Dian,[Biao]。「Biao」Dian,「〔Biao〕」Dian,[Biao]。
《書名》、「強調」、『重點』。
《書名》、「強調」、『重點』。
我认为,没人可以「如此」放肆,你说是吧!
请你们告诉我这是怎么一回事……。
把示例给看清楚了,这是一种点号、「开引号」的组合也可以标点悬挂的概念。
日文標點
點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。
「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。
標、「點」標、「點」標、「點」標、「點」。
「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕
Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。
「Biao」Dian,「〔Biao〕」Dian,[Biao]。「Biao」Dian,「〔Biao〕」Dian,[Biao]。「Biao」Dian,「〔Biao〕」Dian,[Biao]。
《書名》、「強調」、『重點』。
《書名》、「強調」、『重點』。
我認為,沒人可以「如此」放肆,你說是吧!
請你們告訴我這是怎麼一回事⋯⋯。
把示例給看清楚了,這是一種點號、「開引號」的組合也可以標點懸掛的概念。
--------------------------------------------------------------------------------
/demo/em.html:
--------------------------------------------------------------------------------
1 | 測試・強調元素(着重號)— 漢字標準格式測試·強調元素(着重號)
基本着重號
繁體中文的着重號和簡體中文一樣。
简体中文的着重号和繁体中文一样。
日本語の著重奌独特の風味。
完整中日韓意音文字區段支援
注意:部分擴展區漢字可能不為多數作業系統支援,而顯示為空白方框。安裝花園明朝體可以解決這個問題。
中日韓意音文字擴展區段:𫞵𫞦𠁻𠁶
13 | 意音數字零:〇
14 | 康熙字典及簡體字部首:⼌⿕⺃⻍⻰⻳
15 | 意音文字描述字元:⿸⿷⿳
標點規避
唐朝是中國歷史上一個重要的朝代。唐王李淵於618年逼隋恭帝禪位,遂建唐朝取代隋朝,設首都於長安。在其鼎盛時的7世紀,遙遠的中亞綠洲地帶亦受唐支配。唐朝在文化、政治、經濟、外交……等方面都達到了很高的成就,是中國歷史上的盛世之一,也是當時的世界強國。
日語着重號的標點規避
アンネリース・マリー・フランク(ドイツ語:Annelies Marie Frank、1929年6月12日-1945年3月上旬)は、『アンネの日記』の著者として知られるユダヤ系ドイツ人の少女である。
西文
拉丁字母
我道,¡Hola! 他問,¿Cómo estás?
德文中如何表達「羅曼式建築」這個概念?德國學者最初在teutsch、longobardisch和romantische三詞間猶豫,最終在19世紀30年代偏向了「romantishce」一詞。
希臘字母
至今關於古希臘遊吟詩人Ὅμηρος的資料很少,所以對其生平有很多說法,但都無確鑿證據。
西里爾字母
Храм-паметник „Свети Александър Невски‟是一座位於保加利亞首都索菲亞的保加利亞東正教大教堂。該教堂為新拜占庭式建築,是保加利亞主教的主座教堂,也是東正教在世界上最大的教堂之一,還是索菲亞的象徵之一以及主要的遊覽景點。
組合字(combining character)
對你吶喊一聲,у̐ë̈̈Α̫Ή̥!
自成一體的西文強調
I will have to tell you —
17 | The cat is cute.
我必須說——Η γάτα είναι χαριτωμένο.
言う必要があります、Кошка мило.
與其他字級語意元素共用
行間注ruby是按怎?註記元素u與變音元素i。
定制
無論你想要把着重號放在上邊,或是想用空心「芝麻號」都沒有問題!抑或是這樣搞怪的圈圈,也可以用有紀念意義的顏色。
不想「規避標點」也行。
--------------------------------------------------------------------------------
/README-ja.md:
--------------------------------------------------------------------------------
1 |
2 | - [中文](https://github.com/ethantw/Han/blob/master/README.md)
3 | - 日本語
4 | - [English](https://github.com/ethantw/Han/blob/master/README-en.md)
5 |
6 |
7 | 漢字標準格式
8 | ==========
9 |
10 | 漢字標準格式(組版標準フォーマット)は、「セマンティック要素のスタイルの標準化」「タイポグラフィ」「ハイレベルな組版」を実現するためのSass/StylusとJavaScriptのフレームワークです。美しい見た目と標準化された環境を、漢字文化圏のウェブサイトへ提供するために設計されました。伝統的な読書環境をスクリーン上での事実上の標準仕様とすることで、漢字文化圏のウェブデザインの組版需要に当面の解決策となります。
11 |
12 | 漢字標準格式は、中国語繁体字、中国語簡体字および日本語をサポートします。
13 |
14 | [表示例のテストページ(中国語)](http://ethantw.github.io/Han/latest/)
15 |
16 | ## インストール方法
17 |
18 | - NPM `npm install --save han-css`
19 | - Bower `bower install --save Han`
20 | - Rails `gem install 'hanzi-rails'`([詳細はこちら](https://github.com/billy3321/hanzi-rails))
21 |
22 | ### カスタマイズ
23 | 漢字標準格式には、カスタマイズ可能な機能が多くあります。設定を変更したりモジュールをインポートすることで、プロジェクトに独自のスタイルシートを容易に組み込めます。詳細は[取扱説明書(中国語)][api]をお読みください。
24 |
25 | [api]: http://css.hanzi.co/manual/sass-api
26 |
27 | ### CDNで使う
28 |
29 | カスタマイズが不要な場合、デフォルトのスタイルシート、JavaScriptおよびWebフォントがコンパイルされたものをCDNで使うことで、高速なダウンロードやキャッシュの利用ができます。[このサービスはcdnjs.comが提供します][cdnjs]。
30 |
31 | [cdnjs]: http://cdnjs.com/libraries/han
32 |
33 | ````html
34 |
35 | ````
36 |
37 | JavaScript
38 |
39 | ````html
40 |
41 | ````
42 |
43 | Webフォント
44 |
45 | - WOFF `//cdnjs.cloudflare.com/ajax/libs/Han/3.3.0/font/han.woff`
46 | - OTF `//cdnjs.cloudflare.com/ajax/libs/Han/3.3.0/font/han.otf`
47 |
48 | ## 使用方式
49 |
50 | 1. 従来から使用しているスタイルより前に、`han.min.css`(もしくは漢字標準格式のSass/Stylus)を組み込んでください。
51 | 2. 必要に応じて、`han.min.js`を組み込んでください。DOM-readyのレンダリングを有効にするには、``タグのclassに、`han-init`を追加します。
52 | 3. レンダリングをカスタマイズすることも可能です。詳細は[取扱説明書(中国語)][rendering]をお読みください。
53 |
54 | [rendering]: http://css.hanzi.co/manual/js-api#rendering
55 |
56 | ### JavaScriptのオプション
57 | 漢字標準格式は、低相互依存、高セマンティックです。スタイルシートとJavaScriptはほとんど依存し合いません。様々なレベルでスタイルシートのフォールバックができるので、JavaScriptの使用の可否を、必要に応じて選択できます。
58 |
59 | ## よくある質問
60 |
61 | ### スタイルを上書きすることについて
62 | 多くのCSSフレームワークとは異なり、漢字標準格式は大量のスタイルを持っており、言語属性(`:lang`)によって意図するスタイルを適用させます。そのため、スタイルの上書きは予期しない結果を引き起こす可能性があります。
63 |
64 | #### 言語毎のスタイルの集合を使った要素のスタイル
65 | - テキストレベルのセマンティック
66 | - グルーピングコンテンツ要素とsection要素の組み合わせ**(font-familyのみ)**
67 | - ルート要素`html`**(font-familyのみ)**
68 |
69 | #### 解決策
70 | このような状況を適切に対処するために、スタイルの継承のルールを十分ご確認ください。親要素または他のセレクタに適切な言語属性を追加することをおすすめします。`!important`宣言の過度の使用を避けることができ、保守性が向上します。
71 |
72 | 必要な場合は、ブラウザでDOMインスペクタを使うことにより、スタイルシートの継承や上書きの関係が分かります。
73 |
74 | ### han.jsスクリプトの動作環境
75 |
76 | han.jsはDOM環境でのみ動作します。必要な場合は、サーバに[jsdom]等のライブラリを導入してください。
77 |
78 | [jsdom]: https://github.com/tmpvar/jsdom
79 |
80 | ## サポートするブラウザ
81 |
82 | - Chrome(最新版)
83 | - Edge(最新版)
84 | - Firefox(最新版)
85 | - Firefox ESR+
86 | - Internet Explorer 11
87 | - Opera(最新版)
88 | - Safari 9
89 |
90 | ## 開発について
91 |
92 | - Node.js
93 | - LiveScript 1.4.0(`sudo npm install -g livescript`)
94 |
95 | 以下はプログラムの開発に有用なコマンドの一覧です。
96 |
97 | - 開発パッケージをインストール:`sudo npm install`
98 | - 開発環境の起動:`npm start`か`gulp dev`(ローカルサーバの実行と自動コンパイルを含む)
99 | - コンパイルしたファイルを公開:`gulp build`
100 | - `han.js`のAPIをテストする:`gulp test`(PhantomJS)
101 | - モジュールを更新する:`sudo npm update && gulp dep`
102 |
103 | * * *
104 | 漢字標準格式 v3.3.0
105 | Last-modified: 2016-3-19 00:11 (UTC+8)
106 | Translator: [神場雅史][translator] (Jimba Masafumi, [@westantenna][trans-twr])
107 |
108 | [translator]: http://westantenna.com
109 | [trans-twr]: https://twitter.com/westantenna
110 |
111 |
--------------------------------------------------------------------------------
/src/styl/locale/mixin.styl:
--------------------------------------------------------------------------------
1 |
2 | han-mark-to-code( $mark, $shape = filled )
3 | $ret = $mark
4 | if $shape == filled
5 | if $mark == circle
6 | $ret = "\25cf"
7 | if $mark == sesame
8 | $ret = "\fe45"
9 | if $mark == dot
10 | $ret = "\2022"
11 | if $mark == double-circle
12 | $ret = "\25c9"
13 | if $mark == triangle
14 | $ret = "\25b2"
15 | if $shape == open
16 | if $mark == circle
17 | $ret = "\25cb"
18 | if $mark == sesame
19 | $ret = "\fe46"
20 | if $mark == dot
21 | $ret = "\25e6"
22 | if $mark == double-circle
23 | $ret = "\25ce"
24 | if $mark == triangle
25 | $ret = "\25b3"
26 | $ret
27 |
28 | han-calc( $prop, $exp )
29 | $prop: -moz-calc( $exp )
30 | $prop: -webkit-calc( $exp )
31 | $prop: calc( $exp )
32 |
33 | han-scale( $size, $origin = 'left top' )
34 | -moz-transform: scale( $size )
35 | -ms-transform: scale( $size )
36 | -webkit-transform: scale( $size )
37 | transform: scale( $size )
38 | -moz-transform-origin: unquote($origin)
39 | -ms-transform-origin: unquote($origin)
40 | -webkit-transform-origin: unquote($origin)
41 | transform-origin: unquote($origin)
42 |
43 | han-scale-center( $size )
44 | -moz-transform: scale( $size )
45 | -ms-transform: scale( $size )
46 | -webkit-transform: scale( $size )
47 | transform: scale( $size )
48 |
49 | han-typo-reset()
50 | han-text-emphasis-internal( none )
51 | font-style: normal
52 | font-weight: normal
53 | line-height: normal
54 | text-decoration: none
55 | text-indent: 0
56 |
57 | han-text-emphasis-internal( $posi = $HAN-TEXT-EMPHASIS-POSI, $mark = $HAN-TEXT-EMPHASIS-MARK, $shape = $HAN-TEXT-EMPHASIS-SHAPE, $color = $HAN-TEXT-EMPHASIS-COLOR )
58 | if $posi == none
59 | $mark = none
60 | $shape = null
61 | if $mark != null or $shape != null
62 | -moz-text-emphasis: $shape $mark
63 | -webkit-text-emphasis: $shape $mark
64 | text-emphasis: $shape $mark
65 | if $posi != null and $posi != none
66 | -moz-text-emphasis-position: $posi
67 | -webkit-text-emphasis-position: $posi
68 | text-emphasis-position: $posi
69 | if $color != null and $color != inherit
70 | -moz-text-emphasis-color: $color
71 | -webkit-text-emphasis-color: $color
72 | text-emphasis-color: $color
73 |
74 | han-text-emphasis-pf( $posi = $HAN-TEXT-EMPHASIS-POSI, $mark = $HAN-TEXT-EMPHASIS-MARK, $shape = $HAN-TEXT-EMPHASIS-SHAPE, $color = $HAN-TEXT-EMPHASIS-COLOR, $skip = $HAN-TEXT-EMPHASIS-SKIP, $extend = true )
75 | if $extend
76 | @extend $han-text-emphasis-pf
77 | if $extend and $skip
78 | @extend $han-text-emphasis-skip
79 | if $posi == under
80 | $posi = 1em
81 | if $posi == over
82 | $posi = -0.7em
83 |
84 | $mark = han-mark-to-code($mark, $shape)
85 |
86 | .textemphasis &
87 | @extend $han-need-no-jinze
88 |
89 | .no-textemphasis & h-char:after
90 | if $posi != null
91 | margin-top: $posi
92 | if $mark != null and $mark != ""
93 | content: $mark
94 | if $color != null and $color != inherit
95 | color: $color
96 | if $extend == false and $skip == false
97 | h-char.punct,
98 | h-char.biaodian
99 | han-text-emphasis(null, inherit, null, null)
100 | .no-textemphasis &:after
101 | if $mark == null
102 | $mark = "\25cf"
103 | if $shape == open
104 | $mark = "\25cb"
105 | content: $mark !important
106 |
107 |
--------------------------------------------------------------------------------
/src/styl/var/default.styl:
--------------------------------------------------------------------------------
1 |
2 | // *!
3 | // * **WARNING**
4 | // * It is recommended to overwrite the variables before
5 | // * including the module, instead of modifying them here.
6 | // *
7 |
8 | // **
9 | // * The root selector
10 | // * `html` || `'*:root'`
11 | // *
12 | $han-root ?= html
13 |
14 | // **
15 | // * The article selector
16 | // * Possible values:
17 | // * `article` || `.article` || `.post` || `.entry`
18 | // *
19 | $han-article ?= article
20 |
21 | // **
22 | // * Global line-height
23 | // * Recommended: `1.2-1.7em`
24 | // *
25 | $han-line-height ?= 1.3
26 |
27 | // **
28 | // * Line-height in article
29 | // * Recommended: `1.5-2em`
30 | // *
31 | $han-article-line-height ?= 1.7
32 |
33 | // **
34 | // * Justified alignment in articles
35 | // * `true` || `false`
36 | // *
37 | $han-article-justify ?= true
38 |
39 | // **
40 | // * [Advanced]
41 | // * Sectional counter in articles
42 | // * `true` || `false`
43 | // *
44 | $han-section-counter ?= false
45 | $han-section-counter-toc ?= false
46 |
47 | // **
48 | // * Indentation
49 | // * Recommended: `1em` || `2em`
50 | // *
51 | $han-indent ?= 2em
52 |
53 | // **
54 | // * Indentation on mobile devices
55 | // * Recommended: `1em` || `2em`
56 | // *
57 | $han-indent-md ?= 1em
58 |
59 | // **
60 | // * Max mobile-device width for RWD
61 | // * Recommended: `480px`
62 | // *
63 | $han-mobile-device-width ?= 480px
64 |
65 | // **
66 | // * Emphasis mark
67 | // * See: http://www.w3.org/TR/css-text-decor-3/#emphasis-marks
68 | // *
69 | // * `none` || `biaodian`
70 | $han-text-emphasis-skip ?= true
71 | // * `none` || `filled` || `open`
72 | $han-text-emphasis-shape ?= filled
73 | // * `dot` || `circle` || `double-circle` || `triangle` || `sesame` ||
74 | $han-text-emphasis-mark ?= circle
75 | // * `over` || `under`
76 | $han-text-emphasis-posi ?= under
77 | // * `inherit` ||
78 | $han-text-emphasis-color ?= inherit
79 | // *
80 | // * Emphasis mark in Japanese
81 | // *
82 | $han-text-emphasis-shape-ja ?= filled
83 | $han-text-emphasis-mark-ja ?= sesame
84 | $han-text-emphasis-posi-ja ?= over
85 | $han-text-emphasis-color-ja ?= inherit
86 |
87 | $han-zhuyin-size ?= .4
88 |
89 | // **
90 | // * Default Chinese locale variant
91 | // * (Traditional or simplified characters)
92 | // * `hant` || `hans`
93 | // *
94 | $han-default-variant ?= hant
95 |
96 | // **
97 | // * Chinese glyph set in general
98 | // * `default` || `CNS` || `GB`
99 | // *
100 | $han-glyph-set-hant ?= default
101 |
102 | // **
103 | // * Simplified Chinese glyph set
104 | // * `default` || `GB`
105 | // *
106 | $han-glyph-set-hans ?= GB
107 |
108 | // **
109 | // * Biaodian set for Tradtional Chinese
110 | // * `Pro` || `CNS` || `GB` || `simp`
111 | // *
112 | $han-biaodian-hant ?= CNS
113 |
114 | // **
115 | // * Biaodian set for Simplified Chinese
116 | // * `Pro` || `CNS` || `GB` || `simp`
117 | // *
118 | $han-biaodian-hans ?= GB
119 |
120 | // **
121 | // * Hanging Biaodian
122 | // *
123 | $han-hanging-hant ?= false
124 | $han-hanging-hans ?= true
125 | $han-hanging-ja ?= true
126 |
127 | // **
128 | // * Generic typefaces for Western (Latin-based)
129 | // * characters
130 | // *
131 | $han-sans ?= "Helvetica Neue", Helvetica, Arial
132 | $han-serif ?= Georgia, "Times New Roman"
133 | $han-cursive ?= "Apple Chancery", "Snell Roundhand"
134 | $han-mono ?= Menlo, Consolas, Courier
135 |
136 | // **
137 | // * Generic typefaces for Chinese
138 | // *
139 | $han-sans-zh ?= ""
140 | $han-serif-zh ?= ""
141 | $han-cursive-zh ?= ""
142 | $han-mono-zh ?= $han-sans-zh
143 |
144 | // **
145 | // * Web font paths
146 | // * (Zhuyin, Yang checked-toned romanisation and
147 | // * partial Biaodian correction)
148 | // *
149 | $han-font-path ?= "./font/"
150 |
151 |
--------------------------------------------------------------------------------
/src/js/inline/hws.js:
--------------------------------------------------------------------------------
1 | define([
2 | '../core',
3 | '../method',
4 | '../regex'
5 | ], function( Han, $ ) {
6 |
7 | var hws = '<>'
8 |
9 | var $hws = $.create( 'h-hws' )
10 | $hws.setAttribute( 'hidden', '' )
11 | $hws.innerHTML = ' '
12 |
13 | function sharingSameParent( $a, $b ) {
14 | return $a && $b && $a.parentNode === $b.parentNode
15 | }
16 |
17 | function properlyPlaceHWSBehind( $node, text ) {
18 | var $elmt = $node
19 | var text = text || ''
20 |
21 | if (
22 | $.isElmt( $node.nextSibling ) ||
23 | sharingSameParent( $node, $node.nextSibling )
24 | ) {
25 | return text + hws
26 | } else {
27 | // One of the parental elements of the current text
28 | // node would definitely have a next sibling, since
29 | // it is of the first portion and not `isEnd`.
30 | while ( !$elmt.nextSibling ) {
31 | $elmt = $elmt.parentNode
32 | }
33 | if ( $node !== $elmt ) {
34 | $elmt.insertAdjacentHTML( 'afterEnd', ' ' )
35 | }
36 | }
37 | return text
38 | }
39 |
40 | function firstStepLabel( portion, mat ) {
41 | return portion.isEnd && portion.index === 0
42 | ? mat[1] + hws + mat[2]
43 | : portion.index === 0
44 | ? properlyPlaceHWSBehind( portion.node, portion.text )
45 | : portion.text
46 | }
47 |
48 | function real$hwsElmt( portion ) {
49 | return portion.index === 0
50 | ? $.clone( $hws )
51 | : ''
52 | }
53 |
54 | var last$hwsIdx
55 |
56 | function apostrophe( portion ) {
57 | var $elmt = portion.node.parentNode
58 |
59 | if ( portion.index === 0 ) {
60 | last$hwsIdx = portion.endIndexInNode-2
61 | }
62 |
63 | if (
64 | $elmt.nodeName.toLowerCase() === 'h-hws' && (
65 | portion.index === 1 || portion.indexInMatch === last$hwsIdx
66 | )) {
67 | $elmt.classList.add( 'quote-inner' )
68 | }
69 | return portion.text
70 | }
71 |
72 | function curveQuote( portion ) {
73 | var $elmt = portion.node.parentNode
74 |
75 | if ( $elmt.nodeName.toLowerCase() === 'h-hws' ) {
76 | $elmt.classList.add( 'quote-outer' )
77 | }
78 | return portion.text
79 | }
80 |
81 | $.extend( Han, {
82 | renderHWS: function( context, strict ) {
83 | // Elements to be filtered according to the
84 | // HWS rendering mode.
85 | var AVOID = strict
86 | ? 'textarea, code, kbd, samp, pre'
87 | : 'textarea'
88 |
89 | var mode = strict ? 'strict' : 'base'
90 | var context = context || document
91 | var finder = Han.find( context )
92 |
93 | finder
94 | .avoid( AVOID )
95 |
96 | // Basic situations:
97 | // - 字a => 字a
98 | // - A字 => A字
99 | .replace( Han.TYPESET.hws[ mode ][0], firstStepLabel )
100 | .replace( Han.TYPESET.hws[ mode ][1], firstStepLabel )
101 |
102 | // Convert text nodes `` into real element nodes:
103 | .replace( new RegExp( '(' + hws + ')+', 'g' ), real$hwsElmt )
104 |
105 | // Deal with:
106 | // - '字' => '字'
107 | // - "字" => "字"
108 | .replace( /([\'"])\s(.+?)\s\1/g, apostrophe )
109 |
110 | // Deal with:
111 | // - “字”
112 | // - ‘字’
113 | .replace( /\s[‘“]/g, curveQuote )
114 | .replace( /[’”]\s/g, curveQuote )
115 | .normalize()
116 |
117 | // Return the finder instance for future usage
118 | return finder
119 | }
120 | })
121 |
122 | $.extend( Han.fn, {
123 | renderHWS: function( strict ) {
124 | Han.renderHWS( this.context, strict )
125 | return this
126 | },
127 |
128 | revertHWS: function() {
129 | $.tag( 'h-hws', this.context )
130 | .forEach(function( hws ) {
131 | $.remove( hws )
132 | })
133 | this.HWS = []
134 | return this
135 | }
136 | })
137 |
138 | return Han
139 | })
140 |
--------------------------------------------------------------------------------
/src/sass/locale/_mixin.sass:
--------------------------------------------------------------------------------
1 |
2 | @function han-mark-to-code( $mark, $shape: filled )
3 | $ret: $mark
4 |
5 | @if ( $shape == filled )
6 | @if ( $mark == circle )
7 | $ret: '\25cf'
8 | @if ( $mark == sesame )
9 | $ret: '\fe45'
10 | @if ( $mark == dot )
11 | $ret: '\2022'
12 | @if ( $mark == double-circle )
13 | $ret: '\25c9'
14 | @if ( $mark == triangle )
15 | $ret: '\25b2'
16 |
17 | @if ( $shape == open )
18 | @if ( $mark == circle )
19 | $ret: '\25cb'
20 | @if ( $mark == sesame )
21 | $ret: '\fe46'
22 | @if ( $mark == dot )
23 | $ret: '\25e6'
24 | @if ( $mark == double-circle )
25 | $ret: '\25ce'
26 | @if ( $mark == triangle )
27 | $ret: '\25b3'
28 | @return $ret
29 |
30 | =han-calc( $prop, $exp )
31 | #{$prop}: -moz-calc( #{$exp} )
32 | #{$prop}: -webkit-calc( #{$exp} )
33 | #{$prop}: calc( #{$exp} )
34 |
35 | =han-scale( $size, $origin: 'left top' )
36 | -moz-transform: scale( $size )
37 | -ms-transform: scale( $size )
38 | -webkit-transform: scale( $size )
39 | transform: scale( $size )
40 | -moz-transform-origin: #{$origin}
41 | -ms-transform-origin: #{$origin}
42 | -webkit-transform-origin: #{$origin}
43 | transform-origin: #{$origin}
44 |
45 | =han-scale-center( $size )
46 | -moz-transform: scale( $size )
47 | -ms-transform: scale( $size )
48 | -webkit-transform: scale( $size )
49 | transform: scale( $size )
50 |
51 | =han-typo-reset
52 | +han-text-emphasis-internal( none )
53 | font-style: normal
54 | font-weight: normal
55 | line-height: normal
56 | text-decoration: none
57 | text-indent: 0
58 |
59 | =han-text-emphasis-internal( $posi: $HAN-TEXT-EMPHASIS-POSI, $mark: $HAN-TEXT-EMPHASIS-MARK, $shape: $HAN-TEXT-EMPHASIS-SHAPE, $color: $HAN-TEXT-EMPHASIS-COLOR )
60 | @if ( $posi == none )
61 | $mark: none
62 | $shape: null
63 |
64 | @if ( $mark != null or $shape != null )
65 | -moz-text-emphasis: $shape $mark
66 | -webkit-text-emphasis: $shape $mark
67 | text-emphasis: $shape $mark
68 | @if ( $posi != null and $posi != none )
69 | -moz-text-emphasis-position: $posi
70 | -webkit-text-emphasis-position: $posi
71 | text-emphasis-position: $posi
72 | @if ( $color != null and $color != inherit )
73 | -moz-text-emphasis-color: $color
74 | -webkit-text-emphasis-color: $color
75 | text-emphasis-color: $color
76 |
77 | =han-text-emphasis-pf( $posi: $HAN-TEXT-EMPHASIS-POSI, $mark: $HAN-TEXT-EMPHASIS-MARK, $shape: $HAN-TEXT-EMPHASIS-SHAPE, $color: $HAN-TEXT-EMPHASIS-COLOR, $skip: $HAN-TEXT-EMPHASIS-SKIP, $extend: true )
78 | @if ( $extend )
79 | @extend %han-text-emphasis-pf
80 | @if ( $extend and $skip )
81 | @extend %han-text-emphasis-skip
82 |
83 | @if ( $posi == under )
84 | $posi: 1em
85 | @if ( $posi == over )
86 | $posi: -.7em
87 |
88 | $mark: han-mark-to-code( $mark, $shape )
89 |
90 | .textemphasis &
91 | @extend %han-need-no-jinze
92 |
93 | .no-textemphasis & h-char:after
94 | @if ( $posi != null )
95 | margin-top: $posi
96 | @if ( $mark != null and $mark != '' )
97 | content: $mark
98 | @if ( $color != null and $color != inherit )
99 | color: $color
100 |
101 | @if ( $extend == false and $skip == false )
102 | h-char.punct,
103 | h-char.biaodian
104 | +han-text-emphasis( null, inherit, null, null )
105 |
106 | .no-textemphasis &:after
107 | @if ( $mark == null )
108 | $mark: '\25cf'
109 | @if ( $shape == open )
110 | $mark: '\25cb'
111 |
112 | content: $mark !important
113 |
114 |
--------------------------------------------------------------------------------
/demo/well-knit.html:
--------------------------------------------------------------------------------
1 | 測試・文章、章節與內容的邊界調整 — 漢字標準格式測試·文章、章節與內容的邊界調整
提示:下方淺灰色區塊是文章章節的範例,建議使用瀏覽器的「元件檢閱器」來査閱各種群組元素在不同情境下的樣式。亦可伸縮視窗寬度來觀看專為行動裝置提供的彈性設計(responsive web design),行動裝置預設為480px以下的視窗或設備。
文章標題(一級)
段落,也許是前言。上邊界對一級標題收緊。文章區塊的行高大於全域行高,預設為1.7em。
二級標題
這是一個段落,可以是對二級標題的內容詳述,上邊界對二級標題收緊。
這是另一個段落,可見上邊界不收緊了。
段落、清單、引用區塊等群組元素對標題的收緊
三級標題
這是一個引用區塊段落,可見上邊界對標題收緊;而三級標題則對二級標題收緊。
這是第二個引用區塊段落,可見上邊界不收緊了。
在文章中的引用區塊,會縮進二個字元(行動裝置上縮進一字元),並使用楷體。
三級標題
- 這是一個有序清單,
- 可見上邊界對標題收緊。
- 這是另一個有序清單,
- 可見上邊界不收緊了。
三級標題
詩,與標題收緊規則
總結成詩,琅琅上口:
小級標題對大級標題收緊、
同級標題互相收緊;
大級標題
不對小級標題收緊、
一級標題
不對一級標題收緊。
上方描述規則的區塊是一個套用類詩篇類別.poem-like的分塊元素div。在任意情境下,其後代段落元素p縮進二字元;在行動裝置中,縮進一字元。
六級標題
五級標題
四級標題
三級標題
二級標題
二級標題
三級標題
四級標題
五級標題
六級標題
後代章節元素不影響群組收緊
後代章節元素section不會影響各個群組元素對上級標題的收緊。
比如說……
二級標題(在section下)
二級標題(在section下)
三級標題(在section下)
四級標題(在section下)
這是一個放在後代章節元素section中的段落,雖然和四級標題並非同輩,但仍然會對標題收緊。
同輩章節元素則否
互為「同輩」的二個章節元素下的標題則不互相收緊。
這是一個段落,屬於section庚,與甲乙丙丁戊己同輩。
--------------------------------------------------------------------------------
/demo/hanging.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html(lang='zh-Hant').han-init
3 | head
4 | meta(charset='utf-8')
5 | title 測試・行尾點號懸掛 — 漢字標準格式
6 | link(rel='stylesheet', href='./han.min.css')
7 |
8 | style.
9 | html {
10 | /* box */
11 | overflow-x: hidden;
12 | padding: 0 1.5em;
13 | }
14 |
15 | article {
16 | /* position */
17 | margin: 0 auto;
18 |
19 | /* box */
20 | max-width: 35em;
21 | padding: 0 0 15em;
22 |
23 | /* style */
24 | border-left: 1px solid #ccc;
25 | border-right: 1px solid #ccc;
26 | }
27 |
28 | article h1:first-child {
29 | margin-top: 0;
30 | }
31 |
32 | section.narrow {
33 | /* box */
34 | width: 15em;
35 |
36 | /* style */
37 | border-right: 1px solid #ccc;
38 | }
39 | meta(name='viewport' content='width=device-width, initial-scale=1.0')
40 | meta(name='description' content='印刷品般的漢字網頁排版框架')
41 | meta(name='keywords' content='漢字標準格式, 中文, 排版, 排版規範, 日文, 字體排印, 文字設計, CLReq, CSS, Sass, typography')
42 | body.test
43 |
44 | article
45 | h1 測試·行尾點號懸掛
46 | p 提示:調整瀏覽器視窗寬度來觀看各種標點在行間的擠壓及懸掛行為。
47 | p 提示二:文字橫排時,使用繁體中文的網頁或元素預設不開啓行尾點號懸掛,可透過相應的Sass變數啓用。
48 | ul
49 | li: a(href='#hant') 繁體中文
50 | li: a(href='#hans') 簡體中文
51 | li: a(href='#ja') 日文
52 |
53 | section#hant(lang='zh-Hant')
54 | h2 繁體中文標點
55 | p 點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。
56 | p 「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。
57 | p 標、「點」標、「點」標、「點」標、「點」。
58 | p 「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕
59 | p 《書名》、「強調」、『重點』。
60 | p 《書名》、「強調」、『重點』。
61 | section#hans(lang='zh-Hans')
62 | h2 简体中文标点
63 | p 点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。
64 | p 「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。
65 | p 标、「点」标、「点」标、「点」标、「点」。
66 | p 「标点。」「『标』点,」《标点。》(Biao、)〔Dian、〕「标点。」「『标』点,」《标点。》(Biao、)〔Dian、〕「标点。」「『标』点,」《标点。》(Biao、)〔Dian、〕
67 | p Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。
68 | p 「Biao」Dian,「〔Biao〕」Dian,[Biao]。「Biao」Dian,「〔Biao〕」Dian,[Biao]。「Biao」Dian,「〔Biao〕」Dian,[Biao]。
69 | p 《書名》、「強調」、『重點』。
70 | p 《書名》、「強調」、『重點』。
71 | section.narrow
72 | p 我认为,没人可以「如此」放肆,你说是吧!
73 | p 请你们告诉我这是怎么一回事……。
74 | p 把示例给看清楚了,这是一种点号、「开引号」的组合也可以标点悬挂的概念。
75 |
76 | section#ja(lang='ja')
77 | h2 日文標點
78 | p 點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。
79 | p 「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。
80 | p 標、「點」標、「點」標、「點」標、「點」。
81 | p 「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕「標點。」「『標』點,」《標點。》(Biao、)〔Dian、〕
82 | p Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。Dian、Dian,Dian。
83 | p 「Biao」Dian,「〔Biao〕」Dian,[Biao]。「Biao」Dian,「〔Biao〕」Dian,[Biao]。「Biao」Dian,「〔Biao〕」Dian,[Biao]。
84 | p 《書名》、「強調」、『重點』。
85 | p 《書名》、「強調」、『重點』。
86 | section.narrow
87 | p 我認為,沒人可以「如此」放肆,你說是吧!
88 | p 請你們告訴我這是怎麼一回事⋯⋯。
89 | p 把示例給看清楚了,這是一種點號、「開引號」的組合也可以標點懸掛的概念。
90 |
91 | //script(src='./han.min.js')
92 | script(src='./han.js')
93 |
--------------------------------------------------------------------------------
/demo/hws.html:
--------------------------------------------------------------------------------
1 | 測試・漢字-西文混排間隙 — 漢字標準格式測試·漢字-西文混排間隙
基本漢字-西文混排間隙
拉丁字母及數字
研究發現,全球狂銷的蘋果iPad超省電。根據非營利組織EPRI(電力研究中心),iPad一年電費只需1.36美刀(U.S. Dollar)。
希臘字母
游離輻射可以區分為高能粒子流與高能電磁波,其中高能粒子流包含α粒子、β粒子(+/−)與中子,高能電磁波包含γ射線、X射線與特定波長的紫外線。每一種粒子或射線的電離能力與穿透性均不同,例如α粒子的電離能力很強,但穿透力非常弱,只要一張紙就能阻隔;γ射線的特性就恰與α粒子相反,其穿透能力非常強,需要幾英呎厚的混凝土才能降低γ射線,但是γ射線的電離能力卻很弱,對生物的影響相對較小。
西里爾字母
我有學過українська мова,所以русский язык我可以稍微看得懂。
完整中日韓意音文字區段支援
注意:部分擴展區漢字可能不為多數作業系統支援,而顯示為空白方框。安裝花園明朝體可以解決這個問題。
擴展A:How㐀are㘻you䶵?
13 | 擴展B:A𠀀b𠄉C𪛖d
14 | 擴展C:E𪜀f𪶛G𪷼h𪜺I
15 | 擴展D:j𫝀K𫠝L
16 | 意音數字零:Θ〇Ω
17 | 康熙及簡體字部首:⼌Т⿕Я⺃ж⻍ы⻰Ӓ⻳Ӂ
18 | 意音文字描述字元:⿸Ҕ⿷ẳ⿳
假名
歯のEnamelに復元不可能な損害をもたらす。
組合字(combining character)
天然ê上好!
荷Ὅ̴̊̌ηρος̃馬。
貓К҉о҈ш҉к҈а҈咪。
元素邊界的調整
美國Chicago是這架飛船的目的地。
去Europe旅行帶上Dollars
19 | Euró就夠了!
多層元素嵌套
Who do you自以為you are?
你是咧com啥物plain啦!
非典型情況
雖然很非典型,但是¿你說不可能嗎?不對哦.
想使用Vue作為Blaze 2.0的內核。
他罵了一聲¡逼!就走——了.
22 | 他罵了一句¡逼、逼逼!就走……了.
繁:為‘什’麼;為“什”麼?
简:为‘什’么;为“什”么?
這是一個句子[漢字123]然後就沒有然後了;
23 | 這是一個句子[漢123字]然後就沒有然後了;
24 | 這是一個句子(漢字123)然後就沒有然後了;
25 | 這是一個句子(漢123字)然後就沒有然後了.
選項(必填) for example,
26 | For example: (必填)選項
27 | 問題: 這是,答案.
這是一段包含單'引'號和雙"引"號'單引號'和"雙引號"的文字.
28 | 單引號'大X中ZZ天'!
29 | 單引號'大X中ZZ天'和雙引號"大X中Y天"哦!
這是一段包含單'引'號和雙"引"號'單引號'和"雙引號"的文字.
30 | 單引號'大X中ZZ天'!
31 | 單引號'大X中ZZ天'和雙引號"大X中Y天"哦!
不作用的元素
文字區塊表單
代碼等元素
代code碼、輸key入board鍵、計算機samp輸出示例。
格式pre處理
中文加上 some code,中文加上 some code 放在中間,some code 加上中文,一般的 English。
中文加上some code,中文加上some code放在中間,some code加上中文,一般的English。
注意:在漢字–西文混排間隙「基本模式」下,代碼、輸入鍵、計算機輸出示例等元素仍經renderHWS()處理,惟使用樣式表將其下之hws元素隱藏,可藉樣式的改寫來顯示漢字–西文混排間隙;「嚴格模式」下,則不渲染以上元素。
--------------------------------------------------------------------------------
/demo/jiya.html:
--------------------------------------------------------------------------------
1 | 測試・標點擠壓 — 漢字標準格式測試·標點擠壓
提示:調整瀏覽器視窗寬度來觀看各種標點在行間的擠壓及懸掛行為。
提示二:為求較佳的效果展示,本測試頁已停用「行尾點號懸掛」渲染。
繁體中文標點
點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。
「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。
「何謂『標點擠壓』?」
何謂「標點『擠壓』」呢?
讓我來告訴你何謂「『標點』擠壓」。
讓我來告訴你何謂「『標點』擠壓。」
「就這樣,我、『那個人』和他們戰鬥了數個鐘頭,(最後)沒輸沒贏……『那個人』逃之夭夭。」
輕聲叨唸道——「好的……」
「好」「不好」
「好」·「不好」「好」・「不好」「好」、「不好」
「『好』·不好」「『好』・不好」「『好』、不好」
「好·『不好』」「好、『不好』」
《書名》〈篇名〉(內容)
《書名》〈篇名〉(內容)「『好』、不好」
內容《書名》〈篇名〉(內容)「好、『不好』」
內容《書名》〈篇名〉(內容)『好』、「不好」
《書名》、「文字」、『重點』。
《書名》、「強調」、『重點』。
《書名》、「關鍵字」、『重點』。
書名強調重點。
简体中文标点
点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。点、点,点。
「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。「标」、「『标』」,《标》、〈标〉。
「标」点、「『标』」点,《标》点、(标)点。「标」点、「『标』」点,《标》点、(标)点。「标」点、「『标』」点,《标》点、(标)点。「标」点、「『标』」点,《标》点、(标)点。「标」点、「『标』」点,《标》点、(标)点。
「何谓『标点挤压』?」
何谓「标点『挤压』」呢?
让我来告诉你何谓「『标点』挤压」。
让我来告诉你何谓「『标点』挤压。」
「就这样,我、『那个人』和他们战斗了数个钟头,(最后)没输没赢……『那个人』逃之夭夭。」
轻声叨念道——「好的……」
「『好』·不好」「『好』・不好」「『好』、不好」
「好·『不好』」「好、『不好』」
《书名》〈篇名〉(内容)
《书名》〈篇名〉(内容)「『好』、不好」
內容《書名》〈篇名〉(內容)「好、『不好』」
內容《書名》〈篇名〉(內容)『好』、「不好」
《书名》、「文字」、『重点』。
《書名》、「強調」、『重點』。
《書名》、「關鍵字」、『重點』。
書名強調重點。
日文標點
點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。點、點,點。
「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。「標」、「『標』」,《標》、〈標〉。
「標」點、「『標』」點,《標》點、(標)點。「標」點、「『標』」點,《標》點、(標)點。「標」點、「『標』」點,《標》點、(標)點。「標」點、「『標』」點,《標》點、(標)點。「標」點、「『標』」點,《標》點、(標)點。
「何謂『標點擠壓』?」
何謂「標點『擠壓』」呢?
讓我來告訴你何謂「『標點』擠壓」。
讓我來告訴你何謂「『標點』擠壓。」
「就這樣,我、『那個人』和他們戰鬥了數個鐘頭,(最後)沒輸沒贏……『那個人』逃之夭夭。」
輕聲叨唸道——「好的……」
「好」「不好」
「好」·「不好」「好」・「不好」「好」、「不好」
「『好』·不好」「『好』・不好」「『好』、不好」
「好·『不好』」「好、『不好』」
《書名》〈篇名〉(內容)
《書名》〈篇名〉(內容)「『好』、不好」
內容《書名》〈篇名〉(內容)「好、『不好』」
內容《書名》〈篇名〉(內容)『好』、「不好」
《書名》、「文字」、『重點』。
《書名》、「強調」、『重點』。
《書名》、「關鍵字」、『重點』。
書名強調重點。
--------------------------------------------------------------------------------
/src/js/method.js:
--------------------------------------------------------------------------------
1 | define(function() {
2 |
3 | var $ = {
4 | /**
5 | * Query selectors which return arrays of the resulted
6 | * node lists.
7 | */
8 | id: function( selector, $context ) {
9 | return ( $context || document ).getElementById( selector )
10 | },
11 |
12 | tag: function( selector, $context ) {
13 | return this.makeArray(
14 | ( $context || document ).getElementsByTagName( selector )
15 | )
16 | },
17 |
18 | qs: function( selector, $context ) {
19 | return ( $context || document ).querySelector( selector )
20 | },
21 |
22 | qsa: function( selector, $context ) {
23 | return this.makeArray(
24 | ( $context || document ).querySelectorAll( selector )
25 | )
26 | },
27 |
28 | parent: function( $node, selector ) {
29 | return selector
30 | ? (function() {
31 | if ( typeof $.matches !== 'function' ) return
32 |
33 | while (!$.matches( $node, selector )) {
34 | if (
35 | !$node ||
36 | $node === document.documentElement
37 | ) {
38 | $node = undefined
39 | break
40 | }
41 | $node = $node.parentNode
42 | }
43 | return $node
44 | })()
45 | : $node
46 | ? $node.parentNode : undefined
47 | },
48 |
49 | /**
50 | * Create a document fragment, a text node with text
51 | * or an element with/without classes.
52 | */
53 | create: function( name, clazz ) {
54 | var $elmt = '!' === name
55 | ? document.createDocumentFragment()
56 | : '' === name
57 | ? document.createTextNode( clazz || '' )
58 | : document.createElement( name )
59 |
60 | try {
61 | if ( clazz ) {
62 | $elmt.className = clazz
63 | }
64 | } catch (e) {}
65 |
66 | return $elmt
67 | },
68 |
69 | /**
70 | * Clone a DOM node (text, element or fragment) deeply
71 | * or childlessly.
72 | */
73 | clone: function( $node, deep ) {
74 | return $node.cloneNode(
75 | typeof deep === 'boolean'
76 | ? deep
77 | : true
78 | )
79 | },
80 |
81 | /**
82 | * Remove a node (text, element or fragment).
83 | */
84 | remove: function( $node ) {
85 | return $node.parentNode.removeChild( $node )
86 | },
87 |
88 | /**
89 | * Set attributes all in once with an object.
90 | */
91 | setAttr: function( target, attr ) {
92 | if ( typeof attr !== 'object' ) return
93 | var len = attr.length
94 |
95 | // Native `NamedNodeMap``:
96 | if (
97 | typeof attr[0] === 'object' &&
98 | 'name' in attr[0]
99 | ) {
100 | for ( var i = 0; i < len; i++ ) {
101 | if ( attr[ i ].value !== undefined ) {
102 | target.setAttribute( attr[ i ].name, attr[ i ].value )
103 | }
104 | }
105 |
106 | // Plain object:
107 | } else {
108 | for ( var name in attr ) {
109 | if (
110 | attr.hasOwnProperty( name ) &&
111 | attr[ name ] !== undefined
112 | ) {
113 | target.setAttribute( name, attr[ name ] )
114 | }
115 | }
116 | }
117 | return target
118 | },
119 |
120 | /**
121 | * Indicate whether or not the given node is an
122 | * element.
123 | */
124 | isElmt: function( $node ) {
125 | return $node && $node.nodeType === Node.ELEMENT_NODE
126 | },
127 |
128 | /**
129 | * Indicate whether or not the given node should
130 | * be ignored (`` or comments).
131 | */
132 | isIgnorable: function( $node ) {
133 | if ( !$node ) return false
134 |
135 | return (
136 | $node.nodeName === 'WBR' ||
137 | $node.nodeType === Node.COMMENT_NODE
138 | )
139 | },
140 |
141 | /**
142 | * Convert array-like objects into real arrays.
143 | */
144 | makeArray: function( object ) {
145 | return Array.prototype.slice.call( object )
146 | },
147 |
148 | /**
149 | * Extend target with an object.
150 | */
151 | extend: function( target, object ) {
152 | if ((
153 | typeof target === 'object' ||
154 | typeof target === 'function' ) &&
155 | typeof object === 'object'
156 | ) {
157 | for ( var name in object ) {
158 | if (object.hasOwnProperty( name )) {
159 | target[ name ] = object[ name ]
160 | }
161 | }
162 | }
163 | return target
164 | }
165 | }
166 |
167 | return $
168 | })
169 |
170 |
--------------------------------------------------------------------------------
/src/js/inline/jiya.js:
--------------------------------------------------------------------------------
1 | define([
2 | '../core',
3 | '../method',
4 | '../regex/unicode',
5 | '../find'
6 | ], function( Han, $, UNICODE ) {
7 |
8 | var JIYA_CLASS = 'bd-jiya'
9 | var JIYA_AVOID = 'h-char.bd-jiya'
10 | var CONSECUTIVE_CLASS = 'bd-consecutive'
11 | var JIYA_CS_HTML = ' '
12 |
13 | var matches = Han.find.matches
14 |
15 | function trimBDClass( clazz ) {
16 | return clazz.replace(
17 | /(biaodian|cjk|bd-jiya|bd-consecutive|bd-hangable)/gi, ''
18 | ).trim()
19 | }
20 |
21 | function charifyBiaodian( portion ) {
22 | var biaodian = portion.text
23 | var $elmt = portion.node.parentNode
24 | var $bd = $.parent( $elmt, 'h-char.biaodian' )
25 | var $new = Han.createBDChar( biaodian )
26 | var $jinze
27 |
28 | $new.innerHTML = '' + biaodian + ''
29 | $new.classList.add( JIYA_CLASS )
30 |
31 | if ( $jinze = $.parent( $elmt, 'h-jinze' )) {
32 | insertJiyaCS( $jinze )
33 | }
34 |
35 | return !$bd
36 | ? $new
37 | : (function() {
38 | $bd.classList.add( JIYA_CLASS )
39 |
40 | return matches( $elmt, 'h-inner, h-inner *' )
41 | ? biaodian
42 | : $new.firstChild
43 | })()
44 | }
45 |
46 | var prevBDType, $$prevCS
47 |
48 | function locateConsecutiveBD( portion ) {
49 | var prev = prevBDType
50 | var $elmt = portion.node.parentNode
51 | var $bd = $.parent( $elmt, 'h-char.biaodian' )
52 | var $jinze = $.parent( $bd, 'h-jinze' )
53 | var classList
54 |
55 | classList = $bd.classList
56 |
57 | if ( prev ) {
58 | $bd.setAttribute( 'prev', prev )
59 | }
60 |
61 | if ( $$prevCS && classList.contains( 'bd-open' )) {
62 | $$prevCS.pop().setAttribute( 'next', 'bd-open' )
63 | }
64 |
65 | $$prevCS = undefined
66 |
67 | if ( portion.isEnd ) {
68 | prevBDType = undefined
69 | classList.add( CONSECUTIVE_CLASS, 'end-portion' )
70 | } else {
71 | prevBDType = trimBDClass($bd.getAttribute( 'class' ))
72 | classList.add( CONSECUTIVE_CLASS )
73 | }
74 |
75 | if ( $jinze ) {
76 | $$prevCS = locateCS( $jinze, {
77 | prev: prev,
78 | 'class': trimBDClass($bd.getAttribute( 'class' ))
79 | })
80 | }
81 | return portion.text
82 | }
83 |
84 | function insertJiyaCS( $jinze ) {
85 | if (
86 | matches( $jinze, '.tou, .touwei' ) &&
87 | !matches( $jinze.previousSibling, 'h-cs.jiya-outer' )
88 | ) {
89 | $jinze.insertAdjacentHTML( 'beforebegin', JIYA_CS_HTML )
90 | }
91 | if (
92 | matches( $jinze, '.wei, .touwei' ) &&
93 | !matches( $jinze.nextSibling, 'h-cs.jiya-outer' )
94 | ) {
95 | $jinze.insertAdjacentHTML( 'afterend', JIYA_CS_HTML )
96 | }
97 | }
98 |
99 | function locateCS( $jinze, attr ) {
100 | var $prev, $next
101 |
102 | if (matches( $jinze, '.tou, .touwei' )) {
103 | $prev = $jinze.previousSibling
104 |
105 | if (matches( $prev, 'h-cs' )) {
106 | $prev.className = 'jinze-outer jiya-outer'
107 | $prev.setAttribute( 'prev', attr.prev )
108 | }
109 | }
110 | if (matches( $jinze, '.wei, .touwei' )) {
111 | $next = $jinze.nextSibling
112 |
113 | if (matches( $next, 'h-cs' )) {
114 | $next.className = 'jinze-outer jiya-outer ' + attr[ 'class' ]
115 | $next.removeAttribute( 'prev' )
116 | }
117 | }
118 | return [ $prev, $next ]
119 | }
120 |
121 | Han.renderJiya = function( context ) {
122 | var context = context || document
123 | var finder = Han.find( context )
124 |
125 | finder
126 | .avoid( 'textarea, code, kbd, samp, pre, h-cs' )
127 |
128 | .avoid( JIYA_AVOID )
129 | .charify({
130 | avoid: false,
131 | biaodian: charifyBiaodian
132 | })
133 | // End avoiding `JIYA_AVOID`:
134 | .endAvoid()
135 |
136 | .avoid( 'textarea, code, kbd, samp, pre, h-cs' )
137 | .replace( TYPESET.group.biaodian[0], locateConsecutiveBD )
138 | .replace( TYPESET.group.biaodian[1], locateConsecutiveBD )
139 |
140 | return finder
141 | }
142 |
143 | $.extend( Han.fn, {
144 | renderJiya: function() {
145 | Han.renderJiya( this.context )
146 | return this
147 | },
148 |
149 | revertJiya: function() {
150 | $.qsa(
151 | 'h-char.bd-jiya, h-cs.jiya-outer',
152 | this.context
153 | ).forEach(function( $elmt ) {
154 | var classList = $elmt.classList
155 | classList.remove( 'bd-jiya' )
156 | classList.remove( 'jiya-outer' )
157 | })
158 | return this
159 | }
160 | })
161 |
162 | return Han
163 | })
164 |
--------------------------------------------------------------------------------