├── 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 | 測試・標音(注音符號、羅馬拼音) — 漢字標準格式

測試·標音(注音符號、羅馬拼音)

注音符號

黑體

ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙ
ㆠㆣㆢㆡㆭ
ㄧㄨㄩ
ㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦ
ㆤㆥㆦㆧㆨㆩㆪㆫㆬㆮㆯㆰㆱㆲㆳ
ㄪㄫㄬㄭ
ˊˇˋ˪˫˙
ㆴㆵㆶㆷㆴ̇ㆵ̇ㆶ̇ㆷ̇

楷體

ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙ
ㆠㆣㆢㆡㆭ
ㄧㄨㄩ
ㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦ
ㆤㆥㆦㆧㆨㆩㆪㆫㆬㆮㆯㆰㆱㆲㆳ
ㄪㄫㄬㄭ
ˊˇˋ˪˫˙
ㆴㆵㆶㆷㆴ̇ㆵ̇ㆶ̇ㆷ̇

羅馬拼音

元音(陰、陽入韻)

aeioua̍e̍i̍o̍u̍

萌典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+"":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的元素樣式修正

上列測試頁

配合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?

德文中如何表達「羅曼式建築」這個概念?德國學者最初在teutschlongobardischromantische三詞間猶豫,最終在19世紀30年代偏向了「romantishce」一詞。

希臘字母

至今關於古希臘遊吟詩人Ὅμηρος的資料很少,所以對其生平有很多說法,但都無確鑿證據。

西里爾字母

Храм-паметник „Свети Александър Невски‟是一座位於保加利亞首都索菲亞的保加利亞東正教大教堂。該教堂為新拜占庭式建築,是保加利亞主教的主座教堂,也是東正教在世界上最大的教堂之一,還是索菲亞的象徵之一以及主要的遊覽景點。

組合字(combining character

對你吶喊一聲,у̐ë̈̈Α̫Ή̥!

自成一體的西文強調

I will have to tell you — 17 | The cat is cute.

我必須說——Η γάτα είναι χαριτωμένο.

言う必要があります、Кошка мило.

與其他字級語意元素共用

行間注hángjiānzhùrubyㄒㄧ˫ㄢˋㄗㄨㆩˋ註記元素u變音元素i

定制

無論你想要把着重號放在上邊,或是想用空心「芝麻號」都沒有問題!抑或是這樣搞怪的圈圈,也可以用有紀念意義的顏色。

不想「規避標點」也行。

定制方式

定制功能需要自行引用han.sass模塊(而無法直接使用CDN文件),並依需求設定變數等,詳見說明文件CSS Text Decoration Module Level 3

-------------------------------------------------------------------------------- /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。

二級標題

這是一個段落,可以是對二級標題的內容詳述,上邊界對二級標題收緊。

這是另一個段落,可見上邊界不收緊了。

段落、清單、引用區塊等群組元素對標題的收緊

三級標題

這是一個引用區塊段落,可見上邊界對標題收緊;而三級標題則對二級標題收緊。

這是第二個引用區塊段落,可見上邊界不收緊了。

在文章中的引用區塊,會縮進二個字元(行動裝置上縮進一字元),並使用楷體。

三級標題

  1. 這是一個有序清單,
  2. 可見上邊界對標題收緊。
  1. 這是另一個有序清單,
  2. 可見上邊界不收緊了。

三級標題

  • 這是一個無序清單,
  • 可見上邊界對標題收緊。

詩,與標題收緊規則

總結成,琅琅上口:

上方描述規則的區塊是一個套用類詩篇類別.poem-like的分塊元素div在任意情境下,其後代段落元素p縮進二字元;在行動裝置中,縮進一字元。

六級標題
五級標題

四級標題

三級標題

二級標題

二級標題

三級標題

四級標題

五級標題
六級標題

一級標題

一級標題

一級標題不會互相收緊。

後代章節元素不影響群組收緊

後代章節元素section不會影響各個群組元素對上級標題的收緊。

比如說……

二級標題(在section下)

二級標題(在section下)

三級標題(在section下)

四級標題(在section下)

這是一個放在後代章節元素section中的段落,雖然和四級標題並非同輩,但仍然會對標題收緊。

四級標題(在section下)

五級標題(在section下)
六級標題(在section下)

同輩章節元素則否

互為「同輩」的二個章節元素下的標題則不互相收緊。

二級標題(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ó就夠了!

有註解及機會斷行元素的情況

不知道是不是like this你用「元件檢閱器」看看。

多層元素嵌套

Who do you自以為you are?

你是咧com啥物plain啦!

清單

  1. Tissue
  2. 鴨蛋
  3. Eggs
  4. 垃圾袋XL

非典型情況

雖然很非典型,但是¿你說不可能嗎?不對哦.

想使用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 | --------------------------------------------------------------------------------